Secret manifest¶
apiVersion: v1beta1
kind: Secret
metadata:
name: anthropic-token
realm: kuke-system # scope coordinates; deepest non-empty wins
# space: team-a # optional — space-scoped
# stack: web # optional — stack-scoped (requires space)
# cell: api # optional — cell-scoped (requires stack)
spec:
data: <bytes> # write-only; never echoed back
A Secret is a named, scoped, daemon-managed credential. Unlike the realm / space / stack / cell hierarchy resources it has no runtime and carries no status — its only state is the bytes on disk. kuke apply writes the bytes to a root-owned file under the scope's metadata tree; there is no get / delete verb (tracked in #622) yet.
See docs/cli-use-cases.md → Secrets for the full apply workflow and invariants.
metadata¶
Scope coordinates live on metadata (not spec), so a Secret's full identity is its scope plus its name.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | The secret's name, unique within its scope. |
realm |
string | yes | The always-required top-level scope coordinate. |
space |
string | no | When set, scopes the secret to a space within realm. |
stack |
string | no | When set, scopes the secret to a stack within space (requires space). |
cell |
string | no | When set, scopes the secret to a cell within stack (requires stack). |
The scope is the deepest non-empty coordinate: a Secret with only realm set is realm-scoped; one with realm + space + stack set is stack-scoped. A deeper coordinate may only be set when every shallower one is — a cell-scoped secret must also name its stack, space, and realm; a gap exits non-zero.
spec¶
spec.data (string, required)¶
The raw secret material supplied at apply time. Write-only: it is persisted to the daemon-managed file and never echoed back in any apply output, daemon log, or audit trail. Must be non-empty; an empty data exits non-zero.
Storage layout¶
The daemon writes the bytes to a root-owned file under the scope's metadata tree:
<runPath>/data/<realm>/secrets/<name> # realm-scoped
<runPath>/data/<realm>/<space>/secrets/<name> # space-scoped
<runPath>/data/<realm>/<space>/<stack>/secrets/<name> # stack-scoped
<runPath>/data/<realm>/<space>/<stack>/<cell>/secrets/<name> # cell-scoped
The secrets/ directory is 0700 and each secret file is 0600, both owned by root — stricter than the 0o2750 setgid metadata directories, so the kuke group cannot read secret material. Because secrets/ nests inside the scope's metadata directory, the same teardown that reclaims a scope (kuke purge / kuke delete) reclaims its secrets too. There is no crypto-at-rest in v1.
Invariants¶
- Exit code 0 on success; the result reports
createdon the first apply of a name andupdatedon re-apply (write-through — the daemon overwrites without reading the prior bytes back to diff them). - The scope must already exist — apply does not auto-create a missing realm / space / stack / cell for a secret (unlike the hierarchy reconcilers). An unreachable scope exits non-zero with a
scope does not existmessage.
Minimal¶
apiVersion: v1beta1
kind: Secret
metadata:
name: anthropic-token
realm: kuke-system
spec:
data: sk-ant-...
A realm-scoped secret named anthropic-token in the kuke-system realm.