Attestkeep docs

Configuration

Installation shape comes from Helm values. Anything a person changes while running it lives in the console, so a policy edit is not a redeploy.

An upgrade may be run with helm upgrade --reuse-values, which keeps the values you installed with and does not merge in the new chart's defaults. Every setting added since your installed version then takes the default documented here, so the flag is supported across versions — see Upgrade.

Identity and scale

ValueDefaultWhat it does
clusterName""Names this installation in notifications and evidence. Never a hostname — nothing topological leaves the cluster.
replicaCount2Webhook replicas, spread by anti-affinity. One serves, two survive a node.
scanner.replicas1Scan workers. Raising this with a ReadWriteOnce cache is refused at install.
image.repositoryghcr.io/attestkeep/attestkeep-k8sPoint at your mirror for an air-gapped install.
image.tagchart appVersion

Database

ValueDefaultWhat it does
postgresql.enabledtrueInstall a PostgreSQL alongside. Turn off to use your own.
postgresql.persistence.size20Gi
postgresql.auth.password""Generated when empty.
externalDsnExistingSecret.name""Preferred for an external database.
externalDsn""A DSN inline. Avoid: it lands in your Helm release history and stays there.

Scanning

ValueDefaultWhat it does
scan.workers2Concurrent scans per scanner pod.
scan.timeout10mPer scan.
scan.rescanInterval24hHow often a known digest is re-evaluated against a refreshed database.
scan.insecureRegistries[]Registries served over plain HTTP. Must be named — silently downgrading a connection is not a decision a security tool makes for you.
scan.cosignOfflinefalseVerify against the key and skip the transparency log. See air-gapped for what that costs.
kev.sourceCISA's catalogue URLWhere the Known Exploited Vulnerabilities catalogue is fetched from, on the same six-hour cadence as the vulnerability database. A path or a file:// URL reads a mirror inside the perimeter instead; kev.existingConfigMap below mounts one. An empty string refreshes nothing: the stored catalogue stays exactly as it is and findings keep being marked against it. What admission does about a marked finding is the policy's choice: spec.knownExploited.
kev.existingConfigMap""The name of a ConfigMap in the release namespace holding a mirrored copy of the catalogue, mounted read-only at /etc/kev on the scanner. The copy has to be gzipped: a ConfigMap holds at most 1 MiB and the published catalogue is 1.7 MB, which the API server refuses outright; gzipped it is under 200 KB. Point kev.source at file:///etc/kev/<key>, the key being the name of the file the ConfigMap was created from — gzip -k known_exploited_vulnerabilities.json and kubectl -n attestkeep create configmap kev-catalog --from-file=known_exploited_vulnerabilities.json.gz is read as file:///etc/kev/known_exploited_vulnerabilities.json.gz. The scanner decides whether a file is compressed by its first two bytes, not its name. Empty mounts nothing.
reconcile.interval1hHow often what is actually running — each container's observed imageID — is reconciled against the admission ledger, catching workloads that entered before the install, during an outage, or under failurePolicy: Ignore. 0 disables the sweep. What a finding does is the policy's choice: spec.runtimeReconciliation.
rbac.allowEnforcefalseWhether the operator may evict pods at all. Enforcement is armed with two keys: the policy chooses enforce, this grants the pods/eviction permission it needs. An audit-only install carries no eviction right.

Admission

See Admission — webhook.failurePolicy and webhook.coldImagePolicy are posture decisions rather than tuning, and they are explained there rather than listed here.

Runtime events (Falco)

Attestkeep does not ship, install or run Falco, and never writes to it. Your own Falco sends its alerts to the operator over mutual TLS, from its own http_output or through Falcosidekick (integrations.falco.connection): the operator issues a client certificate and accepts events only from it. An event never changes an admission decision; a runtime policy can send it on, open an issue and stop the pod it came from. The Falco side, the certificates and what the events then do are on Runtime events.

ValueDefaultWhat it does
integrations.falco.enabledfalseTurns the integration on: the integrations listener, the Falco client CA and client certificate (Secret <release>-falco-mtls), and the console's Falco section. Off, there is no listener and no CA.
integrations.port8444The TLS port Falco posts to, on the pod and the Service. It requires a client certificate from the Falco CA and serves only POST /api/v1/integrations/falco. Only used when the integration is on.
runtime.retentionDays90Every event is stored; stored events older than this are removed hourly. Only events — issue history, audit entries and rule revisions stay. 0 keeps them.

