Skip to content

Supply chain & attestation CRDs

These four kinds form the supply-chain story: every signed fact in the cluster is an AttestationBundle, the attestor reads AttestorConfig for its signing mode, and per-node hardware measurements flow through the ConfidentialAttestationRun / ConfidentialAttestationResult pair.

KindScopeCardinalityOwning operator
AttestationBundleClusterper signed factugallu-attestor
AttestorConfigNamespacedsingleton per namespaceugallu-attestor
ConfidentialAttestationRunNamespacedper node + windowconfidential-attestation
ConfidentialAttestationResultNamespacedper runconfidential-attestation

Cluster-scoped, one CR per signed fact. Owned by ugallu-attestor.

Spec

  • attestedFor (ObjectReference) - the SecurityEvent or EventResponse being signed.
  • parentBundleRef (ObjectReference, optional) - for re-attestation, closure, or redaction records that chain back to a previous bundle.

Status

  • phase (enum) - Pending, Signed, Logged, Sealed.
  • statementDigest (string) - SHA-256 of the canonicalised in-toto Statement.
  • signature.mode (enum) - fulcio-keyless, openbao-transit, dual.
  • signature.keyID (string) - fingerprint of the key used.
  • rekorEntry.{logIndex, uuid, inclusionProof} - transparency log inclusion proof.
  • wormRef - DSSE envelope archived to WORM.
  • signedAt, sealedAt - lifecycle timestamps.
  • failures[] - errors encountered during pipeline stages (preserved on retry so a half-failure stays auditable).

A bundle reaches Sealed only after the DSSE envelope is in WORM AND the rekor inclusion proof is recorded. Anything short of that keeps the bundle in an earlier phase, and forensics will not trigger on it (when requireAttested=true).

Example (created by the attestor, not by humans)

apiVersion: security.ugallu.io/v1alpha1
kind: AttestationBundle
metadata:
name: bundle-1f4abc
labels:
ugallu.io/source-uid: "1f4abc..."
spec:
attestedFor:
apiVersion: security.ugallu.io/v1alpha1
kind: SecurityEvent
name: ugse-cluster-admin-xfb2
status:
phase: Sealed
statementDigest: "sha256:..."
signature:
mode: fulcio-keyless
keyID: "abcd1234..."
rekorEntry:
logIndex: 8412933
uuid: "..."
signedAt: "2026-04-29T20:11:42Z"
sealedAt: "2026-04-29T20:11:46Z"

Namespace-scoped singleton. Configures the signing mode plus the endpoints / credentials for the active backend(s).

Spec

  • signingMode (enum) - fulcio-keyless (default), openbao-transit, or dual (sign with both, fail if either fails).
  • fulcio.issuer (string) - OIDC issuer URL.
  • fulcio.fulcioURL (string) - Fulcio v2 CA endpoint.
  • fulcio.oidcTokenPath (string) - projected ServiceAccount token mount path.
  • openbao.address (string) - OpenBao base URL.
  • openbao.transitMount (string) - default transit.
  • openbao.keyName (string) - must be ed25519, rsa-pss-sha256, or ecdsa-p256.
  • openbao.authRole (string) - K8s auth role bound to the attestor’s ServiceAccount.
  • rekor.enabled (bool) - default true.
  • rekor.url (string) - transparency log endpoint.

Status - none. Last-load failures surface as a SE rather than on the CR.

InsecureSkipVerify on the Fulcio CA bundle and OpenBao TLS is exposed for development clusters only; flip it back off before promoting to staging.

Example

apiVersion: security.ugallu.io/v1alpha1
kind: AttestorConfig
metadata: { name: default, namespace: ugallu-system }
spec:
signingMode: dual
fulcio:
issuer: "https://kubernetes.default.svc.cluster.local"
fulcioURL: "https://fulcio.sigstore.dev"
oidcTokenPath: "/var/run/secrets/sigstore/oidc-token"
openbao:
address: "https://openbao.openbao:8200"
transitMount: transit
keyName: ugallu-attestor-prod
authRole: ugallu-attestor
rekor:
enabled: true
url: "https://rekor.sigstore.dev"

Namespace-scoped, one CR per node + window. Owned by confidential-attestation.

Spec

  • backend (enum) - tpm, sev-snp, tdx.
  • targetNodeName (string) - node the run targets. The DaemonSet pod whose NODE_NAME matches handles the reconcile; everyone else skips.
  • nonce (string) - anti-replay value (32-byte hex recommended).
  • policyRef (LocalProfileRef, optional) - AttestationPolicy with expected measurements. Absent = report-only mode.
  • timeout (Duration) - default 2m.

Status

  • phase (enum) - Pending, Running, Succeeded, Failed.
  • startTime, completionTime.
  • resultRef - the ConfidentialAttestationResult produced (empty until Succeeded).
  • conditions[].

Example

apiVersion: security.ugallu.io/v1alpha1
kind: ConfidentialAttestationRun
metadata: { name: bootcheck-node1, namespace: ugallu-system }
spec:
backend: tpm
targetNodeName: node1.example.internal
nonce: "1f4abc...32 bytes hex..."
policyRef:
name: tpm-policy-bios-v3
kind: AttestationPolicy
timeout: 30s

Namespace-scoped, one CR per run. Carries the quote bytes plus the verifier verdict.

Spec

  • derivedFromRun (LocalProfileRef).
  • backend (enum) - mirrors the run.
  • nodeName (string) - the node that answered.
  • nonce (string) - the value the run requested (audit trail).
  • quote (bytes) - raw attestation evidence (TPM2 quote / SNP report / TDX report - shape varies by backend).
  • signature (bytes) - quote signature (TPM EK / SNP VLEK / TDX - empty when the signature is embedded in the quote bytes).
  • measurements[] - per-slot digest summary extracted by the verifier.
  • verdict (enum) - verified, failed, indeterminate.
  • verifierNotes (string) - chain check details, missing-device messages, etc.

Status

  • trusted (bool) - true only when verdict=verified.

Results are kept 7 days; the linked AttestationBundle carries the long-term signed snapshot.

Example (controller-produced)

apiVersion: security.ugallu.io/v1alpha1
kind: ConfidentialAttestationResult
metadata: { name: bootcheck-node1-result, namespace: ugallu-system }
spec:
derivedFromRun: { name: bootcheck-node1 }
backend: tpm
nodeName: node1.example.internal
nonce: "1f4abc..."
quote: "<base64 quote bytes>"
signature: "<base64 quote signature>"
measurements:
- { slot: "PCR-0", digest: "sha256:ab12...c3" }
- { slot: "PCR-7", digest: "sha256:ee45...77" }
verdict: verified
verifierNotes: "policy tpm-policy-bios-v3 matched, all PCRs ok"
status:
trusted: true