Documentation Index
Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt
Use this file to discover all available pages before exploring further.
What it does
Every call toGET /api/v1/decisions/:id/provenance returns a
canonicalised provenance bundle (decision trace + model snapshots +
audit chain + SLSA attestation + fairness slice). When the deployment
is configured for sigstore signing, the bundle is also signed with
cosign sign-blob and the detached signature lands in the response
header:
Configuration
Two env vars on the runtime container:| Env var | Required | Meaning |
|---|---|---|
| COSIGN_KEY | yes (for signing) | Cosign-format private key bytes (e.g., the contents of cosign.key your operator generated with cosign generate-key-pair). Cosign accepts the raw bytes via the env:// URI scheme — see below. |
COSIGN_BINARY | no | Override the binary path (default: cosign on PATH). The image installs cosign at /usr/local/bin/cosign. |
How the signing works
lib/supply-chain/cosign-sign-blob.ts invokes:
spawnonly — neverexec. No shell is invoked, so there is no command-injection surface. The full argv is a fixed array of constants.- The signing key never appears on argv. Cosign reads the key
bytes from the env var named by the
env://COSIGN_KEYURI; only the URI string lives in argv. - The blob payload arrives via stdin. No tempfile, no argv leak. The canonical-JSON bundle is piped to the child’s stdin and the stream is closed immediately.
spawn’s argv (it scans every argv entry for
the literal key value).
Failure modes (fail-soft to “unsigned”)
| Condition | Header value | Audit log changes field |
|---|---|---|
| COSIGN_KEY env unset | unsigned | signed: false (no signatureFailureCode) |
| Cosign binary missing on PATH | unsigned | signed: false, signatureFailureCode: "binary_missing" |
| Cosign exited non-zero | unsigned | signed: false, signatureFailureCode: "exit_nonzero" |
| Cosign exited 0 but with empty stdout | unsigned | signed: false, signatureFailureCode: "exit_nonzero" |
| 30s spawn timeout | unsigned | signed: false, signatureFailureCode: "timeout" |
| spawn-time OS error (permission denied, out of memory, etc.) | unsigned | signed: false, signatureFailureCode: "spawn_error" |
diagnostics field — never to the
response body, never to the response header.
Image layout
The runtime stage ofplatform/Dockerfile installs cosign:
cosign verify-blob against the sigstore root after image build, as a
separate CI step. That bootstrap is operator-authorised follow-up.
Installing cosign signing
Bundles are returned unsigned until you provide a signing key. There are exactly two supported install paths — pick whichever matches your deployment topology. Both paths set the same two env vars (COSIGN_KEY, COSIGN_PASSWORD) on the runtime container; what differs is where those values live at rest.Path A — Cloud (AWS Secrets Manager)
Use this on App Runner / ECS / EKS / any AWS-resident deployment. Keys live encrypted in Secrets Manager and the runtime resolves them at container start. Operator runbook with full commands lives attools/runbooks/cosign-key-rollout.md
in the platform repo. Summary:
cosign generate-key-pair(one time) →cosign.key+cosign.pub.aws secretsmanager create-secret --name <prefix>/cosign-key --secret-string file://cosign.keyaws secretsmanager create-secret --name <prefix>/cosign-password --secret-string '<passphrase>'- Grant the runtime instance role
secretsmanager:GetSecretValueon those two ARNs (least-privilege; one inline policy is enough). - Wire the ARNs as runtime secrets (App Runner runtime-env-secrets
block, ECS task-definition secrets list, or EKS
valueFrom.secretKeyRef). - Commit
cosign.pubtokaireonai-docs/security/cosign.pubso downstream verifiers can validate signatures offline.
Path B — Self-host / local (key file on disk)
Use this for VM, on-prem, Docker Compose, or single-host installs.cosign generate-key-pair(one time) →cosign.key+cosign.pub.- Mount
cosign.keyinto the container (read-only,0400):Or read at boot: - Restart the container.
- Distribute
cosign.pubto every party that needs to verify bundles (CI, audit reviewers, downstream consumers).
Required. Production deployments must install cosign signing
via Path A or Path B. Running without it leaves every provenance
bundle marked X-Provenance-Signature: unsigned, which downstream
verifiers reject. The fail-soft is intentional (a missing key never
breaks the response) but is not a substitute for installation.
Verifying signing is live
- Hit
/api/v1/decisions/:id/provenanceand confirm the response includesX-Provenance-Signature: <base64>(notunsigned). - Verify offline:
- Audit-log spot-check:
auditLog.changes.signedshould betruefor every successful bundle. AsignatureFailureCodefield means the wire intended to sign but couldn’t — page whoever owns the image / key-management layer.
Roadmap
- Keyless signing (Fulcio + OIDC + Rekor upload) so the deployment does not need a long-lived private key.
- Image-time
cosign verify-blobof the cosign release artefact itself (closes the bootstrap-trust gap noted above). - Reproducible-build verification step that re-canonicalises the bundle and re-signs against a CI-only key, comparing digests.