Skip to main content

AI Gateway Helm values

Configure the AI Gateway chart with these Helm values.

This reference lists values declared in the chart's default values.yaml. Templates can also accept optional settings and inherited global values.

Chart: ai-gateway-v2. Chart version: 0.24.0. Generated from the platform source at v0.24.0.

Values​

replicaCount​

Type: int

Default: 2

Number of replicas for the deployment. Ignored when replicas.managedExternally is true.

replicas.managedExternally​

Type: bool

Default: false

When true, the chart never writes replicas: on the Deployment, so an external scaler (HPA/KEDA) is not overridden on every helm upgrade.

image.repository​

Type: string

Default: "image-proxy.stacklok.com/proxy/stacklok-enterprise/ghcr.io/stacklok/stacklok-enterprise/sprout"

Container image repository.

image.tag​

Type: string

Default: ""

Image tag (defaults to appVersion if empty)

image.pullPolicy​

Type: string

Default: "IfNotPresent"

Image pull policy

imagePullSecrets​

Type: list

Default: []

Extra image pull Secrets for the sprout pod. On Replicated installs the SDK pull secret is added automatically; list only additional registries here.

nameOverride​

Type: string

Default: ""

Override the name of the chart

fullnameOverride​

Type: string

Default: ""

Override the full name of the resources

serviceAccount.create​

Type: bool

Default: true

Specifies whether a service account should be created. Its identity backs the projected tokens Sprout presents to directory and budgets.

serviceAccount.automount​

Type: bool

Default: false

Automatically mount API-server credentials. Keep false: every token Sprout needs is a separately projected volume.

serviceAccount.annotations​

Type: object

Default: {}

Annotations to add to the service account

serviceAccount.name​

Type: string

Default: ""

The name of the service account to use (if not set and create is true, a name is generated using the fullname template)

podAnnotations​

Type: object

Default: {}

Annotations to add to the pod

podLabels​

Type: object

Default: {}

Labels to add to the pod

podSecurityContext​

Type: object

Default value
fsGroup: 65532
runAsGroup: 65532
runAsNonRoot: true
runAsUser: 65532
seccompProfile:
type: RuntimeDefault

Security context for the pod (ko/Chainguard nonroot UID = 65532)

securityContext​

Type: object

Default value
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532

Security context for the container

service.type​

Type: string

Default: "ClusterIP"

Kubernetes service type

service.port​

Type: int

Default: 8080

Service port

service.targetPort​

Type: int

Default: 8080

Container target port. The Service never exposes the /metrics listener.

telemetry​

Type: object

Default value
claimLabels: []
groupLabelAttributes: []
headerLabels: []
metrics:
port: 9464
otlp:
enabled: false
endpoint: ''
headersSecretRef:
key: headers
name: ''
insecure: false
tracesEndpoint: ''
prometheus:
enabled: false
spanAttributes: []
tracing:
enabled: false
exportTimeoutSeconds: 0
samplingRate: 0

Metrics and tracing export, all off by default. Sprout's strict decoder rejects unknown fields, so never add a key here the binary does not declare. otlp.endpoint falls back to global.stacklok.telemetry.otlp; enabled and insecure are true if either the local or the global value is true.

telemetry.otlp.enabled​

Type: bool

Default: false

Push metrics to an OTLP collector.

telemetry.otlp.endpoint​

Type: string

Default: ""

Collector endpoint (e.g. "otel-collector.observability:4318"). Required, locally or via global, when otlp or tracing is enabled.

telemetry.otlp.insecure​

Type: bool

Default: false

Disable TLS on the OTLP connection. Only for a collector reachable over a private, trusted network.

telemetry.otlp.tracesEndpoint​

Type: string

Default: ""

Exact URL spans are POSTed to over OTLP/HTTP (no "/v1/traces" appended), e.g. "https://telemetry.cloudzero.com/v2/telemetry/<sink>". Traces only; its scheme decides TLS. Needs tracing.enabled; not composed with global.

telemetry.otlp.headersSecretRef​

Type: object

Default: {"key":"headers","name":""}

Secret holding OTLP export headers for tracesEndpoint as key=value,key2=value2. Needs an https tracesEndpoint and is refused while OTLP metrics push is on, which would send this credential to the metrics collector. key defaults to "headers".

telemetry.prometheus.enabled​

Type: bool

Default: false

Expose a pull-scrapeable /metrics route on its own listener (metrics.port).

telemetry.tracing​

Type: object

Default: {"enabled":false,"exportTimeoutSeconds":0,"samplingRate":0}

Push traces to the OTLP collector. Off by default.

telemetry.tracing.enabled​

Type: bool

Default: false

Export spans via OTLP. Requires otlp.endpoint or otlp.tracesEndpoint.

telemetry.tracing.samplingRate​

Type: int

Default: 0

Sampling ratio (0.0-1.0) for requests with no or unsampled inbound trace context; a sampled inbound traceparent is always honored. 0 samples every request.

telemetry.tracing.exportTimeoutSeconds​

Type: int

Default: 0

Bound, in seconds, on one OTLP export; 0 keeps the 30s default. Set it above the destination's worst-case response time, or a slow destination can receive the same batch twice and double-count spans.

