Skip to main content

Configuration

OSAPI is configured through a YAML file and optional environment variable overrides.

Config File

By default OSAPI looks for /etc/osapi/osapi.yaml. Override the path with the -f / --osapi-file flag:

osapi -f /path/to/osapi.yaml controller start

Validation

Configuration is validated at startup. If any field has an invalid value, OSAPI exits with a clear error message before starting any component. Validation uses the same go-playground/validator library as the API handlers.

  • Required fields must be present and non-empty (e.g., signing_key, bearer_token, stream and bucket names)
  • Port fields must be between 1 and 65535
  • Duration fields must be valid Go durations (e.g., 30s, 5m, 1h, 720h). The d (day) suffix is not supported — use hours instead (e.g., 168h for 7 days)
  • Condition thresholds must be within valid ranges (1–100 for percentages, >0 for load multiplier)

Most fields have sensible defaults set via Viper and can be omitted from the config file.

Environment Variables

Every config key can be overridden with an environment variable using the OSAPI_ prefix. Dots and nested keys become underscores, and the name is uppercased:

Config KeyEnvironment Variable
debugOSAPI_DEBUG
controller.api.portOSAPI_CONTROLLER_API_PORT
controller.api.nats.hostOSAPI_CONTROLLER_API_NATS_HOST
controller.api.nats.portOSAPI_CONTROLLER_API_NATS_PORT
controller.api.nats.client_nameOSAPI_CONTROLLER_API_NATS_CLIENT_NAME
controller.api.nats.namespaceOSAPI_CONTROLLER_API_NATS_NAMESPACE
controller.api.nats.auth.typeOSAPI_CONTROLLER_API_NATS_AUTH_TYPE
controller.api.job_timeoutOSAPI_CONTROLLER_API_JOB_TIMEOUT
controller.api.security.signing_keyOSAPI_CONTROLLER_API_SECURITY_SIGNING_KEY
controller.client.security.bearer_tokenOSAPI_CONTROLLER_CLIENT_SECURITY_BEARER_TOKEN
controller.metrics.enabledOSAPI_CONTROLLER_METRICS_ENABLED
controller.metrics.portOSAPI_CONTROLLER_METRICS_PORT
controller.pki.enabledOSAPI_CONTROLLER_PKI_ENABLED
controller.pki.key_dirOSAPI_CONTROLLER_PKI_KEY_DIR
controller.pki.auto_acceptOSAPI_CONTROLLER_PKI_AUTO_ACCEPT
controller.pki.rotation_grace_periodOSAPI_CONTROLLER_PKI_ROTATION_GRACE_PERIOD
nats.server.hostOSAPI_NATS_SERVER_HOST
nats.server.portOSAPI_NATS_SERVER_PORT
nats.server.namespaceOSAPI_NATS_SERVER_NAMESPACE
nats.server.auth.typeOSAPI_NATS_SERVER_AUTH_TYPE
nats.server.metrics.enabledOSAPI_NATS_SERVER_METRICS_ENABLED
nats.server.metrics.portOSAPI_NATS_SERVER_METRICS_PORT
nats.stream.nameOSAPI_NATS_STREAM_NAME
nats.kv.bucketOSAPI_NATS_KV_BUCKET
nats.kv.response_bucketOSAPI_NATS_KV_RESPONSE_BUCKET
nats.audit.streamOSAPI_NATS_AUDIT_STREAM
nats.audit.subjectOSAPI_NATS_AUDIT_SUBJECT
nats.audit.max_ageOSAPI_NATS_AUDIT_MAX_AGE
nats.audit.max_bytesOSAPI_NATS_AUDIT_MAX_BYTES
nats.audit.storageOSAPI_NATS_AUDIT_STORAGE
nats.audit.replicasOSAPI_NATS_AUDIT_REPLICAS
nats.registry.bucketOSAPI_NATS_REGISTRY_BUCKET
nats.registry.ttlOSAPI_NATS_REGISTRY_TTL
nats.registry.storageOSAPI_NATS_REGISTRY_STORAGE
nats.registry.replicasOSAPI_NATS_REGISTRY_REPLICAS
nats.facts.bucketOSAPI_NATS_FACTS_BUCKET
nats.facts.ttlOSAPI_NATS_FACTS_TTL
nats.facts.storageOSAPI_NATS_FACTS_STORAGE
nats.facts.replicasOSAPI_NATS_FACTS_REPLICAS
nats.state.bucketOSAPI_NATS_STATE_BUCKET
nats.state.storageOSAPI_NATS_STATE_STORAGE
nats.state.replicasOSAPI_NATS_STATE_REPLICAS
nats.objects.bucketOSAPI_NATS_OBJECTS_BUCKET
nats.objects.max_bytesOSAPI_NATS_OBJECTS_MAX_BYTES
nats.objects.storageOSAPI_NATS_OBJECTS_STORAGE
nats.objects.replicasOSAPI_NATS_OBJECTS_REPLICAS
nats.objects.max_chunk_sizeOSAPI_NATS_OBJECTS_MAX_CHUNK_SIZE
nats.file_state.bucketOSAPI_NATS_FILE_STATE_BUCKET
nats.file_state.storageOSAPI_NATS_FILE_STATE_STORAGE
nats.file_state.replicasOSAPI_NATS_FILE_STATE_REPLICAS
telemetry.tracing.enabledOSAPI_TELEMETRY_TRACING_ENABLED
telemetry.tracing.exporterOSAPI_TELEMETRY_TRACING_EXPORTER
telemetry.tracing.otlp_endpointOSAPI_TELEMETRY_TRACING_OTLP_ENDPOINT
controller.notifications.enabledOSAPI_CONTROLLER_NOTIFICATIONS_ENABLED
controller.notifications.notifierOSAPI_CONTROLLER_NOTIFICATIONS_NOTIFIER
controller.notifications.renotify_intervalOSAPI_CONTROLLER_NOTIFICATIONS_RENOTIFY_INTERVAL
agent.nats.hostOSAPI_AGENT_NATS_HOST
agent.nats.portOSAPI_AGENT_NATS_PORT
agent.nats.client_nameOSAPI_AGENT_NATS_CLIENT_NAME
agent.nats.namespaceOSAPI_AGENT_NATS_NAMESPACE
agent.nats.auth.typeOSAPI_AGENT_NATS_AUTH_TYPE
agent.hostnameOSAPI_AGENT_HOSTNAME
agent.facts.intervalOSAPI_AGENT_FACTS_INTERVAL
agent.conditions.memory_pressure_thresholdOSAPI_AGENT_CONDITIONS_MEMORY_PRESSURE_THRESHOLD
agent.conditions.high_load_multiplierOSAPI_AGENT_CONDITIONS_HIGH_LOAD_MULTIPLIER
agent.conditions.disk_pressure_thresholdOSAPI_AGENT_CONDITIONS_DISK_PRESSURE_THRESHOLD
agent.process_conditions.memory_pressure_bytesOSAPI_AGENT_PROCESS_CONDITIONS_MEMORY_PRESSURE_BYTES
agent.process_conditions.high_cpu_percentOSAPI_AGENT_PROCESS_CONDITIONS_HIGH_CPU_PERCENT
agent.metrics.enabledOSAPI_AGENT_METRICS_ENABLED
agent.metrics.portOSAPI_AGENT_METRICS_PORT
agent.privilege_escalation.enabledOSAPI_AGENT_PRIVILEGE_ESCALATION_ENABLED
agent.pki.enabledOSAPI_AGENT_PKI_ENABLED
agent.pki.key_dirOSAPI_AGENT_PKI_KEY_DIR