What an event leads to is not a chart value: it is decided by the runtime rules written in the console's Falco section. integrations.falco.existingSecret and integrations.falco.minPriority from earlier releases are no longer read.

Licence

ValueDefaultWhat it does
license.existingCertificateSecret""Name of a Secret holding an offline certificate under the key certificate, for installs that never open the console. The operator reads it at start and activates from it if it holds no certificate, or if this one runs later than the one it holds, so a Secret left behind after a console renewal is ignored. The certificate comes from the licence page at attestkeep.com, issued against an activation request this cluster produced, so it is valid for this cluster and no other. Empty everywhere else: activation is a console screen, not a chart value. See offline activation.
nodes.pollInterval5mHow often the operator counts the cluster's Ready nodes against the licence's node ceiling. The count stays in the cluster.
nodes.graceDays14Days the cluster may stay over its node ceiling before image names never seen this period are denied at admission; everything already counted keeps running. Neither value loosens the ceiling, which is in the certificate. See the node ceiling.

The data key

The key that encrypts the credentials this installation stores for you — today the issue-tracker tokens that can open and close issues in your own GitHub, GitLab or Jira. Those tokens live in the product database, so without this key a backup or a dump handed to support would carry a working write credential for your forge.

ValueDefaultWhat it does
api.dataKey.existingSecret.name""Empty means the chart generates <release>-data-key on first install and preserves it across upgrades. Point this at your own Secret to supply the key from a secret manager instead.
api.dataKey.existingSecret.keydata-keyThe key inside that Secret.
kubectl -n attestkeep create secret generic attestkeep-data-key \
  --from-literal=data-key="$(openssl rand -hex 32)"

It is never written into the product database — a key stored beside the data it protects is not a key — and there is no database fallback: with no key, saving an issue-tracker channel is refused rather than storing the token in the clear, and nothing else about the product changes. Re-keying is not offered in this version; if you replace the key, the credentials already stored cannot be opened and each tracker channel needs its token entered again. Back the Secret up with everything else on Backup and restore.

Observability

Metrics are exposed in Prometheus format on the operator's metrics port, and labelled series are created at zero on start-up so a dashboard is not empty until the first event. OTLP export is available and is always additional: if the collector is unreachable, nothing about scanning or admission changes.

OpenTelemetry export switches on the moment a collector is named, and not before. Traces cover the admission path — the span is what answers "why did that pod take four seconds" — metrics mirror the Prometheus set, and logs travel with their attestkeep.log/v1 schema version.

ValueDefaultWhat it does
observability.otlp.endpointemptyThe collector, e.g. http://otel-collector.observability.svc:4317. Empty means no OTLP export at all.
observability.otlp.protocolgrpcgrpc or http/protobuf.
observability.otlp.insecuretruePlain connection, for a collector on the cluster's own network. Set false the moment the endpoint leaves it.
observability.otlp.headersemptykey=value pairs, comma-separated — how a hosted collector takes its API key.
observability.traces.enabledtrueTraces, once an endpoint exists.
observability.traces.sampleRatio0.1A tenth of admission reviews. Admission runs on every pod in the cluster; a full trace of each is a bill rather than a signal.
observability.metrics.enabledtrueMetrics over OTLP, once an endpoint exists. The Prometheus port stays either way.
observability.metrics.intervalMillis30000Export interval, in milliseconds because the OpenTelemetry specification defines it that way.
observability.logs.enabledtrueLogs over OTLP, once an endpoint exists. Stdout keeps its copy regardless.

The same knobs answer to their standard environment names (OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_TRACES_SAMPLER_ARG, OTEL_METRIC_EXPORT_INTERVAL, …) for an installation that configures collectors outside Helm.

The log level is a runtime control in the console, not a deployment setting. Turning up logging to diagnose something should not require a rollout.

What lives in the console instead

The dividing line: a Helm value describes how the installation is shaped, and everything a person changes while operating it belongs where they can change it without a deploy.

The Single Sign-On page: OIDC providers with their issuer and client id, a stored secret, the fixed redirect URI to register with each provider, an on-sign-in-page toggle, and a test-connection action.
Single sign-on is one of these console-managed settings. Each provider bounces the browser back to one fixed redirect URI on this installation — register it with the provider exactly, down to the trailing slash, or the sign-in is refused. A provider can be tested and toggled on the sign-in page without a redeploy. SSO is an Enterprise capability, and the server is always the real gate on who gets in.