telemetry.metrics​

Type: object

Default: {"port":9464}

Dedicated /metrics listener, bound whenever prometheus.enabled is true.

telemetry.headerLabels​

Type: list

Default: []

Header-to-attribute mappings on the token-usage metric. Values outside permitted fold to "other". Governance and credential headers are refused; use claimLabels for caller identity.

Example:
headerLabels:
- header: x-stacklok-team
attribute: team
permitted: [platform, research]

telemetry.claimLabels​

Type: list

Default: []

Verified token claims carried as labels on the token-usage metric, read from the signed token (or, for a virtual key, its owner's directory record). Without permitted the value passes through, so a per-user label is one series per user and puts personal data in your metrics store. At most 10 entries; a claim that changes per token or session (jti, nonce, sid) needs permitted.

Example:
claimLabels:
- claim: sub
attribute: user_id
- claim: department
attribute: department

telemetry.groupLabelAttributes​

Type: list

Default: []

Stamp a directory-resolved group label onto the interaction span under a custom attribute name instead of its bare name. Each label must be in directory.groupLabels, or the gateway refuses to start.

Example:
groupLabelAttributes:
- label: department
attribute: cz.context.department

telemetry.spanAttributes​

Type: list

Default: []

Copy a caller-sent request header onto the interaction span under a chosen attribute name. The value is client-supplied, so treat it as an attribution hint, never an identity. Credential and personal-data headers are refused; at most 20 entries. Needs telemetry.tracing.enabled.

Example:
spanAttributes:
- header: x-cz-context-project
attribute: cz.context.project

resources​

Type: object

Default: {"limits":{"memory":"256Mi"},"requests":{"cpu":"50m","memory":"128Mi"}}

Resource limits and requests for the container. No CPU limit: requests are mostly blocked on upstream I/O, so a CPU ceiling only throttles stream bursts.

readinessProbe​

Type: object

Default value
failureThreshold: 2
httpGet:
path: /readyz
port: http
initialDelaySeconds: 0
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 3

Readiness probe. /readyz fails once a graceful drain has started.

livenessProbe​

Type: object

Default value
failureThreshold: 32
httpGet:
path: /healthz
port: http
initialDelaySeconds: 0
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 5

Liveness probe. Must satisfy (failureThreshold - 1) * periodSeconds > drain-deadline + 5s for lifecycle.maxStreamDuration; the render fails otherwise.

runtime​

Type: object

Default: {"drainDeadline":"","drainWindow":"","jwksWarmupTimeout":""}

Process flags passed on argv. Empty renders no flag and keeps the binary default.

runtime.drainWindow​

Type: string

Default: ""

-drain-window: how long a draining pod keeps accepting connections after SIGTERM. Go duration string. Binary default 5s.

runtime.drainDeadline​

Type: string

Default: ""

-drain-deadline: overrides the deadline derived from lifecycle.maxStreamDuration. Setting it decouples it from the rendered terminationGracePeriodSeconds. Go duration string.

runtime.jwksWarmupTimeout​

Type: string

Default: ""

-jwks-warmup-timeout: per-issuer budget for the first JWKS fetch; a miss exits the process. Go duration string. Binary default 10s.

lifecycle.maxStreamDuration​

Type: string

Default: "15m"

Upstream stream ceiling. The termination grace period, liveness guard and httpRoute timeouts all derive from it. Go duration string.

providers​

Type: list

Default: []

Upstream providers. credentialSecretRef names the Secret and key holding the provider's credential, mounted as a file; inline plaintext credentials are refused. A provider without one uses the ambient credential chain.

Example:
providers:
- kind: openai
baseUrl: https://api.openai.com
models: ['gpt-5.5']
credentialSecretRef:
name: ai-gateway-v2-openai-credentials
key: api-key
- kind: bedrock-anthropic
baseUrl: https://bedrock-runtime.us-east-1.amazonaws.com
region: us-east-1
models: ['us.anthropic.claude-opus-4-8']

auth​

Type: object

Default: {"issuers":[]}

Trusted OIDC issuers: issuer, audience, bindingClaim, tokenUse, requiredScope, jwksUri and optional caBundleRef. requiredScope is written as the token's scope claim holds it (for Entra, "LLM.Invoke"); a token without it gets 403. An issuer matching global.stacklok.primaryIdp.issuer inherits its caBundleRef.

caBundleRef:
secretRef: { name: corp-idp-ca } # or configMapRef: {name: ...}
key: ca.crt # optional, default ca.crt

directory.endpoint​

Type: string

Default: ""

Directory gRPC endpoint (host:port), e.g. "enterprise-server.toolhive-system:9091". Empty with insecure: true inherits global.stacklok.directoryGrpcEndpoint; empty otherwise disables virtual-key resolution and group labels. Once one resolves, any JWT caller the directory does not resolve gets 403.

directory.insecure​

Type: bool

Default: false

Dial the directory over plaintext instead of TLS. Transport only: the caller credential comes from tokenProjection. Set true for Enterprise Manager's cleartext gRPC listener, and to inherit global.stacklok.directoryGrpcEndpoint when endpoint is empty. With Enterprise Manager caller authentication on, also set tokenProjection.enabled: true.

directory.caBundle.secretName​

Type: string

Default: ""

Secret holding the PEM bundle that verifies the directory's TLS certificate, added to the system roots. Required for a TLS dial to an in-cluster endpoint, whose certificate no public root vouches for. Mounted without a subPath and read at every reconnect, so a rotated certificate is picked up without restarting the gateway. Chart-local like directory.endpoint, with no global.stacklok default: the CA vouches for the address this gateway dials, which may differ from other charts'.

directory.caBundle.key​

Type: string

Default: "ca.crt"

Key of the bundle in that Secret.

directory.caBundle.mountPath​

Type: string

Default: "/etc/directory-tls"

Directory the bundle is mounted into.

directory.groupsResolutionIssuer​

Type: string

Default: ""

The iss the virtual-key path presents to the directory to resolve the key owner's groups. Do not add this issuer to auth.issuers only for this lookup: the gateway would also trust its tokens.

directory.groupLabels​

Type: list

Default: []

Directory group label names this gateway resolves onto the principal, its X-<Label> governance header and the audit trail. Lower-case underscore identifiers; a name colliding with a reserved header fails startup.

directory.tokenProjection.enabled​

Type: bool

Default: false

Project a ServiceAccount token for the directory. Required when directory.endpoint is set and directory.insecure is false.

directory.tokenProjection.mountPath​

Type: string

Default: "/var/run/secrets/directory"

Directory the projected token is mounted into.

directory.tokenProjection.audience​

Type: string

Default: "directory-service"

Audience the directory's caller-auth gate expects.

directory.tokenProjection.expirationSeconds​

Type: int

Default: 3600

Requested lifetime of the projected token. Minimum 600 — the API server REJECTS a Pod spec below that floor rather than clamping to it.

directory.workloadTrust.pollInterval​

Type: string

Default: ""

Snapshot poll interval as a Go duration, e.g. "15s", at least "10s". Empty keeps the binary's 30s default.

budgets.endpoint​

Type: string

Default: ""

Budget webhook receiver base URL, e.g. "https://enterprise-server.toolhive-system:443". Empty leaves the gateway UNGOVERNED (no admission, no charge) — see acknowledgeUnmetered below.

budgets.caBundle.secretName​

Type: string

Default: ""

Secret holding the PEM bundle that verifies the budgets receiver. Required when endpoint is set; falls back to global.webhooks.caBundleSecret.

budgets.caBundle.key​

Type: string

Default: "ca.crt"

Key within that Secret holding the PEM bundle.

budgets.mountPath​

Type: string

Default: "/etc/budgets-tls"

Directory the CA bundle is mounted into.

budgets.tokenProjection.enabled​

Type: bool

Default: false

Project a ServiceAccount token presented to the budgets receiver. Required when endpoint is set.

budgets.tokenProjection.mountPath​

Type: string

Default: "/var/run/secrets/budgets"

Directory where the projected budgets ServiceAccount token is mounted.

budgets.tokenProjection.audience​

Type: string

Default: "budgets-webhook"

Audience requested for the projected budgets ServiceAccount token. Match the audience accepted by Enterprise Manager's budgets receiver.

budgets.tokenProjection.expirationSeconds​

Type: int

Default: 3600

Requested lifetime, in seconds, of the projected budgets ServiceAccount token. Kubernetes rotates the token before expiry.

budgets.capture​

Type: bool

Default: false

Forward the client request body to the receiver (conversation capture). With scanning off this sends the raw, unredacted body.

budgets.sessionHeaders​

Type: list

Default: []

Ordered session-correlation headers. Empty inherits global.stacklok.sessionHeaders, then the shipped defaults.

budgets.acknowledgeUnmetered​

Type: bool

Default: false

REQUIRED (true) to render without budgets.endpoint, so an unmetered gateway is never an accident.

modelAccess.enabled​

Type: bool

Default: false

Enforce directory model access: inference for a model the caller is not granted gets 403, and model discovery lists only granted models. Needs directory.endpoint; reuses budgets.tokenProjection and the budgets CA.

modelAccess.endpoint​

Type: string

Default: ""

Receiver base URL, e.g. "https://enterprise-server.toolhive-system:443". Defaults to budgets.endpoint, which is the same listener.

failureLogs.level​

Type: string

Default: "warn"

Severity of structured operational failure records (warn, error, or debug).

failureLogs.includeMessage​

Type: bool

Default: true

Include a bounded parsed failure message by default. Set false to log metadata only when stderr retention or access cannot accommodate PII.

audit.enabled​

Type: bool

Default: false

Enable audit logging. On if this OR global.stacklok.audit.enabled is true; it cannot force audit off while the global is on.

capture​

Type: object

Default: {}

Inline capture config, rendered verbatim into the ConfigMap. Empty by default: capture records full request and response bodies.

networkPolicy.enabled​

Type: bool

Default: false

Enable a NetworkPolicy for the sprout pod.

networkPolicy.ingress.gatewayNamespaces​

Type: list

Default: ["envoy-gateway-system"]

Namespaces whose pods may reach the gateway port. An empty list with allowAllSources false fails the render rather than admitting every pod.

networkPolicy.ingress.gatewayPodSelector​

Type: object

Default: {"app.kubernetes.io/name":"envoy"}

Pod selector within those namespaces. Set to {} to admit the whole namespace.

networkPolicy.ingress.monitoringNamespaces​

Type: list

Default: ["monitoring"]

Namespaces whose pods may scrape /metrics when telemetry.prometheus.enabled is true. The listener is unauthenticated, so this list bounds who reads it.

networkPolicy.ingress.allowAllSources​

Type: bool

Default: false

Admit every source instead of the lists above. This also exposes the unauthenticated /metrics listener to every pod in the cluster.

networkPolicy.governanceEgress​

Type: object

Default: {"enabled":true,"namespaces":[],"podSelector":{"app.kubernetes.io/name":"enterprise-manager"}}

When allowExternalEgress is false, emit egress rules to the directory, budgets and enterprise-manager services this install dials. Without them a locked-down install 503s every request.

networkPolicy.governanceEgress.namespaces​

Type: list

Default: []

Namespaces the governance services run in; empty means the release namespace. Must match if directory or budgets endpoints point elsewhere, or the rule admits nothing.

networkPolicy.governanceEgress.podSelector​

Type: object

Default: {"app.kubernetes.io/name":"enterprise-manager"}

Pods within those namespaces. Set to {} to admit the whole namespace.

networkPolicy.allowExternalEgress​

Type: bool

Default: true

Allow ALL egress traffic, overriding any cluster-wide default-deny. Set false and populate egress to lock this pod down.

networkPolicy.egress​

Type: list

Default: []

Additional egress rules (NetworkPolicyEgressRule shape) applied when allowExternalEgress is false. Must cover DNS and every provider, directory, budgets and OTLP destination. With directory.endpoint set, an in-cluster workload trust needs the API server's endpoint addresses and port, often 6443; the kubernetes.default Service address on 443 is not enough. A trust with a public JWKS URL needs its host on 443.

extraEnv​

Type: list

Default: []

Additional environment variables for the sprout container.

extraVolumes​

Type: list

Default: []

Additional volumes to attach to the pod.

extraVolumeMounts​

Type: list

Default: []

Additional volume mounts to attach to the sprout container.

nodeSelector​

Type: object

Default: {}

Node labels for pod assignment

tolerations​

Type: list

Default: []

Tolerations for pod assignment

affinity​

Type: object

Default: {}

Affinity rules for pod assignment

topologySpreadConstraints​

Type: list

Default: [{"maxSkew":1,"topologyKey":"kubernetes.io/hostname","whenUnsatisfiable":"ScheduleAnyway"}]

Spread replicas across nodes. Set to [] to disable spreading.

httpRoute.enabled​

Type: bool

Default: false

Render a Gateway API HTTPRoute attaching this Service to the shared Envoy Gateway. Requires parentRefs.

httpRoute.parentRefs​

Type: list

Default: []

Gateway API parentRefs (name, namespace, optional sectionName) of the shared Gateway. Required when httpRoute.enabled is true.

httpRoute.hostname​

Type: string

Default: ""

Hostname this route serves. Empty inherits the host of global.stacklok.aiGatewayV2.url, and with neither set the route matches every hostname the parent Gateway listener accepts.

config.mountPath​

Type: string

Default: "/etc/ai-gateway-v2/config"

Directory the config ConfigMap is mounted into.

config.fileName​

Type: string

Default: "config.json"

File name of the rendered config JSON within mountPath.

config.credentialsRoot​

Type: string

Default: "/var/run/secrets/ai-gateway-v2"

Directory every provider credential file must resolve inside. Passed as a flag, so the ConfigMap cannot widen it.

scanning​

Type: object

Default value
adapter:
image:
digest: ''
pullPolicy: IfNotPresent
repository: image-proxy.stacklok.com/proxy/stacklok-enterprise/ghcr.io/stacklok/stacklok-enterprise/ai-gateway-main-processor
tag: ''
logLevel: ''
maxReplicas: null
metrics:
enabled: null
port: 9090
nodeSelector: {}
podAnnotations: {}
replicas: 2
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 50m
memory: 64Mi
targetCPUUtilization: null
tolerations: []
topologySpreadConstraints: []
allowlist: []
allowlistMatch: exact
audience: ''
diagnostics:
includePIIInDebugLogs: false
enabled: false
entities: []
entityActions: []
extractionFailureAction: block
hook:
caMountPath: /etc/scanning-tls
failurePolicy: Fail
timeout: ''
tokenExpirationSeconds: 3600
tokenMountPath: /var/run/secrets/scanning
mutationFailureAction: block
ner:
circuitBreaker:
failureThreshold: 5
resetTimeout: 30s
failureAction: fail-closed
timeout: 5s
placeholder: ''
presidio:
autoscaling:
mode: HPA
image:
digest: ''
pullPolicy: IfNotPresent
repository: image-proxy.stacklok.com/proxy/stacklok-enterprise/ghcr.io/stacklok/stacklok-enterprise/presidio-analyzer
tag: ''
language: en
maxReplicas: null
nodeSelector: {}
podAnnotations: {}
recognizers: []
replicas: 2
resources:
limits:
cpu: '2'
memory: 3Gi
requests:
cpu: 500m
memory: 2Gi
scoreThreshold: 50
targetCPUUtilization: null
tolerations: []
topologySpreadConstraints: []
requestAction: block
resultCache:
enabled: false
macSecret:
key: mac-secret
name: ''
redis:
clusterMode: null
existingSecret: ''
existingSecretKey: ''
host: ''
port: null
tls: null
username: ''
ttl: ''
skipPaths: []
tls:
caBundleKey: ca.crt
caBundleSecret: ''
issuerRef:
kind: ''
name: ''

PII scanning with Presidio and the scanning-adapter. scanning.enabled=true plus an issuer and a CA bundle is enough for a working scan.

scanning.enabled​

Type: bool

Default: false

Render the Presidio stack and the scanning-adapter, including a cluster-scoped ClusterRoleBinding, and wire the gateway's scan hook to it.

scanning.audience​

Type: string

Default: ""

Audience of the token the gateway presents to the adapter. Empty derives https://<adapter-service>.<release-namespace>.svc.

scanning.requestAction​

Type: string

Default: "block"

Global action when Presidio finds an entity: block (403), redact (replace the match with a placeholder) or log-only.

scanning.placeholder​

Type: string

Default: ""

Text substituted for a redacted match whose entity sets no placeholder of its own, at most 64 characters. Empty uses [REDACTED-<ENTITY>], e.g. [REDACTED-EMAIL_ADDRESS].

scanning.entityActions​

Type: list

Default: []

Per-entity overrides of requestAction: entity, action (block|redact|log-only), optional placeholder, and optional mode (enforce, default, or shadow, which only records the detection).

scanning.extractionFailureAction​

Type: string

Default: "block"

When the request body's text cannot all be extracted for scanning (invalid JSON, an unrecognized input item, or text nested over 32 levels): block (403) or continue, which forwards the unreachable text unscanned with any PII in it, still scans the rest, and counts it as unscanned.

scanning.mutationFailureAction​

Type: string

Default: "block"

When a match cannot be redacted safely: block (403) or continue, which forwards the match unredacted to the provider.

scanning.skipPaths​

Type: list

Default: []

Extra request fields the adapter never scans, appended to its built-in list of protocol values and never replacing it. Each entry is <type>.<field>[.<key>|[*]]..., e.g. computer_call.action.button or tool_use.input.trace_id. An unknown type or field, or a path below a string field, stops the adapter; a misspelled deeper key skips nothing. A skipped field reaches the provider unscanned, and under tool_use.input the client picks the keys.

scanning.diagnostics.includePIIInDebugLogs​

Type: bool

Default: false

SECURITY: with adapter.logLevel: debug, writes raw matched PII into adapter logs. Incident response only; never leave it on in production.

scanning.entities​

Type: list

Default: []

Presidio entities to detect. Empty uses files/presidio/default_entities.json. Custom recognizers' entities are always added; editing this list rolls the adapter.

scanning.allowlist​

Type: list

Default: []

Strings Presidio never reports as a detection.

scanning.allowlistMatch​

Type: string

Default: "exact"

How allowlist entries match: exact or regex.

scanning.ner.timeout​

Type: string

Default: "5s"

Budget for one Presidio call, as a single-unit Go duration. Must be positive.

scanning.ner.failureAction​

Type: string

Default: "fail-closed"

What the adapter does when Presidio is unreachable or slow: fail-closed blocks the request, fail-open admits it.

scanning.ner.circuitBreaker.failureThreshold​

Type: int

Default: 5

Consecutive Presidio failures that trip the breaker.

scanning.ner.circuitBreaker.resetTimeout​

Type: string

Default: "30s"

How long the breaker stays open before probing again.

scanning.hook.timeout​

Type: string

Default: ""

Budget the gateway gives the adapter, as a single-unit Go duration. Empty derives ner.timeout + 2s; an explicit value must exceed ner.timeout. Raise it if large requests need several Presidio waves under load.

scanning.hook.failurePolicy​

Type: string

Default: "Fail"

When the adapter call fails: Fail refuses the request, Ignore forwards it unscanned. Under Ignore, an outage or an oversized request lets PII through.

scanning.hook.tokenExpirationSeconds​

Type: int

Default: 3600

Requested lifetime of the projected token, minimum 600.

scanning.hook.tokenMountPath​

Type: string

Default: "/var/run/secrets/scanning"

Directory the projected token is mounted into on the gateway pod.

scanning.hook.caMountPath​

Type: string

Default: "/etc/scanning-tls"

Directory the adapter CA bundle is mounted into on the gateway pod.

scanning.tls.issuerRef​

Type: object

Default: {"kind":"","name":""}

cert-manager issuer for the adapter's serving certificate. Empty name falls back to global.webhooks.issuerRef; one of the two must name an issuer.

scanning.tls.caBundleSecret​

Type: string

Default: ""

Secret holding the PEM CA that verifies the adapter's serving certificate, in the release namespace. Empty falls back to global.webhooks.caBundleSecret; one of the two is required.

scanning.tls.caBundleKey​

Type: string

Default: "ca.crt"

Key within that Secret holding the PEM bundle.

scanning.adapter.image.repository​

Type: string

Default value
image-proxy.stacklok.com/proxy/stacklok-enterprise/ghcr.io/stacklok/stacklok-enterprise/ai-gateway-main-processor

Scanning-adapter image (the ai-gateway main-processor).

scanning.adapter.image.tag​

Type: string

Default: ""

Image tag (defaults to appVersion if empty).

scanning.adapter.image.digest​

Type: string

Default: ""

Optional image digest, appended as @<digest> after the tag.

scanning.adapter.image.pullPolicy​

Type: string

Default: "IfNotPresent"

Image pull policy.

scanning.adapter.replicas​

Type: int

Default: 2

Replica count, and the HPA's minReplicas. The scan hook is fail-closed, so a single adapter is a single point of failure for every request.

scanning.adapter.maxReplicas​

Type: string

Default: nil

Upper bound for the HPA. Unset means no HPA, and replicas is written on the Deployment.

scanning.adapter.targetCPUUtilization​

Type: string

Default: nil

HPA target average CPU utilization, 1-100. Defaults to 75 when unset.

scanning.adapter.podAnnotations​

Type: object

Default: {}

Annotations added to the adapter pods. The chart's own checksum and scrape annotations win over a same-named entry.

scanning.adapter.nodeSelector​

Type: object

Default: {}

Node labels for adapter pod assignment.

scanning.adapter.tolerations​

Type: list

Default: []

Tolerations for adapter pod assignment.

scanning.adapter.topologySpreadConstraints​

Type: list

Default: []

Topology spread constraints for the adapter pods. Entries without a labelSelector get the adapter's selector labels.

scanning.adapter.resources​

Type: object

Default: {"limits":{"cpu":"500m","memory":"256Mi"},"requests":{"cpu":"50m","memory":"64Mi"}}

Adapter container resources.

scanning.adapter.logLevel​

Type: string

Default: ""

Adapter log level (debug|info|warn|error). Empty keeps the binary default.

scanning.adapter.metrics.enabled​

Type: string

Default: nil

Serve the adapter's scan metrics. Unset follows the gateway's telemetry settings; false turns them off; true always serves port.

scanning.resultCache.enabled​

Type: bool

Default: false

Cache Presidio results in Redis/Valkey. Requires a Redis host here or in global.redis. Writes pause while Presidio is mid-rollout.

scanning.resultCache.ttl​

Type: string

Default: ""

Entry lifetime as a Go duration. Empty keeps the runtime default (24h).

scanning.resultCache.redis.host​

Type: string

Default: ""

Redis host. Empty falls back to global.redis.host.

scanning.resultCache.redis.port​

Type: string

Default: nil

Redis port. Empty falls back to global.redis.port.

scanning.resultCache.redis.clusterMode​

Type: string

Default: nil

Speak the Redis Cluster protocol. Unset falls back to global.redis.clusterMode.

scanning.resultCache.redis.username​

Type: string

Default: ""

ACL username. Empty falls back to global.redis.username.

scanning.resultCache.redis.existingSecret​

Type: string

Default: ""

Secret holding the Redis password, in the release namespace. Empty falls back to global.redis.existingSecret.

scanning.resultCache.redis.existingSecretKey​

Type: string

Default: ""

Key within that Secret. Empty falls back to global.redis.existingSecretKey.

scanning.resultCache.redis.tls​

Type: string

Default: nil

Dial Redis over TLS. Unset falls back to global.redis.tls.enabled.

scanning.resultCache.macSecret.name​

Type: string

Default: ""

Your own Secret holding the cache's HMAC key (at least 32 printable bytes). Empty makes the adapter create <fullname>-ner-cache-mac if absent. Never point this at a Secret another controller also writes.

scanning.resultCache.macSecret.key​

Type: string

Default: "mac-secret"

Key within that Secret.

scanning.presidio.image.repository​

Type: string

Default value
image-proxy.stacklok.com/proxy/stacklok-enterprise/ghcr.io/stacklok/stacklok-enterprise/presidio-analyzer

Presidio Analyzer image.

scanning.presidio.image.tag​

Type: string

Default: ""

Image tag (defaults to appVersion if empty).

scanning.presidio.image.digest​

Type: string

Default: ""

Optional image digest, appended as @<digest> after the tag.

scanning.presidio.image.pullPolicy​

Type: string

Default: "IfNotPresent"

Image pull policy.

scanning.presidio.replicas​

Type: int

Default: 2

Replica count, and the HPA's minReplicas. With autoscaling.mode External, set it to the scaler's minimum: it sizes per-request Presidio fan-out.

scanning.presidio.maxReplicas​

Type: string

Default: nil

Upper bound for the HPA. Unset means no HPA.

scanning.presidio.targetCPUUtilization​

Type: string

Default: nil

HPA target average CPU utilization, 1-100. Defaults to 75 when unset.

scanning.presidio.autoscaling.mode​

Type: string

Default: "HPA"

Who owns the replica count: HPA, External (e.g. KEDA) or None. The first upgrade that omits replicas drops to 1 analyzer until the scaler acts; do it in a low-traffic window.

scanning.presidio.podAnnotations​

Type: object

Default: {}

Annotations added to the Presidio pods. The chart's own checksum annotations win over a same-named entry.

scanning.presidio.nodeSelector​

Type: object

Default: {}

Node labels for Presidio pod assignment.

scanning.presidio.tolerations​

Type: list

Default: []

Tolerations for Presidio pod assignment.

scanning.presidio.topologySpreadConstraints​

Type: list

Default: []

Topology spread constraints for the Presidio pods. Entries without a labelSelector get the Presidio selector labels.

scanning.presidio.resources​

Type: object

Default: {"limits":{"cpu":"2","memory":"3Gi"},"requests":{"cpu":"500m","memory":"2Gi"}}

Analyzer container resources. One worker runs per whole core of limits.cpu; allow about 1Gi of limits.memory per worker or the render fails.

scanning.presidio.language​

Type: string

Default: "en"

Analysis language. Only en is supported.

scanning.presidio.scoreThreshold​

Type: int

Default: 50

Minimum Presidio confidence, 0-100, for a detection to count.

scanning.presidio.recognizers​

Type: list

Default: []

Custom Pattern recognizers: name, supportedEntity (UPPER_SNAKE, not a built-in), and patterns (name, RE2 regex, score) and/or denyList, optional contextWords. Editing this list rolls Presidio.

guardrails.enabled​

Type: bool

Default: false

Render the guardrails-adapter, including a cluster-scoped ClusterRoleBinding, and wire the gateway's guardrails hook to it. It screens user text with Amazon Bedrock Guardrails after scanning.

guardrails.mode​

Type: string

Default: "Enforce"

Enforce blocks a request the guardrail intervenes on. Monitor never blocks and only counts and logs what Enforce would have blocked.

guardrails.failurePolicy​

Type: string

Default: "Fail"

When the adapter fails under Enforce: Fail blocks the request, Ignore admits it.

guardrails.unscreenableContentPolicy​

Type: string

Default: "Deny"

User content the adapter cannot screen: Deny blocks it, Admit lets it through unscreened. Fallback for every class in unscreenableContentPolicies without an entry.

guardrails.unscreenableContentPolicies​

Type: object

Default: {}

Per-class overrides, each Admit or Deny: nonTextMedia (image, audio, video or a document with no text), toolResult, unrecognizedPart and unrecognizedShape. toolResult defaults to Admit, since agentic clients carry tool output on most turns; the rest follow unscreenableContentPolicy. The adapter sends Bedrock text only, so set nonTextMedia: Admit to let media through unscreened. One Deny blocks.

guardrails.screeningWindowTurns​

Type: string

Default: nil

Screen sliding windows of the last N user turns instead of the whole conversation, an integer of at least 3. Each window's verdict is cached, so on a warm cache a request costs one Bedrock call against at most N turns rather than one against every turn so far. Requires verdictCache.enabled with a resolvable Redis; without a usable cache the adapter screens the whole conversation as it does when this is unset. Only turns carrying text the user wrote count toward N: a tool-output, media-only, whitelisted or empty turn takes no slot. Trade-off: an injection split across more than N text turns is not caught.

guardrails.screeningWindowMaxLiveCalls​

Type: string

Default: nil

The most live Bedrock calls one windowed request makes, an integer of at least 1. Unset keeps the adapter default of 3. A warm cache needs one. On a cold or slow cache, up to this many uncached windows are screened and cached one by one, oldest first, and any beyond that are screened together in a single call, so a long conversation stays inside hook.timeout and warms over its next requests. A cache backend that times out stops being consulted for the rest of the request, and the reads of one request share a fixed budget, so a slow backend cannot spend hook.timeout.

guardrails.verdictCache.enabled​

Type: bool

Default: false

Cache each turn window's Bedrock verdict in Redis/Valkey, keyed by the window's text digest, the guardrail and the window size. Used only when screeningWindowTurns is set. Entries live under aigw:guardrail:v1:val1:<release-namespace>:<fullname>: and last 24h, clamped to 1 minute for a DRAFT guardrail, which is republished in place. Requires a Redis host here or in global.redis.

guardrails.verdictCache.redis.host​

Type: string

Default: ""

Redis host. Empty falls back to global.redis.host.

guardrails.verdictCache.redis.port​

Type: string

Default: nil

Redis port. Empty falls back to global.redis.port.

guardrails.verdictCache.redis.clusterMode​

Type: string

Default: nil

Speak the Redis Cluster protocol. Unset falls back to global.redis.clusterMode.

guardrails.verdictCache.redis.username​

Type: string

Default: ""

ACL username. Empty falls back to global.redis.username.

guardrails.verdictCache.redis.existingSecret​

Type: string

Default: ""

Secret holding the Redis password, in the release namespace. Empty falls back to global.redis.existingSecret.

guardrails.verdictCache.redis.existingSecretKey​

Type: string

Default: ""

Key within that Secret. Empty falls back to global.redis.existingSecretKey.

guardrails.verdictCache.redis.tls​

Type: string

Default: nil

Dial Redis over TLS. Unset falls back to global.redis.tls.enabled.

guardrails.verdictCache.macSecret.name​

Type: string

Default: ""

Bring your own Secret holding the cache's HMAC key, in the release namespace. The adapter only reads it. Empty makes the adapter get-or-create <fullname>-guardrail-cache-mac at startup, through a Role the chart renders (get pinned to that name, create in the namespace); without that grant it logs a WARN and screens the whole conversation uncached. A supplied value must be at least 32 bytes of printable text. Rotation is to replace the value and restart the adapter, a cache cold start.

guardrails.verdictCache.macSecret.key​

Type: string

Default: "mac-secret"

Key within that Secret. Applies to a supplied Secret and to the one the adapter provisions.

guardrails.audience​

Type: string

Default: ""

Audience of the token the gateway presents to the adapter. Empty derives https://<adapter-service>.<release-namespace>.svc.

guardrails.bedrock.guardrailId​

Type: string

Default: ""

Bedrock guardrail identifier. Required.

guardrails.bedrock.guardrailVersion​

Type: string

Default: ""

Guardrail version: DRAFT or a positive integer, written as a string ("1", not 1). Required.

guardrails.bedrock.region​

Type: string

Default: ""

AWS region of the guardrail, e.g. us-east-1. Required.

guardrails.bedrock.promptWhitelist​

Type: object

Default: {"prompts":[],"regexes":[]}

Prompts excluded from screening: exact prompts, or RE2 regexes that match anywhere unless anchored (^ping$, not ^ping).

guardrails.bedrock.credentialsSecretRef​

Type: object

Default: {"name":""}

Secret holding an AWS credentials file under the key credentials. Empty uses the pod's ambient AWS identity (EKS Pod Identity or IRSA).

guardrails.bedrock.endpoint​

Type: string

Default: ""

Bedrock Runtime base URL override, for a PrivateLink endpoint or a test double. Empty uses the SDK's regional endpoint.

guardrails.hook.timeout​

Type: string

Default: "5s"

Budget the gateway gives the adapter, as a single-unit Go duration of at most 120s. The adapter's own Bedrock call must finish inside it.

guardrails.hook.tokenExpirationSeconds​

Type: int

Default: 3600

Requested lifetime of the projected token, minimum 600.

guardrails.hook.tokenMountPath​

Type: string

Default: "/var/run/secrets/guardrails"

Directory the projected token is mounted into on the gateway pod.

guardrails.hook.caMountPath​

Type: string

Default: "/etc/guardrails-tls"

Directory the adapter CA bundle is mounted into on the gateway pod.

guardrails.tls.issuerRef​

Type: object

Default: {"kind":"","name":""}

cert-manager issuer for the adapter's serving certificate. Empty name falls back to global.webhooks.issuerRef; one of the two must name an issuer.

guardrails.tls.caBundleSecret​

Type: string

Default: ""

Secret holding the PEM CA that verifies the adapter's serving certificate, in the release namespace. Empty falls back to global.webhooks.caBundleSecret; one of the two is required.

guardrails.tls.caBundleKey​

Type: string

Default: "ca.crt"

Key within that Secret holding the PEM bundle.

guardrails.adapter.image.repository​

Type: string

Default value
image-proxy.stacklok.com/proxy/stacklok-enterprise/ghcr.io/stacklok/stacklok-enterprise/ai-gateway-main-processor

Guardrails-adapter image (the ai-gateway main-processor).

guardrails.adapter.image.tag​

Type: string

Default: ""

Image tag (defaults to appVersion if empty).

guardrails.adapter.image.digest​

Type: string

Default: ""

Optional image digest, appended as @<digest> after the tag.

guardrails.adapter.image.pullPolicy​

Type: string

Default: "IfNotPresent"

Image pull policy.

guardrails.adapter.replicas​

Type: int

Default: 2

Replica count, and the HPA's minReplicas. Under failurePolicy: Fail a single adapter is a single point of failure for every request.

guardrails.adapter.maxReplicas​

Type: string

Default: nil

Upper bound for the HPA. Unset means no HPA, and replicas is written on the Deployment.

guardrails.adapter.targetCPUUtilization​

Type: string

Default: nil

HPA target average CPU utilization, 1-100. Defaults to 75 when unset.

guardrails.adapter.podAnnotations​

Type: object

Default: {}

Annotations added to the adapter pods. The chart's own checksum annotation wins over a same-named entry.

guardrails.adapter.nodeSelector​

Type: object

Default: {}

Node labels for adapter pod assignment.

guardrails.adapter.tolerations​

Type: list

Default: []

Tolerations for adapter pod assignment.

guardrails.adapter.topologySpreadConstraints​

Type: list

Default: []

Topology spread constraints for the adapter pods. Entries without a labelSelector get the adapter's selector labels.

guardrails.adapter.serviceAccount.annotations​

Type: object

Default: {}

Annotations on the adapter's ServiceAccount, e.g. the eks.amazonaws.com/role-arn of an IRSA role.

guardrails.adapter.resources​

Type: object

Default: {"limits":{"cpu":"500m","memory":"256Mi"},"requests":{"cpu":"50m","memory":"64Mi"}}

Adapter container resources.

guardrails.adapter.metrics.enabled​

Type: string

Default: nil

Serve the adapter's screening metrics. Unset follows the gateway's telemetry settings; false turns them off; true always serves port.

guardrails.adapter.metrics.port​

Type: int

Default: 9090

Port for the guardrails adapter's Prometheus metrics listener when metrics serving is enabled.