Environment variables take precedence over file values.

Required Fields

Two fields carry a required validation tag and must be set before the server or client will start:

KeyPurpose
controller.api.security.signing_keyHS256 key for signing JWTs
controller.client.security.bearer_tokenJWT sent with client requests
controller.metrics.enabledOSAPI_CONTROLLER_METRICS_ENABLED
controller.metrics.portOSAPI_CONTROLLER_METRICS_PORT

Generate a signing key with openssl rand -hex 32. Generate a bearer token with osapi token generate.

Authentication

Each NATS connection supports pluggable authentication. Set the auth.type field in the relevant section (nats.server, controller.api.nats, or agent.nats):

TypeDescriptionExtra Fields
noneNo authentication (default)
user_passUsername and passwordusername, password
nkeyNKey-based auth (server and clients)See examples below

Server-Side Auth

The embedded NATS server (nats.server.auth) accepts a list of users or nkeys:

nats:
api:
auth:
type: user_pass
users:
- username: osapi
password: '<secret>'

Client-Side Auth

API server and agent connections (controller.api.nats.auth, agent.nats.auth) authenticate as a single identity:

controller:
api:
nats:
auth:
type: user_pass
username: osapi
password: '<secret>'

Permissions

OSAPI uses fine-grained resource:verb permissions for access control. Each API endpoint requires a specific permission. Built-in roles expand to a default set of permissions:

