The production problem
Policy files are high-impact config. They decide deny, approval, throttle, and allow behavior for autonomous jobs. Treating them like unsigned text files is a control gap.
If an attacker or misconfigured pipeline changes policy bytes, your enforcement logic changes instantly. No code deploy is required. That makes policy integrity a first-class security boundary.
Signature verification closes this gap only when enforced, monitored, and rotated correctly.
What top results miss
| Source | Strong coverage | Missing piece |
|---|---|---|
| RFC 8032 (EdDSA: Ed25519 and Ed448) | Algorithm and verification behavior for Ed25519 digital signatures. | No operational playbook for policy reload paths in autonomous AI control planes. |
| Sigstore verify docs | Signature verification workflows, identity constraints, and offline bundle verification. | No guidance for runtime policy file verification before in-process policy evaluation. |
| TUF specification | Signed metadata model, role separation, and threshold-based trust management. | No direct mapping to hot-reloaded policy engines with environment-driven key material. |
The missing part is policy-engine runtime behavior: exactly when verification runs and what fails closed during reload.
Signing workflow model
| Stage | Objective | Failure mode |
|---|---|---|
| Build policy artifact | Generate deterministic policy file bytes | Non-deterministic formatting causes signature mismatch |
| Sign policy bytes | Apply Ed25519 private key signature to exact file content | Signing transformed bytes (newline/encoding drift) fails verification |
| Distribute public key | Expose trusted verifier key to runtime via env/config | Missing or malformed key blocks policy load in required mode |
| Verify before parse | Reject unsigned or invalid policies before evaluation pipeline | Late verification can allow temporary unsafe policy use |
| Rotate keypair safely | Roll new key and signatures atomically with rollback plan | Key/signature skew causes startup or reload failures |
Cordum runtime behavior
| Boundary | Current behavior | Operational impact |
|---|---|---|
| Signature requirement | Verification required in production or when `SAFETY_POLICY_SIGNATURE_REQUIRED=true`. | Prevents unsigned policy from entering evaluation path in hardened environments. |
| Public key source | `SAFETY_POLICY_PUBLIC_KEY` accepts base64/hex raw Ed25519 public key. | Operator controls trust root at deployment level. |
| Signature source order | Kernel checks `SAFETY_POLICY_SIGNATURE`, then `SAFETY_POLICY_SIGNATURE_PATH`, then `<policy-file>.sig` fallback. | Supports inline, detached-file, and local file-based workflows. |
| Verification checks | Code validates key/signature length and runs `ed25519.Verify` over exact policy bytes. | Rejects malformed key material and tampered policy artifacts early. |
| Load pipeline order | `loadPolicyBundle` reads source, verifies signature, then parses policy and computes snapshot hash. | No snapshot or policy object is produced for unsigned/invalid payloads. |
Implementation examples
Minimal signing tool (Go)
// sign_policy.go
package main
import (
"crypto/ed25519"
"encoding/base64"
"fmt"
"os"
)
func main() {
policy, _ := os.ReadFile(os.Args[1])
priv, _ := os.ReadFile(os.Args[2]) // raw 64-byte Ed25519 private key
sig := ed25519.Sign(ed25519.PrivateKey(priv), policy)
fmt.Println(base64.StdEncoding.EncodeToString(sig))
}Verification path (Go)
func verifyPolicySignature(data []byte, source string) error {
pubRaw := strings.TrimSpace(os.Getenv("SAFETY_POLICY_PUBLIC_KEY"))
requireSignature := env.IsProduction() || env.Bool("SAFETY_POLICY_SIGNATURE_REQUIRED")
if pubRaw == "" {
if requireSignature {
return errors.New("policy signature required but SAFETY_POLICY_PUBLIC_KEY not configured")
}
return nil
}
pubKey, _ := decodeKey(pubRaw)
sig, _ := readSignature(source)
if !ed25519.Verify(ed25519.PublicKey(pubKey), data, sig) {
return errors.New("policy signature verification failed")
}
return nil
}Rotation runbook
# 1) Configure verifier key and strict mode export SAFETY_POLICY_SIGNATURE_REQUIRED=true export SAFETY_POLICY_PUBLIC_KEY="<base64-or-hex-ed25519-pubkey>" # 2) Provide detached signature export SAFETY_POLICY_SIGNATURE_PATH=/etc/cordum/policy.sig # 3) Restart safety kernel and verify no signature errors kubectl logs deploy/cordum-safety-kernel -n cordum | grep -E "signature|policy updated" # 4) Rotation drill # - sign with new private key # - roll new public key + new signature together # - validate reload # - keep old key only for rollback window
Limitations and tradeoffs
- - Signature enforcement improves integrity but adds key management overhead.
- - Failed verification can block policy reload and temporarily preserve older policy snapshot.
- - Inline env signatures are convenient but increase secret-handling risk in deployment pipelines.
- - Fast key rotation requires disciplined artifact handling and rollback rehearsal.
If signature checks are optional in production, attackers only need one path to unsigned policy injection.
Next step
Run this hardening sequence this week:
- 1. Enable required signature mode in production environments.
- 2. Add CI step that signs policy bundle and publishes detached signature artifact.
- 3. Add startup and reload alerts for signature verification failures.
- 4. Execute a full key rotation drill with rollback timer and success criteria.
Continue with Policy Decision Cache Invalidation and LLM Safety Kernel.