Skip to main content

CRD Reference

Complete reference for all Custom Resource Definitions (CRDs) managed by zen-lock.

Overview

zen-lock manages three CRDs:

CRDKindPurpose
zenlocks.security.zen-mesh.ioZenLockEncrypted secret storage
zenlockcustodies.security.zen-mesh.ioZenLockCustodySigning key custody (Zen Trust)
noncebuckets.security.zen-mesh.ioNonceBucketReplay attack prevention

API Version: security.zen-mesh.io/v1beta1

Short names: zenlock, zl


ZenLock

The primary CRD for storing encrypted secrets. Contains only ciphertext — the API server and etcd never see plaintext.

Schema

apiVersion: security.zen-mesh.io/v1beta1
kind: ZenLock
metadata:
name: <string> # Required; unique in namespace
namespace: <string> # Required
labels: <map>
annotations: <map>
spec:
algorithm: age # Required; currently only "age" supported
encryptedData: # Required; map of key -> base64 ciphertext
<key>: <value>
allowedSubjects: # Optional; ServiceAccounts allowed to receive this secret
- kind: ServiceAccount # Required; only ServiceAccount in v1beta1
name: <string> # Required
namespace: <string> # Optional; defaults to ZenLock namespace
status:
phase: Ready|Error # Current state
lastRotation: <time> # Last key rotation timestamp
conditions: # Detailed conditions
- type: <string>
status: True|False|Unknown
reason: <string>
message: <string>
lastTransitionTime: <time>
rotation: # Key rotation state
phase: idle|rotating|deprecated
activeKeyId: <string>
previousKeyId: <string>
rotatedAt: <time>
deprecatedAt: <time>
graceHits: <integer>
reencrypted: <integer>
pending: <integer>
safeToDeprecate: <boolean>

Fields Reference

spec

FieldTypeRequiredDescription
spec.algorithmstringYesEncryption algorithm. Currently only age is supported.
spec.encryptedDatamap[string]stringYesMap of secret keys to base64-encoded age ciphertext.
spec.allowedSubjects[]SubjectReferenceNoList of ServiceAccounts authorized to receive this secret. Empty = deny all.

spec.allowedSubjects[]

FieldTypeRequiredDescription
kindstringYesMust be ServiceAccount.
namestringYesName of the ServiceAccount.
namespacestringNoNamespace of the ServiceAccount. Defaults to the ZenLock's namespace.

status

FieldTypeDescription
status.phasestringReady or Error.
status.lastRotationtimeLast key rotation timestamp.
status.conditions[][]ZenLockConditionDetailed state conditions.
status.rotationRotationStatusCurrent rotation state (see Key Rotation).

Example

apiVersion: security.zen-mesh.io/v1beta1
kind: ZenLock
metadata:
name: db-credentials
namespace: production
spec:
algorithm: age
encryptedData:
username: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM=
password: cGFzc3dvcmQxMjM0NTY3ODkwYWJjZGVmZ2g=
allowedSubjects:
- kind: ServiceAccount
name: my-app
namespace: production
status:
phase: Ready

Short Names

kubectl get zenlock <name>
kubectl get zl <name>

ZenLockCustody

Holds AGE-encrypted signing keys for Zen Trust. Each object stores exactly one custody key entry — ciphertext only, so the API server never sees plaintext key material.

Internal use

ZenLockCustody is primarily used by Zen Mesh internally for Zen Trust signing key custody. It's listed here for completeness.

Schema

apiVersion: security.zen-mesh.io/v1beta1
kind: ZenLockCustody
metadata:
name: <string> # Derived: {tenant}-{keyRef}-v{version}
namespace: <string>
spec:
tenantId: <string> # Required; tenant identifier
keyReference: <string> # Required; key identifier within tenant
version: <integer> # Required; monotonic version number
algorithm: <string> # Required; e.g., "ES256"
usage: <string> # Required; e.g., "ZCC_SIGNING"
encryptedPrivateKey: <string> # AGE-encrypted, base64-encoded PEM key
activationTime: <time> # Required; when key becomes usable
expiryTime: <time> # Optional; zero = never expires
status: active|revoked|retired|expired|pending # Required
provenance: <string> # Optional; audit metadata
status:
phase: <string> # Controller's observation

Fields Reference

FieldTypeRequiredDescription
spec.tenantIdstringYesTenant identifier (1-253 chars).
spec.keyReferencestringYesKey identifier within tenant (1-253 chars).
spec.versionintegerYesMonotonic version number per tenant+reference.
spec.algorithmstringYesSigning algorithm (e.g., "ES256").
spec.usagestringYesKey usage (e.g., "ZCC_SIGNING").
spec.encryptedPrivateKeystringYesAGE-encrypted, base64-encoded PEM private key (1-32KB).
spec.activationTimetimeYesWhen the key becomes usable.
spec.expiryTimetimeNoWhen the key expires. Zero means no expiry.
spec.statusstringYesLifecycle state: active, revoked, retired, expired, or pending.
spec.provenancestringNoAudit metadata (origin information).

Object Naming

ZenLockCustody objects are named deterministically:

<tenant-id>-<key-ref>-v<version>

Example: acme-corp-signing-key-v1


NonceBucket

Stores accepted replay-attack prevention nonces. Buckets are sharded by minute to keep objects small and enable efficient cleanup.

Schema

apiVersion: security.zen-mesh.io/v1beta1
kind: NonceBucket
metadata:
name: nonce-<bucket-start-utc> # e.g., nonce-2026-08-15t14-30-00z
namespace: <string>
spec:
bucketStart: <string> # RFC3339 UTC start of bucket window
expiresAt: <time> # When bucket can be pruned
nonces: # Optional; map of nonce digests
<hex-digest>:
acceptedAt: <time>
peerDigest: <string> # Short digest of authenticated peer

Fields Reference

FieldTypeRequiredDescription
spec.bucketStartstringYesRFC3339 UTC timestamp marking the start of the bucket's time window.
spec.expiresAttimeYesWhen the entire bucket can be pruned.
spec.noncesmap[string]NonceRecordNoMap of accepted nonce hex digests to their acceptance metadata.

Object Naming

nonce-<bucket-start-utc>

Example: nonce-2026-08-15t14-30-00z

Design Notes

  • Buckets are sharded by minute to limit object size
  • Nonces are SHA-256 digests — no raw identity material stored
  • Expired buckets are pruned automatically
  • Write-once per nonce; updates use JSON Patch

Short Names

# Get all ZenLocks
kubectl get zenlocks
kubectl get zl

# Get all ZenLockCustodies
kubectl get zenlockcustodies

# Get all NonceBuckets
kubectl get noncebuckets

API Discovery

# List all zen-lock CRDs
kubectl get crd | grep security.zen-mesh.io

# Describe a CRD
kubectl describe crd zenlocks.security.zen-mesh.io