RolePermissions
adminagent:read, agent:write, node:read, node:write, network:read, network:write, job:read, job:write, health:read, audit:read, command:execute, file:read, file:write, docker:read, docker:write, docker:execute, cron:read, cron:write, sysctl:read, sysctl:write, ntp:read, ntp:write, timezone:read, timezone:write, power:execute, process:read, process:execute, user:read, user:write, package:read, package:write, log:read, certificate:read, certificate:write, service:read, service:write
writeagent:read, node:read, node:write, network:read, network:write, job:read, job:write, health:read, file:read, file:write, docker:read, docker:write, cron:read, cron:write, sysctl:read, sysctl:write, ntp:read, ntp:write, timezone:read, timezone:write, process:read, user:read, user:write, package:read, package:write, log:read, certificate:read, certificate:write, service:read, service:write
readagent:read, node:read, network:read, job:read, health:read, file:read, docker:read, cron:read, sysctl:read, ntp:read, timezone:read, process:read, user:read, package:read, log:read, certificate:read, service:read

Custom Roles

You can define custom roles in the controller.api.security.roles section. Custom roles override the default permission mapping for the same name, or define entirely new role names:

controller:
api:
security:
roles:
ops:
permissions:
- node:read
- health:read
netadmin:
permissions:
- network:read
- network:write
- health:read

Direct Permissions

Tokens can carry a permissions claim that overrides role-based expansion. When the claim is present, only the listed permissions are granted regardless of the token's roles. Generate a token with direct permissions:

osapi token generate -r admin -u user@example.com \
-p node:read -p health:read

Namespace

The namespace field on NATS connections prefixes all subject names and infrastructure names. This allows multiple OSAPI deployments to share a single NATS cluster without collisions.

Without namespaceWith namespace: osapi
jobs.query._anyosapi.jobs.query._any
JOBS (stream)osapi-JOBS
job-queue (KV bucket)osapi-job-queue

Set the same namespace value in nats.server.namespace, controller.api.nats.namespace, and agent.nats.namespace so all components agree on naming. An empty string disables prefixing.

Full Reference

Below is a complete osapi.yaml with every supported field and inline comments. Values shown are representative defaults from the repository's config file.

# Enable verbose logging.
debug: true

controller:
client:
# Base URL the CLI client connects to.
url: 'http://0.0.0.0:8080'
security:
# JWT bearer token for client requests (REQUIRED).
# Generate with: osapi token generate
bearer_token: '<jwt>'

# Embedded management UI served at / (API at /api/).
ui:
enabled: true

