Configuration
Every strazad configuration key, its environment variable when it has one, and the reason when it has none.
On this page
Every key of straza.yaml is one row below, with the environment variable that sets it when there is one. A map or a list is one row, and its note says what each entry holds. The rows come from the knob table in the strazad source, and make docs-gen rewrites this page from it.
Core
| Key | Environment | Notes |
|---|---|---|
profile |
STRAZA_PROFILE |
The governance profile, standalone or enterprise. The default is standalone. Read before any other key, so it decides the defaults every other key starts from. |
dataDir |
STRAZA_DATA_DIR |
The directory of local state: the SQLite database, the embedded event bus’s storage, the key-encryption key and the approver certificate. The default is data, under the directory strazad starts in. |
log.level |
STRAZA_LOG_LEVEL |
The lowest level strazad logs, debug, info, warn or error. The default is info. |
log.format |
STRAZA_LOG_FORMAT |
The format of the log lines on standard error, json or text. The default is json. |
secrets.kekFile |
STRAZA_SECRETS_KEK_FILE |
The file that holds the 32-byte key-encryption key every stored secret is sealed with. strazad creates it at first boot when it is absent, and a backup needs it beside the store. The default is <dataDir>/secret.key. |
Server
| Key | Environment | Notes |
|---|---|---|
server.listen |
STRAZA_LISTEN |
The address the API, the console and the MCP gateway listen on. The default is 127.0.0.1:8420 under standalone and :8420 under enterprise. |
server.publicUrl |
STRAZA_PUBLIC_URL |
The base URL clients reach strazad at, with no trailing slash. It is the session-token issuer and the base of every link strazad hands out, so it cannot be empty. The default is http://127.0.0.1:8420. |
server.projectName |
STRAZA_PROJECT_NAME |
The name approver apps show for this deployment when a phone holds several, a label only. The default is straza- and the last four hex characters of the project id. |
server.maxBodyBytes |
none | The largest request body strazad accepts, in bytes. /mcp and /v1/audit/batch have limits of their own, and 0 turns the cap off. The default is 1 MiB. Set in the file only. |
server.metricsToken |
STRAZA_METRICS_TOKEN |
A bearer token that GET /metrics then requires. Empty by default, which leaves /metrics open to anyone who reaches the listener. |
server.loginPerIPRPS |
none | Requests per second each client address may make to the sign-in routes that take a credential with no session: the password form in both profiles, which under enterprise signs in only the emergency admin, and under enterprise also the agent token endpoint. 0 turns the limit off. Behind a reverse proxy every client shares the proxy’s address. The default is 2. Set in the file only. |
TLS on the main listener
| Key | Environment | Notes |
|---|---|---|
server.tls.certFile |
STRAZA_TLS_CERT_FILE |
The PEM certificate, leaf first, that turns on HTTPS on the main listener together with keyFile. Empty by default, which serves plain HTTP, fit only for loopback or behind a proxy that terminates TLS. |
server.tls.keyFile |
STRAZA_TLS_KEY_FILE |
The PEM private key of certFile, set together with it. Empty by default. |
The approver listener
| Key | Environment | Notes |
|---|---|---|
server.approverTLS.listen |
STRAZA_APPROVER_TLS_LISTEN |
The address of a second listener, HTTPS only, that serves only the approver routes a phone uses. Set it with certFile, keyFile and publicUrl, or let autoMint fill it in as :8443. Empty by default. |
server.approverTLS.certFile |
STRAZA_APPROVER_TLS_CERT_FILE |
The PEM certificate of the approver listener. A phone pins it at enrollment, so a new certificate means enrolling the phone again. Empty by default. |
server.approverTLS.keyFile |
STRAZA_APPROVER_TLS_KEY_FILE |
The PEM private key of the approver listener’s certificate. Empty by default. |
server.approverTLS.publicUrl |
STRAZA_APPROVER_TLS_PUBLIC_URL |
The https URL a phone dials, written into the enrollment QR code as it stands, so the phone must be able to reach it. Empty by default. |
server.approverTLS.autoMint |
STRAZA_APPROVER_TLS_AUTO_MINT |
Lets strazad fill in at boot the approver keys you leave unset: a self-signed pair kept under <dataDir>/approver-tls, the address :8443 and a URL on the host’s first LAN address. The default is true under standalone and false under enterprise. |
server.approverTLS.perIPRPS |
none | Requests per second each connecting address may make to the approver listener, never read from X-Forwarded-For, and 0 turns the limit off. The default is 10. Set in the file only. |
server.approverPublicUrl |
STRAZA_APPROVER_PUBLIC_URL |
The https URL where an ingress serves the approver routes while publicUrl stays private. The approverTLS publicUrl wins when that listener is set. Empty by default, which sends a phone to publicUrl. |
Store and events
| Key | Environment | Notes |
|---|---|---|
store.driver |
STRAZA_STORE_DRIVER |
The database, sqlite or postgres. The default is sqlite under standalone and postgres under enterprise. |
store.dsn |
STRAZA_STORE_DSN |
The PostgreSQL connection string, required with postgres, or the path of the SQLite file. The default under SQLite is <dataDir>/straza.db. |
events.embedded |
none | Runs the event bus inside strazad with no network socket, and false needs events.url. The default is true in both profiles. Set in the file only. Setting STRAZA_EVENTS_URL turns the embedded bus off. |
events.url |
STRAZA_EVENTS_URL |
The address of an external NATS server with JetStream. strazad uses it only while embedded is false, so in the file set both. Empty by default. |
events.auditStreamMaxAge |
STRAZA_EVENTS_AUDIT_STREAM_MAX_AGE |
How long the audit stream keeps a message. The stream carries each record from the outbox to the audit chain and to every sink, so a sink that stays down longer than this misses the records that aged out. The default is twice governance.captureRetention, 1440h while that keeps its default. |
events.auditStreamMaxBytes |
STRAZA_EVENTS_AUDIT_STREAM_MAX_BYTES |
The most disk the audit stream may use, in bytes. When it is full it drops its oldest messages, so publishing never stops, and it should stay well below the size of the bus’s volume. The default is 2 GiB. |
events.pushEdgeMaxConns |
STRAZA_EVENTS_PUSH_EDGE_MAX_CONNS |
How many clients may hold the push stream open at one strazad. A client over the limit polls instead until a retry gets in. The default is 65536. |
OIDC and OAuth
| Key | Environment | Notes |
|---|---|---|
oidc.issuer |
STRAZA_OIDC_ISSUER |
The discovery URL of your identity provider, matched byte for byte, trailing slash included. The enterprise profile needs it for sign-in, while standalone signs people in with its built-in issuer. Empty by default. |
oidc.discoveryUrl |
STRAZA_OIDC_DISCOVERY_URL |
The full address of your identity provider’s discovery document, for a server that cannot reach the issuer’s own address, such as a container that reaches the provider by an internal name. The document must still name oidc.issuer exactly, and tokens must still carry it. Empty by default, which fetches the document at the issuer. |
oidc.clientId |
STRAZA_OIDC_CLIENT_ID |
The audience strazad expects on ID tokens, which is Straza’s client id at your identity provider. The default is straza. |
oidc.jitProvision |
STRAZA_OIDC_JIT |
Creates a user at their first verified sign-in when no user of that name exists. The default is true under standalone and false under enterprise, where your identity manager creates users over SCIM. |
oidc.bootstrapAdmin |
STRAZA_OIDC_BOOTSTRAP_ADMIN |
A username whose first verified sign-in is created and made straza-admin while nobody holds straza-admin, so an enterprise install gets its first admin. Remove it after that sign-in. Empty by default. |
oauth.providers |
none | A map of OAuth providers for each caller’s own sign-in, keyed by the name a manifest’s credential.oauth.provider names. Each entry takes clientId, clientSecret or clientSecretFile, authUrl, tokenUrl and scopes, and clientCredentials with assertionAudience and scopes for an agent’s own token. A provider named github defaults both URLs. Each caller’s own credential shows a full block. Set in the file only, and the github provider alone has the three variables below. |
oauth.providers.github.clientId |
STRAZA_OAUTH_GITHUB_CLIENT_ID |
The client id of the OAuth app registered at GitHub. Sets this key of the github provider, so no config file is needed. |
oauth.providers.github.clientSecret |
STRAZA_OAUTH_GITHUB_CLIENT_SECRET |
The client secret of that OAuth app. Sets this key of the github provider, so no config file is needed. |
oauth.providers.github.clientSecretFile |
STRAZA_OAUTH_GITHUB_CLIENT_SECRET_FILE |
Path of a file that holds the client secret, which wins over clientSecret. Sets this key of the github provider, so no config file is needed. |
oauth.refreshInterval |
none | How often the refresh worker looks for connections whose token is about to expire. The default is 1m. Set in the file only. |
oauth.refreshWindow |
none | A token that expires within this window is refreshed on the worker’s next pass. The default is 10m. Set in the file only. |
Governance
| Key | Environment | Notes |
|---|---|---|
governance.offlineGraceTTL |
none | How long a client keeps deciding from its last signed snapshot while strazad cannot be reached, and 0 denies at once. The default is 15m under standalone and 0 under enterprise. Set in the file only, so a change to this enforcement setting shows in the config file. |
governance.localToolDefault |
none | The decision for a tool call that no policy rule matches and that is not an MCP tool, allow or deny. It covers the local tools, a tool name Straza does not know and a call that names no tool. The default is allow under standalone and deny under enterprise. Set in the file only, so a change to this enforcement setting shows in the config file. |
governance.auditBackpressure |
none | What strazad does with server audit records while the database cannot take them, and when its in-memory queue of 4,096 records is full. block, the enterprise default, keeps each record in the queue and tries it again until the database answers, so during an outage the queue fills after 4,096 server decisions, about 7 minutes at 10 decisions per second or 41 seconds at 100. After that each new server decision waits up to 25 seconds for room and is then refused with a reason, so nothing runs without its audit record. The queued records are written once the database is back, unless strazad stops or crashes first. drop-with-counter, the standalone default, keeps deciding: it loses a record the database cannot take after four attempts and counts it in straza_audit_lost_total, and it drops a record the full queue cannot take and counts it in straza_audit_dropped_total. Set in the file only, so a change to this enforcement setting shows in the config file. |
governance.minAttestation |
STRAZA_MIN_ATTESTATION |
The lowest attestation a check-in needs to get a session: none, advisory or managed, where managed needs hashes that match the registered ones. The default is none under standalone and managed under enterprise. |
governance.deviceTokenTTL |
STRAZA_DEVICE_TOKEN_TTL |
The lifetime of the device credential a machine keeps after enrollment, 720h by default and renewed at a check-in past half its life; strazad warns at boot when it is shorter than twice sessionMaxLifetime plus seven minutes, because a session that runs its full lifetime would then end with an expired credential and a locked-out machine. |
governance.sessionMaxLifetime |
STRAZA_SESSION_MAX_LIFETIME |
The longest a session stays active from its start, 12h by default, after which the janitor closes it and the client starts a new one from its device credential without any human action. |
governance.captureRetention |
STRAZA_CAPTURE_RETENTION |
How long recorded conversation turns are kept before the janitor deletes them. The default is 720h, which is 30 days. |
governance.transcriptBytesWatermark |
STRAZA_TRANSCRIPT_BYTES_WATERMARK |
The size of the stored transcripts in bytes above which the janitor logs a warning on every pass, so a filling disk shows early. The default is 10 GiB. |
governance.auditIngestBacklogLimit |
STRAZA_AUDIT_INGEST_BACKLOG_LIMIT |
While this many audit records wait to be published, strazad answers a client’s audit upload with 429, and the client keeps the records and retries. 0 turns the limit off. The default is 50000. |
governance.auditIngestPerSessionRPS |
STRAZA_AUDIT_INGEST_PER_SESSION_RPS |
Audit uploads per second one session may make at one strazad, and 0 turns the limit off. The default is 5. |
governance.outboxBulkRetention |
STRAZA_OUTBOX_BULK_RETENTION |
How long an audit or capture record stays in the outbox table once it is published, since the audit chain and the read models hold it. The default is 48h. |
governance.sentinel.enabled |
none | Turns on the audit sentinel, which reads the audit stream and records a warning or critical verdict on patterns such as a burst of denies or a written file that is then run. It alerts only and blocks nothing. The default is false in both profiles. Set in the file only. |
governance.sentinel.denyBurstWarn |
none | How many denies within denyBurstWindow raise a warning verdict. The default is 5. Set in the file only, with sentinel.enabled. |
governance.sentinel.denyBurstCritical |
none | How many denies within denyBurstWindow raise a critical verdict, at least denyBurstWarn. The default is 10. Set in the file only, with sentinel.enabled. |
governance.sentinel.denyBurstWindow |
none | The window the deny counts are taken over. The default is 1m. Set in the file only, with sentinel.enabled. |
governance.sentinel.variantWindow |
none | How long a denied shell command is remembered, so that a variant of it raises a verdict. The default is 10m. Set in the file only, with sentinel.enabled. |
governance.sentinel.writeExecWindow |
none | How long a written path is remembered, so that running it raises a verdict. The default is 30m. Set in the file only, with sentinel.enabled. |
governance.sentinel.baselineMinEvents |
none | How many audit events a user needs before their usual mix of tools counts as a baseline. The default is 50. Set in the file only, with sentinel.enabled. |
Approval
| Key | Environment | Notes |
|---|---|---|
approval.retention |
STRAZA_APPROVAL_RETENTION |
How long a decided or expired approval record is kept before the janitor deletes it. The default is 720h, which is 30 days. |
approval.gatewayHoldSeconds |
STRAZA_APPROVAL_GATEWAY_HOLD_SECONDS |
How many seconds a call that needs approval holds the gateway’s connection open for a decision before it answers that the decision is pending. It never lengthens the rule’s decision window, so lower it when your clients time out sooner. The default is 120. |
approval.unsignedOwnDecisions |
none | Lets a person decide their own request from the console, strazactl and Slack, which carry no device signature. False, the default, accepts such a decision only from an enrolled phone or browser. True means an agent that runs on that person’s machine can approve its own calls. Set in the file only, so a change to this enforcement setting shows in the config file. |
approval.channels.slack.enabled |
STRAZA_APPROVAL_SLACK_ENABLED |
Posts approval requests to Slack, which then needs channel, a bot token and a signing secret. The default is false. |
approval.channels.slack.botToken |
STRAZA_APPROVAL_SLACK_BOT_TOKEN |
The Slack bot token, set here or in botTokenFile but not both. Empty by default. |
approval.channels.slack.botTokenFile |
STRAZA_APPROVAL_SLACK_BOT_TOKEN_FILE |
Path of a file that holds the Slack bot token, the better form because a token in an environment variable can be read by anyone who can inspect the process. Empty by default. |
approval.channels.slack.signingSecret |
STRAZA_APPROVAL_SLACK_SIGNING_SECRET |
The Slack signing secret that proves a request came from Slack, set here or in signingSecretFile but not both. Empty by default. |
approval.channels.slack.signingSecretFile |
STRAZA_APPROVAL_SLACK_SIGNING_SECRET_FILE |
Path of a file that holds the Slack signing secret, the better form for the same reason. Empty by default. |
approval.channels.slack.channel |
STRAZA_APPROVAL_SLACK_CHANNEL |
The id of the Slack channel requests are posted to, required when Slack is enabled. |
approval.channels.slack.includeJustification |
none | Adds the agent’s justification to the Slack message, while the console always shows it. The default is false. Set in the file only, because it sends the agent’s justification to Slack. |
approval.push.fcm.enabled |
STRAZA_APPROVAL_PUSH_FCM_ENABLED |
Turns on the direct Firebase sender for Android phones; it needs serviceAccountFile and projectId, refuses boot beside the relay, and is off by default. |
approval.push.fcm.serviceAccountFile |
STRAZA_APPROVAL_PUSH_FCM_SERVICE_ACCOUNT_FILE |
Path of the Firebase service account file that signs every send, required when fcm.enabled is true and empty by default. |
approval.push.fcm.projectId |
STRAZA_APPROVAL_PUSH_FCM_PROJECT_ID |
The Firebase project id that names the send endpoint and is part of the app config the phone receives, required when fcm.enabled is true or any of appId, apiKey and senderId is set, and empty by default. |
approval.push.fcm.appId |
STRAZA_APPROVAL_PUSH_FCM_APP_ID |
The Firebase Android app id (mobilesdk_app_id in google-services.json) handed to enrolling phones, a public identifier that travels with apiKey, senderId and projectId as one all-or-nothing set, empty by default. |
approval.push.fcm.apiKey |
STRAZA_APPROVAL_PUSH_FCM_API_KEY |
Firebase’s web API key (current_key in google-services.json) handed to enrolling phones, a public identifier in the same all-or-nothing set, empty by default. |
approval.push.fcm.senderId |
STRAZA_APPROVAL_PUSH_FCM_SENDER_ID |
The sender id of the Firebase project (project_number in google-services.json) handed to enrolling phones, a public identifier in the same all-or-nothing set, empty by default. |
approval.push.webpush.vapidKeyFile |
STRAZA_APPROVAL_PUSH_WEBPUSH_VAPID_KEY_FILE |
Path of the VAPID private key, the one setting that turns WebPush on: when the path is set and the file is absent strazad mints the key there at boot, the key is the deployment’s push identity, and empty (the default) leaves WebPush off. |
approval.push.webpush.contact |
STRAZA_APPROVAL_PUSH_WEBPUSH_CONTACT |
A mailto: or https: address the push services may use to reach the operator, optional, valid only beside vapidKeyFile, and empty by default. |
approval.push.apns.keyFile |
STRAZA_APPROVAL_PUSH_APNS_KEY_FILE |
Path of the Apple-issued .p8 auth key, the one setting that turns on sending straight to APNs: strazad never mints it, refuses boot when the file is unreadable or the relay is on, and empty (the default) leaves it off. |
approval.push.apns.keyId |
STRAZA_APPROVAL_PUSH_APNS_KEY_ID |
The ten-character id of the key, shown beside it in the Apple developer portal, required when keyFile is set. |
approval.push.apns.teamId |
STRAZA_APPROVAL_PUSH_APNS_TEAM_ID |
Your Apple developer team id, the team the key belongs to, required when keyFile is set. |
approval.push.apns.topic |
STRAZA_APPROVAL_PUSH_APNS_TOPIC |
The bundle id of the approver app build you sign, sent as the apns-topic header, required when keyFile is set. |
approval.push.apns.environment |
STRAZA_APPROVAL_PUSH_APNS_ENVIRONMENT |
Which APNs cluster to send to: production (the default, right for every TestFlight and App Store build) or sandbox for a build signed with a development profile, and a mismatch fails every send as BadDeviceToken. |
approval.push.relay.enabled |
STRAZA_APPROVAL_PUSH_RELAY_ENABLED |
Turns on the hosted push relay, which sends to iOS and Android phones with no Apple or Firebase account on your side; it refuses boot beside a direct FCM or APNs sender and is off by default. |
approval.push.relay.url |
STRAZA_APPROVAL_PUSH_RELAY_URL |
The relay to register with and send through; empty (the default) means the Straza-operated relay at https://push.straza.ai. |
approval.push.relay.tokenFile |
STRAZA_APPROVAL_PUSH_RELAY_TOKEN_FILE |
Path of the anonymous deployment token the relay hands out, required when the relay is enabled; strazad mints it there at first boot and mints it again once if the relay refuses it. |
approval.push.allowedPushHosts |
STRAZA_APPROVAL_PUSH_ALLOWED_HOSTS |
The hosts a UnifiedPush or WebPush endpoint may point at, checked when a phone or browser registers and again at every send; empty (the default) refuses every such registration. |
approval.push.ticketReminderBefore |
STRAZA_APPROVAL_PUSH_TICKET_REMINDER_BEFORE |
How long before a pending ticket expires the single reminder is sent; empty means the built-in 2h default, and a ticket whose whole window is shorter gets no reminder. |
approval.preview.enabled |
STRAZA_APPROVAL_PREVIEW_ENABLED |
Shows a redacted preview of the call’s arguments on every approval surface. Redaction always applies, and false computes and stores no preview at all. The default is true. |
Apps
| Key | Environment | Notes |
|---|---|---|
apps.dir |
STRAZA_APPS_DIR |
The watched apps directory: a manifest added or changed there becomes a draft that a person publishes, and a removed one becomes a removal draft. The default is <dataDir>/apps. |
apps.pollInterval |
none | How often strazad scans the apps directory. The default is 1s. Set in the file only. |
apps.healthInterval |
none | How often strazad checks each server’s health and compares its tools with the last inventory. The default is 20s. Set in the file only. |
apps.upstreamTimeout |
none | The longest one tool call to a server may take, unless the server’s manifest sets limits.timeoutSeconds. The default is 30s. Set in the file only. |
apps.allowLoopbackUpstreams |
STRAZA_APPS_ALLOW_LOOPBACK_UPSTREAMS |
Lets strazad dial a remote server published at a loopback address such as 127.0.0.1, which reaches strazad’s own host: true by default under the standalone profile and false under enterprise, while unspecified, link-local and cloud metadata addresses are refused whatever it says and private addresses always pass. |
apps.catalog.policyFilter |
none | Leaves a tool that policy denies out of a session’s tool list, instead of listing it and denying the call. The default is true. Set in the file only. |
apps.catalog.warnSize |
none | When a role’s catalog holds more tools than this, strazad logs a warning and counts it in straza_gateway_catalog_oversize_total, and -1 turns the check off. The default is 100. Set in the file only. |
apps.catalog.pageSize |
none | The most tools one tools/list answer carries, the client following a cursor for the rest, and 0 sends the whole catalog at once. The default is 200. Set in the file only. |
The rest of the tree
| Key | Environment | Notes |
|---|---|---|
scim.groupRolePrefix |
none | Removed. strazad refuses to start while the key is present: delete it, because roles now render as SCIM groups and membership is assignment. |
scim.groupRoleMap |
none | Removed. strazad refuses to start while the key is present: delete it, because roles now render as SCIM groups and membership is assignment. |
scim.autoCreateRoles |
none | Removed. strazad refuses to start while the key is present: delete it, because roles now render as SCIM groups and membership is assignment. |
admin.roleAreas |
none | Maps a role name to the admin areas its holders administer, written as admin API token grants such as audit:read. Your identity manager decides who holds the role, and a role the map leaves out grants nothing. straza-admin, straza-global-mcp-admin and straza-draft-config cannot appear here, and full cannot be granted. Delegated admin shows it. Empty by default. Set in the file only. |
admin.secondPerson |
none | Makes a second person publish every change that widens access: when true, a person who wrote a revision of a draft other than a Check again that only took live values, who minted an admin API token that wrote one, or who sponsors an agent that wrote one, cannot publish it while its check lists a risk, and a direct admin write that widens access is refused until it goes through a draft. The drafts publish route and the direct admin routes enforce it. False, the default in both profiles, lets the author publish. It does not cover assignments, which stay immediate, or a credential of the person that an agent can read on that machine, and Drafts and publishing explains both. Set in the file only, so a change to this enforcement setting shows in the config file. |
capture.bodyStore.type |
none | Where transcript bodies are kept. Empty, the default, keeps them in the database, and s3 sends them to an S3-compatible bucket, which only the enterprise profile accepts. Set in the file only. Only the four credential keys below have variables. |
capture.bodyStore.endpoint |
none | The host and port of the S3-compatible service, required with type s3. Set in the file only, with bodyStore.type. |
capture.bodyStore.bucket |
none | The bucket the bodies go to, required with type s3. Set in the file only, with bodyStore.type. |
capture.bodyStore.prefix |
none | A key prefix inside the bucket. Empty by default. Set in the file only, with bodyStore.type. |
capture.bodyStore.region |
none | The region of the bucket. Empty by default. Set in the file only, with bodyStore.type. |
capture.bodyStore.accessKey |
STRAZA_CAPTURE_BODYSTORE_ACCESS_KEY |
The access key of the bucket’s account. accessKeyFile wins when both are set. |
capture.bodyStore.accessKeyFile |
STRAZA_CAPTURE_BODYSTORE_ACCESS_KEY_FILE |
Path of a file that holds the access key, preferred over accessKey. |
capture.bodyStore.secretKey |
STRAZA_CAPTURE_BODYSTORE_SECRET_KEY |
The secret key of the bucket’s account. secretKeyFile wins when both are set. |
capture.bodyStore.secretKeyFile |
STRAZA_CAPTURE_BODYSTORE_SECRET_KEY_FILE |
Path of a file that holds the secret key, preferred over secretKey. |
capture.bodyStore.disableSSL |
none | Turns off TLS to the endpoint, for a service inside a private network. The default is false. Set in the file only, with bodyStore.type. |
Sinks
| Key | Environment | Notes |
|---|---|---|
sinks |
none | A list of sinks, each with name, type (webhook or file), url, secret or secretFile, headers, path, subjects and batch. Sinks and SIEM shows them. Set in the file only. |