Gateway configuration file
Every key of gateway.json, the MAQPNA gateway's configuration file, with types, defaults, validation rules and the Helm values that set them.
The MAQPNA gateway reads one JSON file at start-up, gateway.json. It holds the listen addresses, the identity keys it trusts, where policies, the audit ledger and state live, and the settings of every optional feature. This page lists every key the gateway accepts, grouped by area, as defined by the Config struct in cmd/maqpna-gateway/config.go and the files it embeds.
You need this page when you run the gateway outside Helm (for example on a VM or at the edge), when you set gateway.config overrides in the Helm chart, or when maqpna config validate or the gateway reports a key it does not like.
How the gateway loads the file#
flowchart LR
A["-config flag"] --> P{"path"}
B["MAQPNA_GATEWAY_CONFIG"] --> P
C["/etc/maqpna/gateway.json"] --> P
P --> D["strict JSON decode<br/>(unknown key = error)"]
D --> E["normalize: fill defaults,<br/>validate every block"]
E -->|errors| X["exit 1, all errors listed"]
E --> F["-listen overrides listen"]
F --> G["serve"]
- The path is the
-configflag. Without it the gateway usesMAQPNA_GATEWAY_CONFIG, then/etc/maqpna/gateway.json. - The decoder rejects unknown fields.
- Each block fills its defaults and validates. The gateway collects every error and prints them together.
-listenreplaceslistenafter validation.
The gateway binary has four flags:
| Flag | Default | Meaning |
|---|---|---|
-config |
$MAQPNA_GATEWAY_CONFIG, else /etc/maqpna/gateway.json |
Path to the JSON config. |
-listen |
(none) | Overrides listen from the file. |
-check-config |
false |
Validate the file with every gateway rule and exit. Nothing is started or written. Prints config OK: <path>. |
-version |
false |
Print the version and exit. |
Two secrets never go in the file. They come from the environment (or a _FILE variant that names a file holding the value): MAQPNA_ADMIN_TOKEN (static admin token; without it the admin API is disabled in mode token) and MAQPNA_AUDIT_HMAC_KEY (HMAC audit checkpoints). See environment variables.
Check a file before you deploy it#
-
Validate offline with the CLI. It applies the core rules shared with the gateway and warns about unknown keys and missing files:
maqpna config validate gateway.json -
Add
--strictto turn warnings into errors, and--gateway-binary(orMAQPNA_GATEWAY_BIN) to also run the gateway's own full check:maqpna config validate gateway.json --strict --gateway-binary ./maqpna-gateway -
Or run the gateway check directly:
maqpna-gateway -check-config -config gateway.json
maqpna config validate exits 0 when valid (warnings allowed) and 3 on errors. See maqpna config validate.
Minimal file#
The gateway needs a policy file, an audit path, a way to verify session tokens and at least one route (an MCP server, a model route, upstreamsFile or modelsFile):
{
"listen": ":8080",
"policyFile": "/etc/maqpna/policies/policies.json",
"auditPath": "/var/lib/maqpna/audit/ledger.jsonl",
"identity": {
"jwksURL": "http://maqpna-identity.maqpna-system.svc:8081/.well-known/jwks.json"
},
"upstreamsFile": "/etc/maqpna/upstreams/upstreams.json"
}
Core rules#
These rules are shared by the gateway and maqpna config validate (pkg/gatewayconfig):
policyFileis required.auditPathis required.identity.publicKeyFilesoridentity.jwksURLis required.- At least one of
upstreams,upstreamsFile,modelsormodelsFileis set. adminListenmust differ fromlisten(default:8080).auditFailurePolicyisopenorclosed.modelPolicyisscope-onlyorpolicy.tokenExchangeURL, when set, is anhttporhttpsURL with a host.- Each
upstreamsname matches^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$and each URL ishttp(s)with a host. sessionBudgetUSDis 0 or more.shutdownDelaySecondsandshutdownTimeoutSecondsare not negative.
Listeners and HTTP limits#
| Key | Type | Default | Description |
|---|---|---|---|
listen |
string | :8080 |
Address of the main listener (MCP, /llm, /a2a, agent API). |
adminListen |
string | (empty) | When set, the admin API (/v1/* admin endpoints), /metrics and pprof are served only on this address; the main listener answers 404 for them. Bind it to a private interface. Must differ from listen. |
maxBodyBytes |
int64 | 4194304 (4 MiB) |
Largest request body. |
bodyReadTimeoutSeconds |
int | 60 |
Time allowed to read a request body. Response streaming and approval waits are not limited. |
upstreamTimeoutSeconds |
int | 60 |
Time to wait for an upstream's response headers. |
upstreamCAFile |
string | (empty) | PEM CA bundle added to the system pool for upstream TLS. |
corsOrigins |
[]string | (empty) | Browser origins allowed by CORS. |
logLevel |
string | info |
debug, info, warn or error (any other value is info). Logs are JSON on stdout. |
shutdownDelaySeconds |
int | 0 (chart sets 5) |
After SIGTERM, keep serving this long while /readyz already fails, so endpoint removal propagates. |
shutdownTimeoutSeconds |
int | 20 |
Time in-flight requests get to finish after the listener closes. |
tls |
object | off | HTTPS and SVID client certificates. See TLS and workload identity. |
Identity and token verification#
identity is an object.
| Key | Type | Default | Description |
|---|---|---|---|
identity.publicKeyFiles |
[]string | (empty) | PEM files with Ed25519 public (or private) keys. Several keys support rotation. |
identity.jwksURL |
string | (empty) | Identity broker JWKS URL (.../.well-known/jwks.json). |
identity.jwksRefreshSeconds |
int | 300 |
JWKS refresh interval. |
identity.issuer |
string | (empty) | Expected iss claim. |
identity.audience |
string | maqpna-gateway |
Expected aud claim. |
identity.leewaySeconds |
int | 30 |
Clock skew allowed on exp/nbf. |
identity.acceptMLDSA |
bool | false |
Accept ML-DSA (FIPS 204) session tokens signed by AKP keys of the JWKS and mldsaPublicKeyFiles. Off: ML-DSA tokens are refused. |
identity.mldsaPublicKeyFiles |
[]string | (empty) | ML-DSA public keys. |
identity.resourceBaseURL |
string | (empty) | Public base URL of the gateway. The RFC 8707 resource of an MCP server is <resourceBaseURL>/mcp/<name>. Required with trustedIssuers. |
identity.trustedIssuers |
[]object | (empty) | Customer identity providers whose access tokens external MCP clients may present. |
Each identity.trustedIssuers[] entry:
| Key | Type | Default | Description |
|---|---|---|---|
issuer |
string | required | Exact iss. |
namespace |
string | required | Namespace external sessions act in (its policies, budgets and MCP servers apply). |
jwksURL |
string | discovery | Skips OIDC discovery. |
caFile |
string | (empty) | CA for the issuer's TLS certificate. |
algorithms |
[]string | (built-in list) | Allowed signing algorithms. |
jwksRefreshSeconds |
int | 300 |
JWKS refresh interval. |
leewaySeconds |
int | (gateway default) | Clock skew allowed. |
authorizationServer |
string | issuer |
Advertised in the protected-resource metadata. |
agent |
string | external |
Agent name of external sessions in policy and audit. |
agentClaim |
string | (empty) | Derive the agent name from this claim instead (for example client_id or azp), sanitised to a DNS label. |
usernameClaim |
string | preferred_username, then email, then sub |
On-behalf-of user. |
groupsClaim |
string | groups |
Groups claim. |
scopePrefix |
string | (empty) | Stripped from token scopes: maqpna. maps maqpna.tools:github to tools:github. Scopes without the prefix are ignored. |
servers |
[]string | all | MCP servers this issuer's clients may call (globs). |
stepUpScopes |
map[string][]string | (empty) | Extra scopes required for tools/call, keyed <server>/<tool glob>, for example {"github/delete_*": ["tools:github:admin"]}. |
Policies#
| Key | Type | Default | Description |
|---|---|---|---|
policyFile |
string | required | Compiled policies (ConfigMap maqpna-policies, key policies.json). Hot-reloaded. |
policyReloadSeconds |
int | 2 |
Poll interval of every hot-reloaded file (policies, models, MCP servers, credentials, revocations, budgets, memory, tenants). |
modelPolicy |
string | scope-only |
scope-only: model calls need only the route scope. policy: also evaluate policy with server llm/<route> and the operation as tool. |
policy.rego.url |
string | (empty) | OPA Data API decision URL, for example http://127.0.0.1:8181/v1/data/maqpna/authz/decision. Every decision is also evaluated by OPA; the strictest wins. |
policy.rego.timeoutMs |
int | 250 |
Evaluation budget. A timeout denies. |
policy.rego.enforcement |
string | enforce |
enforce or dryRun (audited, never enforced). |
policy.rego.bearerTokenFile |
string | (empty) | OPA API token (OPA --authentication=token). |
sovereigntyPolicyFile |
string | (empty) | A SovereigntyPolicy spec (JSON, or the object with spec). When set, every upstream must comply and all upstream egress goes through the residency-checking dialer. |
MCP servers#
| Key | Type | Default | Description |
|---|---|---|---|
upstreamsFile |
string | (empty) | MCP server registry rendered by the operator (ConfigMap maqpna-upstreams, key upstreams.json). Hot-reloaded. Registry servers take precedence over upstreams. |
upstreams |
map[string]string | (empty) | Deprecated. Static MCP servers, name to URL. Used only when no registry entry or binding matches. Prefer MCPServer resources. |
upstreamCredentialsDir |
string | (empty) | Directory of upstream credentials (Secret maqpna-upstream-credentials), files named <credentialKey>.<suffix>. Re-read every policyReloadSeconds. |
tokenExchangeURL |
string | (empty) | Identity broker RFC 8693 endpoint (.../v1/exchange) for MCP servers with auth type tokenExchange. |
pinStorePath |
string | memory | Journal of observed tool definitions (tool pinning). |
pinCacheSeconds |
int | 60 |
Rate limit of the upstream tools/list fetch used to verify a tool called before it was listed. |
A server name is resolved for the caller in this order: an Agent binding <ns>/<agent>/<server>, the namespace's own MCPServer, exactly one MCPServer shared with the namespace (two or more is ambiguous_server), static upstreams (deprecated), then the implicit server from Agent.spec.tools[].upstreamURL (deprecated). Anything else is unknown_server.
The upstreams.json file is written by the operator, not by hand. Its shape is {"servers": {...}, "bindings": {...}, "agentWeb": {...}}; each server carries url, namespaces, implicit, trust, dataClass, jurisdiction, protocolVersions, timeoutSeconds, caPEM, auth, dlpProfile, pins and toolLabels, rendered from the MCPServer spec.
Model routes#
| Key | Type | Default | Description |
|---|---|---|---|
modelsFile |
string | (empty) | Model routes rendered by the operator, {"models": {route: ...}} (ConfigMap maqpna-models, key models.json). Hot-reloaded. A missing file means no file routes. Routes here override models. |
models |
map[string]object | (empty) | Static model routes, route name to route. |
modelRouting |
object | see below | Failover and route selection. |
pricingFile |
string | (empty) | Pricing table used to meter cost. |
cloudCredentials |
object | environment only | Overrides of the cloud workload identity environment. See Cloud credentials. |
Each model route (models.<route>):
| Key | Type | Default | Description |
|---|---|---|---|
upstream |
string | required for openai |
OpenAI-compatible base URL including /v1, for example http://vllm.models.svc:8000/v1. Other providers may derive it from region. |
model |
string | (empty) | Forced into every request's model field. |
namespaces |
[]string | any | Namespace allow-list. |
agents |
[]string | any | Agent allow-list. |
dlpProfile |
string | (bindings) | dlpProfiles entry for this route; none disables DLP. Overrides dlp bindings. |
jurisdiction |
string | (empty) | Where the primary upstream runs, for example EU-DE. |
preferJurisdiction |
string | (empty) | Endpoints in this jurisdiction are tried first. |
requestsPerMinute |
int | 0 (unlimited) |
Rate cap on the primary upstream. |
apiKeyFile |
string | (empty) | Credential presented to the primary upstream. The agent's session token is always stripped. |
providerTools |
[]string | (none allowed) | Provider-hosted tools allowed on this route (web_search, web_fetch, code_execution, file_search, code_interpreter, computer_use, image_generation, google_search, url_context, system_tool, or a versioned type such as web_search_20250305). Unlisted ones are refused. |
fallbacks |
[]object | (empty) | Endpoints tried in order when the primary fails (transport error, timeout, 5xx, 429), its circuit is open or its rate is exhausted. Each has upstream, model, jurisdiction, requestsPerMinute, apiKeyFile and its own provider keys. Nothing is inherited from the route. |
provider |
string | openai |
openai, azure-openai, bedrock, vertex, gemini, anthropic, oci-genai or llamay. |
mode |
string | per provider | azure-openai: v1 or deployments. bedrock: converse or openai. vertex: native or openai. anthropic: direct, vertex or bedrock. |
region |
string | (empty) | Provider region (Bedrock region, Vertex AI location, OCI region). Derives the default upstream and the endpoint's jurisdiction. |
project |
string | (empty) | Google Cloud project (Vertex AI). |
apiVersion |
string | 2024-10-21 (Azure) / 2023-06-01 (Anthropic) |
Azure OpenAI api-version of mode deployments, or the anthropic-version header. |
auth.type |
string | per provider | api-key, bearer, aws-sigv4, gcp, azure-entra, oci or none. Default: api-key when apiKeyFile is set, else aws-sigv4 for Bedrock, gcp for Vertex AI, azure-entra for Azure OpenAI, oci for OCI, none otherwise. |
auth.tokenFile |
string | (empty) | Short-lived access token kept fresh by a sidecar, re-read on every call. |
auth.tokenEnv |
string | GOOGLE_OAUTH_ACCESS_TOKEN for gcp |
Environment variable of the gateway holding the access token. |
auth.accessKeyIdFile, auth.secretAccessKeyFile, auth.sessionTokenFile |
string | (empty) | AWS credentials, re-read per call. Without them: AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN, then cloud workload identity. |
auth.signingService |
string | bedrock |
SigV4 service name. |
aliases |
map[string]string | (empty) | Model names agents use mapped to provider model IDs ("fast": "<provider-model-id>"). |
reasoning |
bool | detected | Model takes max_completion_tokens instead of max_tokens (detected for OpenAI o-series and gpt-5 IDs). |
modelRouting:
| Key | Type | Default | Description |
|---|---|---|---|
failureThreshold |
int | 3 |
Consecutive failures (transport, timeout, 5xx, 429) that open an endpoint's circuit. |
cooldownSeconds |
int | 30 |
Time an open circuit waits before one trial request. |
attemptTimeoutSeconds |
int | upstreamTimeoutSeconds |
Wait for one endpoint's response headers before failing over. |
probeIntervalSeconds |
int | 0 (passive) |
Active probe (GET <base>/models) of open circuits. |
tierJurisdictions |
map[string]string | (empty) | Trust tier to preferred jurisdiction; overrides the route's preferJurisdiction. |
dataClassModels |
map[string][]string | (empty) | Per data class (public, internal, confidential, restricted), model globs allowed once a session touched an MCP server of that class. A class without an entry inherits the next lower class. |
See model providers for worked examples.
Audit ledger#
| Key | Type | Default | Description |
|---|---|---|---|
auditPath |
string | required | Audit ledger file (JSONL, hash-chained). Many other paths default next to it. |
auditFailurePolicy |
string | open |
open: a failed append is logged and the call proceeds. closed: an intent record must be durable before an allowed call is forwarded. |
auditCheckpointKey |
string | (empty) | Key URI (file:///, kms://, azurekv://, pkcs11:) of the key that signs checkpoints (JWS; Ed25519, P-256 or RSA). Public JWKS at /v1/audit/jwks. |
auditCheckpointPQKey |
string | (empty) | ML-DSA-44/65/87 key URI. With auditCheckpointKey it makes checkpoints hybrid. Requires auditCheckpointKey. |
auditCheckpointIntervalSeconds |
int | 60 |
Signed checkpoint interval. |
auditCheckpointEvery |
int64 | 1000 |
Also checkpoint after this many records, whichever comes first. Also the cadence of HMAC checkpoints. |
auditCheckpointPublicKeyFiles |
[]string | (empty) | Retired public keys still published in the JWKS. |
auditSinks |
[]object | (empty) | SIEM streaming. See below. |
auditAcceptDivergedMirror |
bool | false |
Let a replica whose local mirror is not a prefix of the shared chain move it aside and rebuild. Default: refuse to start. |
transparencyLog |
object | off | Anchor ledger heads in Rekor. See Evidence and anchoring. |
Each auditSinks[] entry:
| Key | Type | Default | Description |
|---|---|---|---|
name |
string | required | [a-z0-9][a-z0-9-]{0,39}; used for the cursor file and metrics label. |
type |
string | required | syslog, http, jsonl, sentinel, chronicle, cloudwatch or splunk-hec. |
address |
string | (empty) | Syslog endpoint tcp://host:port or tls://host:port. |
url |
string | (empty) | HTTP(S) collector (type http), data collection endpoint (sentinel), SecOps instance (chronicle), endpoint override (cloudwatch) or HEC URL. No credentials in the URL. |
path |
string | (empty) | Output file (type jsonl). |
format |
string | syslog rfc5424-json, http ocsf, jsonl json |
json, rfc5424-json, cef or ocsf. |
caFile, certFile, keyFile, serverName |
string | (empty) | TLS; certFile + keyFile enable mutual TLS. |
headersFile |
string | (empty) | Extra HTTP headers, one Name: value per line. |
batchSize |
int | 100 |
Records per delivery. |
pollIntervalMillis |
int | 1000 |
Ledger check interval. |
facility |
int | 13 |
Syslog facility. |
sdId |
string | maqpna@32473 |
RFC 5424 SD-ID. |
timeoutSeconds |
int | 15 |
One delivery. |
tokenFile |
string | (empty) | Bearer or HEC token, re-read when it changes. |
awsCredentialsDir |
string | (empty) | Directory with access-key, secret-key and optional session-token files (cloudwatch). |
credentials |
string | (empty) | Keyless workload identity: aws (cloudwatch), azure (sentinel) or gcp (chronicle). |
dcrImmutableId, streamName |
string | (empty) | Sentinel data collection rule. |
chronicleMode, logType |
string | logs |
Chronicle logs or udm. |
region, logGroup, logStream |
string | (empty) | CloudWatch Logs. |
index, source, sourceType |
string | sourceType maqpna:audit |
Splunk HEC metadata. |
maxBatchBytes |
int | collector limit | Lower per-request byte limit. |
deadLetterPath |
string | <cursor dir>/<name>.deadletter.jsonl |
Records the collector rejects permanently. |
deadLetterMaxBytes |
int64 | 64 MiB | When full, delivery stops instead of dropping records. |
See SIEM and audit forwarding.
Approvals and admin access#
| Key | Type | Default | Description |
|---|---|---|---|
approvalTimeoutSeconds |
int | 300 |
Lifetime of a pending approval. |
approvalStorePath |
string | memory | Approvals journal (JSONL), kept across restarts. |
approvalPreview.mode |
string | redacted |
What approvers and notifications see of arguments: none, hash, redacted or full. Raw arguments are stored only in full. |
approvalPreview.maxBytes |
int | 4096 |
Preview size cap. |
approvalQuorum.default |
object | 1 approver | Four-eyes rule for every require_approval. |
approvalQuorum.rules |
map[string]object | (empty) | Overrides keyed <policy>/<rule>, <policy>/* or */<rule> (globs). |
consoleURL |
string | (empty) | Linked from notifications ("Open console"). |
notifiers |
[]object | (empty) | Approval notifications. |
notifyOutboxPath |
string | memory | Undelivered notifications, kept across restarts. |
A quorum rule (approvalQuorum.default or a rules value) has minApprovers (int, default 1, range 0 to 10), approverGroups ([]string; restricts approvers) and userConfirmation (ciba: the delegating user confirms instead of approvers).
adminAuth:
| Key | Type | Default | Description |
|---|---|---|---|
adminAuth.mode |
string | token |
token (static MAQPNA_ADMIN_TOKEN only), oidc (OIDC bearer tokens only) or both (OIDC plus the static token as break-glass). |
adminAuth.roles |
map[string][]string | (empty) | Role to groups granting it in every namespace. An entry user:<name> grants it to one user. Roles: viewer, approver, auditor, admin, killswitch and audit-forwarder (an offline edge pushing ledger segments to a collector). |
adminAuth.namespaceRoles |
map[string]map[string][]string | (empty) | Roles for one namespace: {"team-a": {"approver": ["team-a-leads"]}}. |
adminAuth.devTokenApprovers |
bool | false |
Development only (maqpna dev up sets it). In mode token, static-token votes are told apart by approver name. Never set it in production. |
adminAuth.oidc.issuer |
string | required in oidc/both |
http(s) issuer URL. |
adminAuth.oidc.audience |
string | required in oidc/both |
Expected audience. |
adminAuth.oidc.jwksURL |
string | discovery | Skips /.well-known/openid-configuration. |
adminAuth.oidc.jwksRefreshSeconds |
int | 300 |
JWKS refresh. |
adminAuth.oidc.usernameClaim |
string | preferred_username, then email, then sub |
Name of the approver in the ledger. |
adminAuth.oidc.groupsClaim |
string | groups |
Dotted paths such as realm_access.roles work. |
adminAuth.oidc.algorithms |
[]string | RS256, ES256, EdDSA |
Allowed algorithms. |
adminAuth.oidc.caFile |
string | (empty) | CA for the issuer. |
adminAuth.oidc.leewaySeconds |
int | (default) | Clock skew. |
adminAuth.oidc.clientID, adminAuth.oidc.scopes |
string, []string | (empty) | Published at GET /v1/auth/config for the console's PKCE login. Public values only. |
Each notifiers[] entry:
| Key | Type | Default | Description |
|---|---|---|---|
name |
string | required | Unique; same syntax as an MCP server name. |
type |
string | required | webhook, slack, teams or matrix. |
url |
string | required for webhook |
Webhook URL. |
webhookURLFile |
string | required for slack/teams (or url) |
File holding the incoming-webhook URL. |
hmacSecretFile |
string | (empty) | Signs outbound webhooks and verifies signed callbacks. |
signingSecretFile |
string | (empty) | Slack app signing secret (interactive callbacks). |
homeserver, roomId, accessTokenFile |
string | required for matrix |
Matrix target. |
events |
[]string | all | Event types to send. |
userMap |
map[string]string or object | (empty) | Chat user id to approver: "[email protected]" or {"user": "...", "groups": [...], "namespaces": [...]}. |
callbackOIDC |
object | (empty) | issuer, audience, jwksURL, discoveryURL to verify callback bearer tokens (Teams). |
See human approvals and notifications.
Kill switch and revocations#
| Key | Type | Default | Description |
|---|---|---|---|
revocationsFile |
string | (empty) | Revocation list (ConfigMap maqpna-revocations, key revocations.json). When set, a missing, unreadable or invalid file denies every call. |
revocationsRecheckMillis |
int | 250 |
Maximum staleness of the in-memory list: a request re-stats the file when the last check is older. -1 leaves reloading to policyReloadSeconds. |
revocationsJournalPath |
string | <auditPath>.revocations.jsonl |
Break-glass revocations (POST /v1/revocations), kept across restarts. |
revocationMirror.enabled |
bool | false |
Mirror break-glass revocations to AgentRevocation objects so every replica and the operator apply them. |
revocationMirror.namespace |
string | maqpna-system |
Namespace for cluster-wide entries. |
Budgets and cost#
| Key | Type | Default | Description |
|---|---|---|---|
sessionBudgetUSD |
float64 | 0 (none) |
Per-session spend limit. Must be 0 or more. |
budgetsFile |
string | (empty) | Budgets rendered from BudgetPolicy and Agent.spec.budget (ConfigMap maqpna-budgets, key budgets.json). Hot-reloaded. |
budgetTimezone |
string | UTC |
IANA zone of day and month windows. |
budgetCurrency |
string | pricing table currency, else USD |
ISO 4217 currency of budgets, cost and the FOCUS export. Budgets in another currency are rejected. |
finopsStatePath |
string | <auditPath>.finops.json |
Metered totals and windows; rebuilt from the ledger when missing. |
finopsSaveSeconds |
int | 10 |
Save cadence. |
energy.enabled |
bool | false |
Energy and carbon estimates with the built-in table. |
energy.file |
string | (empty) | Energy model file; implies enabled. |
energy.defaultRegion |
string | (empty) | Location of sessions without one. |
sandboxUsage.enabled |
bool | false |
Accept the operator's sandbox-time reports (POST /v1/usage/sandbox). |
sandboxUsage.reporters |
[]string | (empty) | ServiceAccount usernames allowed to report (system:serviceaccount:<ns>:<name>). |
sandboxUsage.audience |
string | maqpna-sandbox-usage |
Audience of the reporter's projected token. |
DLP, taint and guards#
| Key | Type | Default | Description |
|---|---|---|---|
dlpProfiles |
map[string]object | (empty) | Named DLP profiles. |
dlp.defaultProfile |
string | (empty) | Profile for traffic with no closer binding. |
dlp.namespaces |
map[string]string | (empty) | Namespace to profile. |
dlp.servers |
map[string]string | (empty) | MCP server to profile. |
dlp.models |
map[string]string | (empty) | Model route to profile. |
taintStorePath |
string | memory | Session taint journal. |
taintRetentionSeconds |
int | 86400 |
How long taint outlives a session's last tool call (never shorter than token expiry). |
guards |
[]object | (empty) | Injection classifiers. |
captureArgs |
object | off | Encrypted, redacted argument captures for maqpna replay. |
Binding precedence: the server's or route's own dlpProfile, then dlp.servers / dlp.models, then dlp.namespaces, then dlp.defaultProfile. none disables DLP for that binding.
A DLP profile (dlpProfiles.<name>):
| Key | Type | Default | Description |
|---|---|---|---|
detectors |
[]string | every validated detector except email, phone_e164, ipv4_private, high_entropy_secret |
Built-in detector IDs. |
custom |
[]object | (empty) | {"id": "[a-z0-9_]{1,40}", "regex": "...", "secret": false}. |
requestAction |
string | redact |
Tool arguments and prompts: off, audit, redact or deny. |
responseAction |
string | redact |
Tool results and completions. |
onSecret |
string | (empty) | Action for secret-class detectors in both directions. |
maxScanBytes |
int | 1 MiB | Text scanned per message. |
onOversize |
string | deny where enforcing, else audit |
Action when a message exceeds maxScanBytes. |
streamCarryBytes |
int | 256 |
Hold-back window for matches split across chunks; -1 disables. |
entropyMinLength, entropyThreshold |
int, float | 32, 4.3 |
Tune high_entropy_secret. |
Each guards[] entry:
| Key | Type | Default | Description |
|---|---|---|---|
name |
string | required | Unique. |
type |
string | required | openai-moderation, llama-prompt-guard, lakera, bedrock-guardrail or http-json. |
url |
string | required | Classifier endpoint (residency-checked). |
model |
string | (empty) | Classifier model. |
apiKeyFile |
string | (empty) | Bearer token (or Bedrock API key). |
on |
[]string | ["toolResult"] |
toolResult, toolArgs, llmPrompt. |
namespaces, servers, tools |
[]string | any | Globs; servers include llm/<route>. |
threshold |
float | 0.5 |
A score at or above flags the content. Range (0, 1]. |
label |
string | prompt-injection-suspected |
Taint label added when flagged. |
action |
string | taint |
taint or block. |
timeoutMs |
int | 300 |
Classification budget; late results still taint. |
failOpen |
bool | true |
When the classifier is unavailable the call proceeds (audited guard_unavailable). |
maxBytes |
int | 16384 |
Text per call; longer text is classified in up to 32 windows. |
scorePath |
string | score |
http-json: dotted path of the score. |
category |
string | max category | openai-moderation: one category. |
positiveIndex |
int | 1 |
llama-prompt-guard: index of the malicious class. |
region |
string | from URL host | bedrock-guardrail: AWS region. |
captureArgs:
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
bool | false |
Turn captures on. |
dir |
string | required when enabled | <dir>/<namespace>/<xx>/<argsSha256>.cap. |
key |
string | required when enabled | Key URI of the customer-held AES-256-GCM key. |
namespaces |
[]string | all | Globs. |
retentionDays |
int | 30 |
Captures not seen this long are deleted. |
dlpProfile |
string | built-in redact-all profile | Redaction before capture. |
Sessions, sandbox tools and memory#
| Key | Type | Default | Description |
|---|---|---|---|
activity.enabled |
bool | false |
Write last-activity annotations on AgentSession (idle suspend). |
activity.intervalSeconds |
int | 60 |
Throttle per session. |
activity.apiServer, activity.tokenFile, activity.caFile |
string | in-cluster | Kubernetes API access overrides. |
sessions.traceURLTemplate |
string | (empty) | Links timeline items to your tracing backend. Placeholders {traceId} (required), {spanId}, {session}, {namespace}. |
sessions.timelineMaxItems |
int | 1000 (max 10000) |
Largest page of GET /v1/sessions/{id}/timeline. |
sessions.listMaxSessions |
int | 500 (max 5000) |
Largest page of GET /v1/sessions. |
memoryFile |
string | (empty) | MemoryStore list (ConfigMap maqpna-memory, key memory.json). Hot-reloaded. |
memoryDataDir |
string | <dir of auditPath>/memory |
Built-in memory backend data. |
memorySweepSeconds |
int | 3600 |
Retention sweep cadence. |
exec.enabled |
bool | false |
POST /v1/sessions/{id}/exec code-interpreter proxy. |
exec.endpointTemplate |
string | http://{session}.{namespace}.svc.cluster.local:8888 |
Must contain {session}. |
exec.maxTimeoutSeconds |
int | 300 |
Per exec. |
exec.maxOutputBytes |
int64 | 10 MiB | Output cap. |
exec.keyFile |
string | (empty) | Sent as X-Maqpna-Exec-Key. |
egress.enabled |
bool | false |
Browser egress proxy (HTTP CONNECT on the main listener). |
liveView.enabled |
bool | false |
Live-view proxy for approvers. |
liveView.endpointTemplate |
string | http://{session}.{namespace}.svc.cluster.local:6080 |
Must contain {session}. |
evidence.dir |
string | <auditPath>.evidence |
Evidence objects (screenshots, recordings) when no WORM sink is set. |
evidence.maxBytes |
int64 | 50 MiB | Per object. |
web configures the built-in maqpna-web MCP server:
| Key | Type | Default | Description |
|---|---|---|---|
web.enabled |
bool | false |
Serve maqpna-web. |
web.allowedDomains, web.deniedDomains |
[]string | (empty) | Gateway-level lists. Strictest level wins. |
web.namespaces |
map[string]object | (empty) | Per-namespace allowedDomains / deniedDomains. |
web.defaultAllow |
bool | false |
Allow any host when no level has an allow-list. |
web.allowedPorts |
[]int | [80, 443] |
Allowed ports. |
web.allowedCIDRs |
[]string | (empty) | Exceptions to the SSRF block list. |
web.allowIPLiterals |
bool | false |
Allow IP-address hosts. |
web.maxBytes |
int64 | 2 MiB (max 32 MiB) | Fetched body cap. |
web.timeoutSeconds |
int | 15 |
One fetch, including redirects. |
web.maxRedirects |
int | 5 |
Each hop is re-checked. |
web.contentTypes |
[]string | text/html, text/plain, text/markdown, text/csv, text/xml, application/xhtml+xml, application/xml, application/json | Allowed media types. |
web.respectRobots |
bool | false |
Honour robots.txt. |
web.userAgent |
string | maqpna-web/1.0 (+governed fetch) |
User agent. |
web.taintLabels |
[]string | ["untrusted-input"] |
Added to the session after every result. |
web.search.backend |
string | none |
none, searxng or opensearch. |
web.search.url |
string | required for a backend | Search endpoint. |
web.search.index |
string | required for opensearch |
Index. |
web.search.fields |
[]string | ["title^2", "content"] |
OpenSearch fields. |
web.search.urlField, titleField, snippetField |
string | url, title, content |
OpenSearch field names. |
web.search.authHeaderFile |
string | (empty) | Full Authorization header value, re-read per request. |
web.search.caFile |
string | (empty) | CA bundle. |
web.search.maxResults |
int | 10 (max 50) |
Result cap. |
k8sOps configures the governed Kubernetes operations MCP server:
| Key | Type | Default | Description |
|---|---|---|---|
k8sOps.enabled |
bool | false |
Serve the tools. |
k8sOps.apiServer, tokenFile, caFile |
string | in-cluster | API access overrides. |
k8sOps.serviceAccount |
string | (empty: gateway's own identity, development only) | <namespace>/<name> impersonated on every call. |
k8sOps.namespaces |
[]string | all | Readable namespaces. |
k8sOps.allowClusterScoped |
bool | false |
Nodes, namespaces and PVs when namespaces are restricted. |
k8sOps.maxLogLines |
int | 200 (max 5000) |
get_pod_logs lines. |
k8sOps.maxLogBytes |
int64 | 64 KiB (max 1 MiB) | get_pod_logs bytes. |
k8sOps.maxListItems |
int | 200 (max 1000) |
List results. |
k8sOps.timeoutSeconds |
int | 10 |
One API call. |
k8sOps.taintLabels |
[]string | ["untrusted-input"] |
Added after logs are read. |
k8sOps.writes.mode |
string | proposal |
disabled, proposal (patch returned, never applied) or apply. |
k8sOps.writes.approval |
string | required |
required (every applied write held for approval) or policy. |
k8sOps.writes.namespaces |
[]string | read namespaces | Writable namespaces. |
k8sOps.writes.maxReplicas |
int | 50 |
scale_workload cap. |
infra governs Terraform and OpenTofu plans:
| Key | Type | Default | Description |
|---|---|---|---|
infra.enabled |
bool | false |
Serve the infra endpoints (404 when off). |
infra.tiers |
object | built-in AWS, Google Cloud, Azure lists | sensitiveTypes, addSensitiveTypes, dataBearingTypes, addDataBearingTypes, protectedAddresses, addProtectedAddresses, maxResources (default 50). |
infra.requireApprovalAtTier |
int | 3 |
Applies of this tier or higher are held for approval; 5 never. |
infra.maxTier |
int | 4 (no cap) |
Applies above this tier are denied. |
infra.denyTypes |
[]string | (empty) | Resource-type globs always denied. |
infra.maxPlanBytes |
int64 | 16 MiB (max 256 MiB) | Request size. |
infra.authorizationTTLSeconds |
int | 3600 |
How long an allowed apply may wait, and how long a started one is tracked. |
infra.budgets.perSession, infra.budgets.perAgent |
object, map | (empty) | resourcesPerHour (0 unlimited) and maxTier; perAgent keyed by agent, * for the rest. |
Agent-to-agent, delegation and user credentials#
| Key | Type | Default | Description |
|---|---|---|---|
a2a.routesFile |
string | (empty) | A2A routing table (ConfigMap maqpna-a2a, key a2a.json). |
a2a.cardSigningKey |
string | (empty: unsigned) | Key URI of the Ed25519 key signing served Agent Cards. |
a2a.publicURL |
string | request host | External base URL in cards. Required with cardSigningKey. |
a2a.publicCards |
bool | false |
Serve cards without a token. |
a2a.cardCacheSeconds |
int | 300 |
Reuse of a verified remote card. |
a2a.maxDelegationDepth |
int | 5 |
Cap on the caller's act chain. |
a2a.pushNotificationHosts |
[]string | (empty: refused) | https host globs push-notification webhooks may target. |
txnTokens.mode |
string | off |
off, add (Txn-Token plus X-Maqpna-* headers) or replace. |
txnTokens.signingKey |
string | required unless off |
Ed25519 key URI. |
txnTokens.issuer |
string | maqpna-gateway |
iss. |
txnTokens.audience |
string | required unless off |
Trust domain. |
txnTokens.workloadID |
string | spiffe://<audience>/maqpna/gateway |
req_wl. |
txnTokens.ttlSeconds |
int | 60 (max 300) |
Lifetime. |
dpop.require |
bool | false |
Refuse tokens not bound with DPoP (except at the egress proxy). |
dpop.maxAgeSeconds |
int | 60 (0 to 600) |
Proof age. |
dpop.publicURL |
string | identity.resourceBaseURL |
Gateway URL as agents address it. |
tokenVault keeps users' OAuth tokens for per-user MCP servers:
| Key | Type | Default | Description |
|---|---|---|---|
tokenVault.enabled |
bool | false |
Turn the vault on. |
tokenVault.keyURI |
string | required | Customer-held AES-256 key URI. |
tokenVault.retiredKeyURIs |
[]string | (empty) | Old keys; records are re-sealed at start-up. |
tokenVault.storePath |
string | <auditPath>.vault.jsonl |
Vault journal. |
tokenVault.publicBaseURL |
string | identity.resourceBaseURL |
Browser-facing URL for redirects; https in production. |
tokenVault.login |
object | (empty) | OIDC client for the consent flow: issuer, clientID, clientSecretFile, scopes, usernameClaim, caFile, authorizationURL, tokenURL, jwksURL. |
tokenVault.providers |
[]object | (empty) | name, preset (github, microsoft, google, salesforce, slack, generic; default generic), clientID, clientSecretFile, authorizationURL, tokenURL, revocationURL, scopes, extraAuthParams, tenant, domain, clientAuth (post default or basic), disablePKCE, issuer, resource, caFile, grant (authorization_code default or id-jag), idJag (idpTokenURL, idpClientID, idpClientSecretFile, audience, resource, scopes), allowedServers, allowedNamespaces, allowAnyServer. |
tokenVault.flowTTLSeconds |
int | 600 |
Consent flow lifetime. |
tokenVault.allowUnverifiedPrincipal |
bool | false |
Inject tokens for sessions whose user was not verified. |
tokenVault.externalUserIssuers |
[]string | (empty) | Trusted issuers whose usernames are the same people as the vault login. |
tokenVault.userRealm |
string | login.issuer, else admin OIDC issuer, else maqpna |
Realm accounts are keyed under. Changing it orphans accounts. |
tokenVault.isolateExternalIssuers |
bool | false |
Serve other external issuers from their own realm instead of refusing them. |
tokenVault.keepOnKillSwitch |
bool | false |
Do not revoke a user's tokens on a matching cluster-wide terminate revocation. |
tokenVault.mirror.enabled, tokenVault.mirror.namespace |
bool, string | false, maqpna-system |
Write ConnectedAccount status objects (no secrets). |
ciba asks the delegating user to confirm on their own device:
| Key | Type | Default | Description |
|---|---|---|---|
ciba.enabled |
bool | false |
Turn CIBA on. |
ciba.issuer |
string | required | OpenID Provider issuer; endpoints are discovered. |
ciba.backchannelAuthenticationEndpoint, ciba.tokenEndpoint, ciba.jwksURL |
string | discovery | Endpoint overrides. |
ciba.clientID, ciba.clientSecretFile |
string | required, (empty) | Gateway's CIBA client (poll mode). |
ciba.clientAuth |
string | basic |
basic or post. |
ciba.caFile, ciba.scopes, ciba.acrValues |
string, []string | (empty) | TLS and request parameters. |
ciba.userClaim |
string | preferred_username, then email, then sub |
Must equal the delegating user. |
ciba.requestedExpirySeconds |
int | approval's remaining life | User's time to answer. |
ciba.fallback |
string | approvers |
approvers or deny when CIBA is unavailable. |
ciba.bindingMessagePrefix |
string | MAQPNA |
Start of the binding message. |
TLS and workload identity#
| Key | Type | Default | Description |
|---|---|---|---|
tls.certFile, tls.keyFile |
string | (empty: plain HTTP) | Serving certificate (for example the gateway's SVID). Reloaded on change. |
tls.clientCAFile |
string | (empty) | SPIFFE trust bundle client SVIDs must chain to. |
tls.svidMode |
string | off |
off, optional or required: bind SVID client certificates to session tokens. |
tls.svidTrustDomains |
[]string | any in bundle | Accepted trust domains. |
tls.reloadSeconds |
int | 30 |
File reload check. |
State and high availability#
| Key | Type | Default | Description |
|---|---|---|---|
stateBackend.type |
string | file |
file or postgres. |
stateBackend.dsnFile |
string | required for postgres |
File holding the connection string. Never inline. |
stateBackend.schema |
string | maqpna |
Schema, created if missing; ^[a-z_][a-z0-9_]{0,62}$. |
stateBackend.maxConns |
int | 10 |
Pool size per process. |
stateBackend.pollMillis |
int | 250 |
How often a replica pulls other replicas' writes. |
stateBackend.leader.retryMillis |
int | 1000 |
Leader election retry and lease check. |
stateBackend.counters |
string | shared for postgres, local for file |
Where rate-limit windows live. shared needs postgres. |
configSync.enabled |
bool | false |
Read operator ConfigMaps from the API (about 1 s) instead of waiting 60 to 90 s for volume refresh. |
configSync.namespace |
string | $POD_NAMESPACE |
ConfigMap namespace. |
configSync.pollMillis |
int | 1000 |
Poll interval. |
configSync.apiServer, tokenFile, caFile |
string | in-cluster | API access overrides. |
configSync.items |
[]object | (empty) | configMap, key, path (all required) and optional. Each item is written atomically to path. |
resourceAPI.enabled |
bool | false |
Serve the resource model without Kubernetes. |
resourceAPI.dir |
string | (empty: postgres backend, then required) | YAML files <plural>/<namespace>/<name>.yaml. |
posture.replicas |
int | 0 (chart sets gateway.replicas) |
Deployed replica count, used by the state-backend posture check. |
posture.accept |
[]string | (empty) | Check IDs accepted as risks. |
See state backend and scaling and HA.
Tenants and licence#
| Key | Type | Default | Description |
|---|---|---|---|
tenantsFile |
string | (empty: single tenant) | Tenant list (ConfigMap maqpna-tenants, key tenants.json). Hot-reloaded. |
tenantLedgerDir |
string | <dir of auditPath>/tenants |
Per-tenant ledgers <dir>/<tenant>/audit.jsonl. |
licenseFile |
string | (empty: Community) | Installed licence. It only switches paid features on and never affects agent traffic. |
Telemetry#
| Key | Type | Default | Description |
|---|---|---|---|
otel.enabled |
bool | false (propagation only) |
Export spans. |
otel.endpoint |
string | required when enabled | OTLP/HTTP base URL (/v1/traces is appended). Must pass the residency check. |
otel.protocol |
string | http/json |
The only supported value. |
otel.headersFile |
string | (empty) | Export headers, one Name: value per line. |
otel.caFile |
string | (empty) | Collector CA. |
otel.serviceName |
string | maqpna-gateway |
service.name. |
otel.sampleRatio |
float | 1 |
Root-span sampling, 0 to 1. |
otel.recordArgs |
bool | false |
Add maqpna.args_sha256 and maqpna.args_bytes (never contents). |
otel.recordUser |
bool | false |
Add enduser.id. |
otel.resourceAttributes |
map[string]string | (empty) | Extra resource attributes. |
otel.maxQueueSize |
int | 2048 |
Queue bound; overflow is dropped and counted. |
otel.maxExportBatchSize |
int | 512 |
Batch size. |
otel.exportIntervalMillis |
int | 5000 |
Max delay. |
otel.exportTimeoutSeconds |
int | 10 |
Per export request. |
otel.genAI.captureContent |
bool | false |
Add GenAI content attributes, always DLP-redacted first. |
otel.genAI.contentDlpProfile |
string | built-in profile | Must name a dlpProfiles entry. |
otel.genAI.maxContentBytes |
int | 16384 |
Larger content is dropped, not truncated. |
otel.genAI.emitLegacySystem |
bool | false |
Also set gen_ai.system. |
See OpenTelemetry and GenAI telemetry.
Evidence and anchoring#
| Key | Type | Default | Description |
|---|---|---|---|
transparencyLog.enabled |
bool | false |
Anchor ledger heads in Rekor. Needs url and auditCheckpointKey. |
transparencyLog.url |
string | (empty) | Rekor base URL (public, v2 shard or private). |
transparencyLog.api |
string | v1 |
v1 or v2. |
transparencyLog.intervalSeconds |
int | 0 (on demand) |
Anchor cadence when the head advanced. |
transparencyLog.publicKeyFiles |
[]string | (empty) | Pin the log's key (PEM or Sigstore trusted_root.json). |
transparencyLog.timeoutSeconds |
int | 30 |
One submission. |
configBundle.enabled |
bool | false |
Apply signed configuration bundles. |
configBundle.dir |
string | required | Where bundle files land; point policyFile, modelsFile, ... into it. |
configBundle.trustedKeyFiles |
[]string | (empty) | PEM public keys (Ed25519, P-256, RSA, ML-DSA). |
configBundle.trustedIssuers |
[]string | any | Accepted manifest issuers. |
configBundle.signaturePolicy |
string | classical |
classical, hybrid or pq. |
configBundle.statePath |
string | <auditPath>.config-bundle.json |
Revision in force (rollback protection). |
configBundle.maxBytes |
int64 | 64 MiB | Bundle size. |
configBundle.leewaySeconds |
int | 60 |
Clock skew for validity. |
configBundle.push |
bool | false |
Enable POST /v1/admin/config:bundle. |
configBundle.pull |
object | (empty) | url, tokenFile, caFile, maxBackoffSeconds (default 300). |
configBundle.dropDir |
string | (empty) | Scanned for *.tar.gz / *.tgz. |
configBundle.pollSeconds |
int | 30 |
Pull and drop-dir cadence. |
See config bundles and transparency log.
Offline edge and collector#
| Key | Type | Default | Description |
|---|---|---|---|
offline.enabled |
bool | false |
Run as an edge that spools signed ledger segments. Needs auditCheckpointKey. |
offline.edgeId |
string | (empty) | Edge name (letters, digits, ., _, -). |
offline.spoolDir |
string | <auditPath>.spool |
Sealed segments. |
offline.spoolMaxBytes |
int64 | 1 GiB | Spool bound. |
offline.fullPolicy |
string | failClosed |
failClosed or dropOldestForwarded. |
offline.segmentMaxRecords |
int64 | 1000 |
Segment rollover. |
offline.sealIntervalSeconds |
int | 60 |
Seal cadence. |
offline.collectorKeyFiles |
[]string | (empty: nothing acknowledged) | Collector receipt keys. |
offline.forward |
object | (empty) | url, tokenFile, caFile, intervalSeconds (10), maxBackoffSeconds (300), timeoutSeconds (30). |
offline.receiptDropDir |
string | (empty) | Receipts carried back on removable media. |
offline.disconnectedAfterSeconds |
int | 300 |
Silence before the edge counts as disconnected. |
offline.maxRevocationStalenessSeconds |
int | 0 (off) |
Deny highRiskTools when the revocation list is older. |
offline.highRiskTools |
[]string | every tool | server/tool globs. |
offline.approvals |
string | deny |
While disconnected: deny or localApprovers. |
offline.localApprovers |
[]string | (empty) | user:<name> or groups. |
auditCollector.enabled |
bool | false |
Receive edge segments. Needs auditCheckpointKey. |
auditCollector.id |
string | host name | Collector name in receipts. |
auditCollector.dir |
string | <auditPath>.edges |
One ledger per edge. |
auditCollector.edges |
[]object | (empty) | id and publicKeyFiles per edge. |
auditCollector.dropDir |
string | (empty) | Segment files on removable media. |
auditCollector.pollSeconds |
int | 30 |
Drop-dir cadence. |
auditCollector.maxSegmentBytes |
int64 | 64 MiB | Per segment. |
See offline edge.
Product integrations#
| Key | Type | Default | Description |
|---|---|---|---|
llamay.upstream |
string | (empty) | OpenAI base URL of a managed llamay. Endpoints on its origin are llamay endpoints. |
llamay.apiKeyFile |
string | (empty) | Key for llamay endpoints without their own. |
llamay.stateless |
bool | false |
Turn per-session context binding off. |
llamay.contextIdleSeconds |
int | 1800 |
Drop idle contexts. |
llamay.maxContexts |
int | 4096 |
Bound contexts (LRU). |
llamay.quarantineSnapshotDir |
string | (empty) | Snapshot a quarantined session's contexts before dropping them. |
llamay.checkpointDir |
string | (empty: 409) | Enables llamay:checkpoint and llamay:restore. |
llamay.auditAnchors |
[]object | (empty) | name, file (required), intervalSeconds (60), continuation, failClosed. |
kosa8.socket |
string | ~/.kosa8/run/kosa8.sock when url is empty |
kosa8d unix socket. |
kosa8.url |
string | (empty) | kosa8d over TCP; needs tokenFile. |
kosa8.tokenFile |
string | (empty) | kosa8d bearer token. |
kosa8.mirrorDecisions |
bool | false |
Post MCP decisions to kosa8's audit chain. |
kosa8.anchorIntervalSeconds |
int | 0 (off) |
Anchor kosa8's audit head in the ledger. |
kosa8.queueSize |
int | 1024 |
Mirror queue; overflow dropped and counted. |
clientAudit.anchors |
[]object | (empty) | Signed audit files of a desktop agent, anchored in the ledger: name, file (required), pubkey (pinned Ed25519 key, hex), requireSigned, allowRestarts, intervalSeconds (60). |
See Kosa8 sandboxes and llamay models.
Cloud credentials#
cloudCredentials overrides the cloud environment used by KMS key backends, the keyless WORM sink, keyless SIEM sinks and cloud model providers.
| Key | Type | Default | Description |
|---|---|---|---|
cloudCredentials.aws.region |
string | $AWS_REGION, then $AWS_DEFAULT_REGION |
Region. |
cloudCredentials.aws.imds |
bool | false |
EC2 IMDSv2 fallback (on EKS it is the shared node role). |
cloudCredentials.aws.partitionDNSSuffix |
string | from region | For example amazonaws.eu. |
cloudCredentials.aws.stsEndpoint |
string | $AWS_ENDPOINT_URL_STS, else regional |
https URL. |
cloudCredentials.azure.managedIdentity |
bool | false |
IMDS managed-identity fallback. |
cloudCredentials.azure.identityBinding |
bool | false |
Route Workload ID token requests through the AKS identity-binding proxy. |
cloudCredentials.gcp.metadataHost |
string | $GCE_METADATA_HOST, else 169.254.169.254 |
Metadata server host[:port]. |
Complete annotated example#
JSON has no comments, so the notes follow the file. This example is a production-style single-region gateway with OIDC admin access, signed checkpoints, a SIEM sink, DLP and a PostgreSQL state backend.
{
"listen": ":8080",
"adminListen": "10.0.0.5:9090",
"logLevel": "info",
"policyFile": "/etc/maqpna/policies/policies.json",
"policyReloadSeconds": 2,
"upstreamsFile": "/etc/maqpna/upstreams/upstreams.json",
"upstreamCredentialsDir": "/var/run/maqpna-upstream-credentials",
"tokenExchangeURL": "http://maqpna-identity.maqpna-system.svc:8081/v1/exchange",
"modelsFile": "/etc/maqpna/models/models.json",
"revocationsFile": "/etc/maqpna/revocations/revocations.json",
"budgetsFile": "/etc/maqpna/budgets/budgets.json",
"budgetTimezone": "Europe/Berlin",
"identity": {
"jwksURL": "http://maqpna-identity.maqpna-system.svc:8081/.well-known/jwks.json",
"audience": "maqpna-gateway",
"leewaySeconds": 30
},
"auditPath": "/var/lib/maqpna/audit/ledger.jsonl",
"auditFailurePolicy": "closed",
"auditCheckpointKey": "file:///var/run/maqpna-audit-key/audit-signing.pem",
"auditCheckpointIntervalSeconds": 60,
"auditSinks": [
{
"name": "siem",
"type": "syslog",
"address": "tls://siem.example.eu:6514",
"caFile": "/etc/maqpna/sinks/siem/tls/ca.crt"
}
],
"approvalTimeoutSeconds": 300,
"approvalStorePath": "/var/lib/maqpna/audit/approvals.jsonl",
"approvalPreview": { "mode": "redacted" },
"approvalQuorum": {
"rules": { "payments/*": { "minApprovers": 2, "approverGroups": ["treasury"] } }
},
"adminAuth": {
"mode": "both",
"oidc": {
"issuer": "https://sso.example.eu/realms/maqpna",
"audience": "maqpna-admin",
"groupsClaim": "groups"
},
"roles": { "admin": ["platform"], "auditor": ["security"], "killswitch": ["security"] },
"namespaceRoles": { "team-a": { "approver": ["team-a-leads"] } }
},
"dlpProfiles": {
"strict": { "requestAction": "redact", "responseAction": "redact", "onSecret": "deny" }
},
"dlp": { "defaultProfile": "strict" },
"pinStorePath": "/var/lib/maqpna/audit/toolpins.jsonl",
"taintStorePath": "/var/lib/maqpna/audit/taint.jsonl",
"stateBackend": { "type": "postgres", "dsnFile": "/var/run/maqpna-state/dsn" },
"shutdownDelaySeconds": 5
}
What each part does:
listen/adminListen: agents reach:8080; the admin API and/metricsare only on the private10.0.0.5:9090.policyFiletobudgetsFile: the files the operator renders from your resources. The gateway polls them every 2 seconds.identity: session tokens are verified against the identity broker's JWKS.auditFailurePolicy: closed: no allowed call is forwarded unless its intent record is durable.auditCheckpointKey: checkpoints are signed every 60 seconds or 1000 records.auditSinks: every record is streamed over TLS syslog.approvalQuorum: rules of policypaymentsneed two approvers from grouptreasury.adminAuth: OIDC for people, the static token kept as break-glass.dlp: every call uses profilestrict, which redacts personal data and denies secrets.stateBackend: approvals, revocations, taint and counters are shared between replicas.
Helm values that set gateway.json#
The chart renders gateway.json into ConfigMap <release>-gateway-config. It starts from gateway.config (copied as is, so any key on this page can go there) and then fills keys from other values. A key you set in gateway.config usually wins; the exceptions are noted.
| Helm value | gateway.json key | Notes |
|---|---|---|
gateway.config.* |
any key | Copied verbatim, decoded strictly by the gateway. |
gateway.port (8080) |
listen |
Set to :<port> when gateway.config.listen is empty. A different port in listen fails the render. |
| (chart default) | policyFile |
/etc/maqpna/policies/policies.json |
| (chart default) | auditPath |
/var/lib/maqpna/audit/ledger.jsonl |
| identity broker URL | identity.jwksURL |
<identity URL>/.well-known/jwks.json |
gateway.brokerPublicKeySecret |
identity.publicKeyFiles |
/var/run/maqpna-identity/pub.pem |
identity.audience |
identity.audience |
|
examples.mcpEcho.enabled |
upstreams.echo |
Adds the example MCP server. |
| (chart default) | upstreamsFile, upstreamCredentialsDir, modelsFile, revocationsFile, budgetsFile, memoryFile, memoryDataDir, tenantsFile, tenantLedgerDir |
Paths under /etc/maqpna/... and /var/lib/maqpna/audit/.... |
identity.enabled |
tokenExchangeURL |
<identity URL>/v1/exchange |
| (chart default) | shutdownDelaySeconds |
5 |
gateway.budgetTimezone |
budgetTimezone |
|
gateway.revocationMirror.enabled + gateway.activity.enabled |
revocationMirror |
Namespace is the release namespace. |
gateway.activity.enabled |
activity.enabled |
Overrides gateway.config.activity. |
| usage reporting enabled | sandboxUsage |
Reporter is the operator's ServiceAccount. |
gateway.approvalStorePath |
approvalStorePath |
|
gateway.auditFailurePolicy |
auditFailurePolicy |
Overrides gateway.config. Must be open or closed. |
gateway.pinStorePath, gateway.taintStorePath |
pinStorePath, taintStorePath |
|
gateway.replicas |
posture.replicas |
|
adminAuth.*, approvals.* |
adminAuth, approvalPreview, approvalQuorum, notifiers, notifyOutboxPath, consoleURL |
_governance.tpl |
gateway.web, gateway.exec, gateway.egress, gateway.liveView, gateway.evidence, gateway.k8sOps |
web, exec, egress, liveView, evidence, k8sOps |
_sandboxtools.tpl; Secrets become mounted files. |
gateway.policyAdapters.rego, gateway.captureArgs, gateway.modelRouting, gateway.guards |
policy, captureArgs, modelRouting, guards |
_extensions.tpl |
llamay.* |
llamay |
_llamay.tpl |
gateway.a2a, gateway.txnTokens, gateway.tls |
a2a, txnTokens, tls |
_workload.tpl |
delegation.* |
tokenVault, ciba |
_delegation.tpl |
state.* |
stateBackend |
_state.tpl; the DSN Secret is mounted as dsnFile. |
sovereignty.* |
sovereigntyPolicyFile |
/etc/maqpna/sovereignty.json, rendered in the same ConfigMap. |
gateway.tracing.* |
otel |
enabled needs endpoint; with sovereignty the endpoint must be in sovereignty.telemetryEndpoints. |
dlp.profiles, dlp.defaultProfile, dlp.namespaces, dlp.servers, dlp.models |
dlpProfiles, dlp |
|
audit.sinks[] |
auditSinks |
Secret refs (tlsSecret, headersSecret, tokenSecret, awsCredentialsSecret) become files under /etc/maqpna/sinks/<name>/. |
audit.checkpointSigning.* |
auditCheckpointKey, auditCheckpointIntervalSeconds, auditCheckpointEvery |
Default key file:///var/run/maqpna-audit-key/audit-signing.pem. |
gateway.configSync.enabled, pollMillis |
configSync |
Also rewrites policyFile, modelsFile, upstreamsFile, revocationsFile, budgetsFile, memoryFile, tenantsFile (and a2a.routesFile) to /var/run/maqpna/live/.... |
license.secretRef |
licenseFile |
|
gateway.cloudCredentials |
cloudCredentials |
Only set values; skipped when gateway.config.cloudCredentials exists. |
To see the rendered file for your values, render the chart and read the ConfigMap:
helm template maqpna oci://$REGISTRY/charts/maqpna --version 2.1.0 -f values.yaml \
--show-only templates/gateway.yaml
REGISTRY is the release registry listed on maqpna.com/download. See Helm values.
What can go wrong#
| Symptom | Cause | Fix |
|---|---|---|
json: unknown field "..." |
A misspelt or unsupported key. | Check the spelling on this page. maqpna config validate lists unknown keys as warnings. |
policyFile is required / auditPath is required |
Core key missing. | Add it. The chart sets both by default. |
identity.publicKeyFiles or identity.jwksURL is required |
No way to verify session tokens. | Point identity.jwksURL at the identity broker. |
at least one upstream (or upstreamsFile / model route / modelsFile) is required |
No route. | Set upstreamsFile (operator-rendered) or modelsFile. |
adminListen must differ from listen |
Same address twice. | Use another port or interface. |
| Every call denied after a restart | revocationsFile is set but missing or invalid (fail closed). |
Restore the file; the chart creates it with {"revocations":[]}. |
admin API disabled: MAQPNA_ADMIN_TOKEN not set (log) |
Mode token without a token. |
Set MAQPNA_ADMIN_TOKEN or use adminAuth.mode oidc. |