api:
# Port the REST API server listens on.
port: 8080
# How long to wait for agent responses before returning partial
# results. Go duration format (default: 30s).
job_timeout: '30s'
nats:
# NATS server hostname for the API server.
host: 'localhost'
# NATS server port for the API server.
port: 4222
# Client name sent to NATS for identification.
client_name: 'osapi-api'
# Subject namespace prefix. Must match nats.server.namespace.
namespace: 'osapi'
auth:
# Authentication type: "none", "user_pass", or "nkey".
type: 'none'
security:
# HS256 signing key for JWT validation (REQUIRED).
# Generate with: openssl rand -hex 32
signing_key: '<secret>'
cors:
# Origins allowed to make cross-origin requests.
# An empty list disables CORS headers entirely.
allow_origins:
- 'http://localhost:3001'
- 'https://osapi-io.github.io'
# Custom roles with fine-grained permissions.
# Permissions: agent:read, agent:write, node:read, node:write,
# network:read, network:write, job:read, job:write,
# health:read, audit:read, command:execute, file:read,
# file:write, docker:read, docker:write, docker:execute,
# cron:read, cron:write, sysctl:read, sysctl:write,
# ntp:read, ntp:write, timezone:read, timezone:write,
# power:execute, process:read, process:execute,
# user:read, user:write, package:read, package:write,
# log:read, certificate:read, certificate:write,
# service:read, service:write
# roles:
# ops:
# permissions:
# - node:read
# - health:read

# Per-component metrics server.
metrics:
# Enable the metrics endpoint (default: true).
enabled: true
# Port the metrics server listens on.
port: 9090

# Condition notification system.
notifications:
# Enable the condition watcher and notifier (default: true).
enabled: true
# Notifier backend: "log" (default).
notifier: 'log'
# How often to re-fire active conditions (Go duration).
# Zero disables re-notification.
renotify_interval: '5m'

# PKI enrollment and job signing.
pki:
# Enable PKI enrollment and job signing.
enabled: false
# Directory for controller keypair storage.
key_dir: '/etc/osapi/pki'
# Automatically accept all enrollment requests (dev/test only).
auto_accept: false
# Grace period during key rotation where both old and new keys
# are accepted. Go duration format.
rotation_grace_period: '24h'

nats:
api:
# Hostname the embedded NATS server binds to.
host: 'localhost'
# Port the embedded NATS server binds to.
port: 4222
# Directory for JetStream file-based storage.
store_dir: '.nats/jetstream/'
# Subject namespace prefix for server-created infrastructure.
namespace: 'osapi'
auth:
# Authentication type: "none", "user_pass", or "nkey".
type: 'none'
# Users for user_pass auth (server-side only).
# users:
# - username: osapi
# password: '<secret>'
# NKeys for nkey auth (server-side only).
# nkeys:
# - '<public-nkey>'
# Per-component metrics server.
metrics:
# Enable the metrics endpoint (default: true).
enabled: true
# Port the metrics server listens on.
port: 9092

# ── JetStream stream ──────────────────────────────────────
stream:
# JetStream stream name for job notifications.
name: 'JOBS'
# Subject filter for the stream.
subjects: 'jobs.>'
# Maximum age of messages in the stream (Go duration).
max_age: '24h'
# Maximum number of messages retained.
max_msgs: 10000
# Storage backend: "file" or "memory".
storage: 'file'
# Number of stream replicas (1 for single-node).
replicas: 1
# Discard policy when limits are reached: "old" or "new".
discard: 'old'

# ── KV bucket settings ────────────────────────────────────
kv:
# KV bucket for immutable job definitions and status events.
bucket: 'job-queue'
# KV bucket for agent result storage.
response_bucket: 'job-responses'
# TTL for KV entries (Go duration).
ttl: '1h'
# Maximum total size of the bucket in bytes.
max_bytes: 104857600 # 100 MiB
# Storage backend: "file" or "memory".
storage: 'file'
# Number of KV replicas.
replicas: 1

# ── Audit log stream ──────────────────────────────────────
audit:
# JetStream stream name for audit log entries.
stream: 'AUDIT'
# Base subject prefix for audit messages.
subject: 'audit'
# Maximum age of audit entries (Go duration). Default 30 days.
max_age: '720h'
# Maximum total size of the audit stream in bytes.
max_bytes: 52428800 # 50 MiB
# Storage backend: "file" or "memory".
storage: 'file'
# Number of stream replicas.
replicas: 1

# ── Agent registry KV bucket ──────────────────────────────
registry:
# KV bucket for agent heartbeat registration.
bucket: 'agent-registry'
# TTL for registry entries (Go duration). Agents refresh
# every 10s; the TTL acts as a liveness timeout.
ttl: '30s'
# Storage backend: "file" or "memory".
storage: 'file'
# Number of KV replicas.
replicas: 1

# ── Facts KV bucket ──────────────────────────────────────
facts:
# KV bucket for agent facts entries.
bucket: 'agent-facts'
# TTL for facts entries (Go duration).
ttl: '5m'
# Storage backend: "file" or "memory".
storage: 'file'
# Number of KV replicas.
replicas: 1

# ── State KV bucket ──────────────────────────────────────
state:
# KV bucket for persistent agent state (drain flags, timeline events).
# No TTL — operator actions persist indefinitely.
bucket: 'agent-state'
# Storage backend: "file" or "memory".
storage: 'file'
# Number of KV replicas.
replicas: 1

# ── Object Store (file uploads) ─────────────────────────
objects:
# Object Store bucket for uploaded file content.
bucket: 'file-objects'
# Maximum total size of the bucket in bytes.
max_bytes: 104857600 # 100 MiB
# Storage backend: "file" or "memory".
storage: 'file'
# Number of Object Store replicas.
replicas: 1
# Maximum chunk size for uploads in bytes.
max_chunk_size: 262144 # 256 KiB

# ── File state KV bucket ────────────────────────────────
file_state:
# KV bucket for file deploy state tracking.
# No TTL — state persists until explicitly removed.
bucket: 'file-state'
# Storage backend: "file" or "memory".
storage: 'file'
# Number of KV replicas.
replicas: 1

# ── Dead Letter Queue ─────────────────────────────────────
dlq:
# Maximum age of messages in the DLQ.
max_age: '168h' # 7 days
# Maximum number of messages retained.
max_msgs: 1000
# Storage backend: "file" or "memory".
storage: 'file'
# Number of DLQ replicas.
replicas: 1

telemetry:
tracing:
# Enable distributed tracing (default: false).
enabled: false
# Exporter type: "stdout" or "otlp".
# exporter: stdout
# gRPC endpoint for OTLP exporter (e.g., Jaeger, Tempo).
# otlp_endpoint: localhost:4317

agent:
nats:
# NATS server hostname for the agent.
host: 'localhost'
# NATS server port for the agent.
port: 4222
# Client name sent to NATS for identification.
client_name: 'osapi-agent'
# Subject namespace prefix. Must match nats.server.namespace.
namespace: 'osapi'
auth:
# Authentication type: "none", "user_pass", or "nkey".
type: 'none'
consumer:
# Durable consumer name.
name: 'jobs-agent'
# Maximum redelivery attempts before sending to DLQ.
max_deliver: 5
# Time to wait for an ACK before redelivering.
ack_wait: '2m'
# Maximum outstanding unacknowledged messages.
max_ack_pending: 1000
# Replay policy: "instant" or "original".
replay_policy: 'instant'
# Backoff durations between redelivery attempts.
back_off:
- '30s'
- '2m'
- '5m'
- '15m'
- '30m'
# Facts collection settings.
facts:
# How often the agent collects and publishes facts.
interval: '60s'
# Node condition thresholds.
conditions:
# Memory pressure threshold (percent used).
memory_pressure_threshold: 90
# High load multiplier (load1 / cpu_count).
high_load_multiplier: 2.0
# Disk pressure threshold (percent used).
disk_pressure_threshold: 90
# Process-level condition thresholds.
process_conditions:
# Process RSS threshold in bytes (0 = disabled).
memory_pressure_bytes: 0
# Process CPU threshold as percentage (0 = disabled).
high_cpu_percent: 0
# Queue group for load-balanced (_any) subscriptions.
queue_group: 'job-agents'
# Agent hostname for direct routing. Defaults to the
# system hostname when empty.
hostname: ''
# Maximum number of concurrent jobs to process.
max_jobs: 10
# Key-value labels for label-based routing (max 5).
# Values can be hierarchical with dot separators.
# Each label creates NATS consumers for prefix matching.
# See Job System Architecture for details.
labels:
group: 'web.dev.us-east'
# Per-component metrics server.
metrics:
# Enable the metrics endpoint (default: true).
enabled: true
# Port the metrics server listens on.
port: 9091
# Least-privilege mode. When enabled, write commands use sudo and
# Linux capabilities are verified at startup.
privilege_escalation:
enabled: false
# PKI enrollment and job signature verification.
pki:
# Enable PKI enrollment and job signature verification.
enabled: false
# Directory for agent keypair storage.
key_dir: '/etc/osapi/pki'

Section Reference

controller.client

KeyTypeDescription
urlstringBase URL the CLI client targets
security.bearer_tokenstringJWT for client auth (required)

controller.ui

KeyTypeDescription
enabledboolServe embedded UI at / (default true)

controller.api

KeyTypeDescription
portintPort the API server listens on
nats.hoststringNATS server hostname
nats.portintNATS server port
nats.client_namestringNATS client identification name
nats.namespacestringSubject namespace prefix
nats.auth.typestringAuth type: none, user_pass
nats.auth.usernamestringUsername for user_pass auth
nats.auth.passwordstringPassword for user_pass auth
security.signing_keystringHS256 JWT signing key (required)
security.cors.allow_origins[]stringAllowed CORS origins
security.rolesmapCustom roles with permissions lists
job_timeoutstringAgent response timeout (default 30s)

controller.metrics

KeyTypeDescription
enabledboolEnable the metrics server (default: true)
portintPort the metrics server listens on (default: 9090)

When enabled, the port also serves /health (liveness) and /health/ready (readiness) probes without authentication.

controller.pki

KeyTypeDescription
enabledboolEnable PKI enrollment and job signing
key_dirstringDirectory for controller keypair (default: /etc/osapi/pki)
auto_acceptboolAuto-accept agent enrollments (default: false)
rotation_grace_periodstringBoth keys accepted during rotation (default: 24h)

nats.server

KeyTypeDescription
hoststringHostname the NATS server binds to
portintPort the NATS server binds to
store_dirstringDirectory for JetStream file storage
namespacestringNamespace prefix for infrastructure
auth.typestringAuth type: none, user_pass
auth.userslistUsers for user_pass auth (see below)
auth.nkeyslistPublic nkeys for nkey auth

nats.server.metrics

KeyTypeDescription
enabledboolEnable the metrics server (default: true)
portintPort the metrics server listens on (default: 9092)

When enabled, the port also serves /health (liveness) and /health/ready (readiness) probes without authentication.

nats.stream

KeyTypeDescription
namestringJetStream stream name
subjectsstringSubject filter for the stream
max_agestringMaximum message age (Go duration)
max_msgsintMaximum number of messages
storagestring"file" or "memory"
replicasintNumber of stream replicas
discardstringDiscard policy: "old" or "new"

nats.kv

KeyTypeDescription
bucketstringKV bucket for job definitions and events
response_bucketstringKV bucket for agent results
ttlstringEntry time-to-live (Go duration)
max_bytesintMaximum bucket size in bytes
storagestring"file" or "memory"
replicasintNumber of KV replicas

nats.audit

KeyTypeDescription
streamstringJetStream stream name for audit log entries
subjectstringBase subject prefix for audit messages
max_agestringMaximum entry age (Go duration)
max_bytesintMaximum stream size in bytes
storagestring"file" or "memory"
replicasintNumber of stream replicas

nats.registry

KeyTypeDescription
bucketstringKV bucket for agent heartbeat entries
ttlstringEntry time-to-live / liveness timeout
storagestring"file" or "memory"
replicasintNumber of KV replicas

nats.facts

KeyTypeDescription
bucketstringKV bucket for agent facts entries
ttlstringEntry time-to-live (Go duration)
storagestring"file" or "memory"
replicasintNumber of KV replicas

nats.state

KeyTypeDescription
bucketstringKV bucket for persistent agent state (no TTL)
storagestring"file" or "memory"
replicasintNumber of KV replicas

nats.objects

KeyTypeDescription
bucketstringObject Store bucket for file uploads
max_bytesintMaximum bucket size in bytes
storagestring"file" or "memory"
replicasintNumber of Object Store replicas
max_chunk_sizeintMaximum chunk size for uploads

nats.file_state

KeyTypeDescription
bucketstringKV bucket for file deploy state (no TTL)
storagestring"file" or "memory"
replicasintNumber of KV replicas

nats.dlq

KeyTypeDescription
max_agestringMaximum message age (Go duration)
max_msgsintMaximum number of messages
storagestring"file" or "memory"
replicasintNumber of DLQ replicas

telemetry.tracing

KeyTypeDescription
enabledboolEnable distributed tracing (default: false)
exporterstring"stdout", "otlp", or unset (log correlation only, no span export)
otlp_endpointstringgRPC endpoint for OTLP exporter (required when exporter is "otlp")

controller.notifications

KeyTypeDescription
enabledboolEnable the condition watcher and notifier (default: false)
notifierstringNotification backend: "log" writes condition events to the server log
renotify_intervalstringRe-fire interval for active conditions (Go duration, default: "0")

agent

KeyTypeDescription
nats.hoststringNATS server hostname
nats.portintNATS server port
nats.client_namestringNATS client identification name
nats.namespacestringSubject namespace prefix
nats.auth.typestringAuth type: none, user_pass
nats.auth.usernamestringUsername for user_pass auth
nats.auth.passwordstringPassword for user_pass auth
consumer.namestringDurable consumer name
consumer.max_deliverintMax redelivery attempts before DLQ
consumer.ack_waitstringACK timeout (Go duration)
consumer.max_ack_pendingintMax outstanding unacknowledged msgs
consumer.replay_policystring"instant" or "original"
consumer.back_off[]stringBackoff durations between redeliveries
queue_groupstringQueue group for load-balanced routing
hostnamestringAgent hostname (defaults to OS hostname)
max_jobsintMax concurrent jobs
facts.intervalstringHow often the agent collects facts
conditions.memory_pressure_thresholdintMemory pressure threshold percent (default 90)
conditions.high_load_multiplierfloatLoad multiplier over CPU count (default 2.0)
conditions.disk_pressure_thresholdintDisk pressure threshold percent (default 90)
process_conditions.memory_pressure_bytesint64Process RSS threshold in bytes (0 = disabled)
process_conditions.high_cpu_percentfloatProcess CPU usage threshold as a percentage (0 = disabled)
labelsmap[string]stringKey-value pairs for label-based routing (max 5)
metrics.enabledboolEnable the metrics server (default: true)
metrics.portintPort the metrics server listens on (default: 9091)
privilege_escalation.enabledboolActivate sudo and capability checks (default false)
pki.enabledboolEnable PKI enrollment and job verify (default false)
pki.key_dirstringDirectory for agent keypair (default /etc/osapi/pki)

When metrics.enabled is true, the port also serves /health (liveness) and /health/ready (readiness) probes without authentication.