ruvnet/ruflo · error
ProofChain requires an explicit signingKey — hardcoded defau
Error message
ProofChain requires an explicit signingKey — hardcoded defaults are not secure
What it means
ProofChain's constructor requires a non-empty signingKey because every envelope in the tamper-evident hash chain is HMAC-signed with it — a hardcoded default key would let anyone forge envelopes and defeat the entire design, so the class fails fast instead. The factory createProofChain({ signingKey }) has the same requirement. Empty string, undefined, or null all trigger this.
Source
Thrown at v3/@claude-flow/guidance/src/proof.ts:136
// ============================================================================
// ProofChain
// ============================================================================
/**
* A tamper-evident, hash-chained sequence of ProofEnvelopes.
*
* Each envelope links to the previous one via `previousHash`, forming
* a blockchain-like structure. Every envelope is HMAC-signed so any
* modification to the chain can be detected.
*/
export class ProofChain {
private envelopes: ProofEnvelope[] = [];
private readonly signingKey: string;
constructor(signingKey: string) {
if (!signingKey) {
throw new Error('ProofChain requires an explicit signingKey — hardcoded defaults are not secure');
}
this.signingKey = signingKey;
}
/**
* Append a new ProofEnvelope to the chain.
*
* @param runEvent - The RunEvent to wrap
* @param toolCalls - Tool call records from the run
* @param memoryOps - Memory operations from the run
* @param metadata - Optional metadata overrides
* @returns The newly created and signed ProofEnvelope
*/
append(
runEvent: RunEvent,
toolCalls: ToolCallRecord[] = [],
memoryOps: MemoryOperation[] = [],
metadata?: Partial<ProofEnvelopeMetadata>,View on GitHub (pinned to fa13ee4ad6)
Solutions
- Generate a strong secret, e.g. openssl rand -hex 32, and pass it explicitly to the constructor
- Load the key from a secret manager or environment variable and validate it at startup before constructing the chain
- Fail fast with a clear config error if the key is missing rather than defaulting or falling back
- Never commit the key; rotate by re-verifying and re-exporting chains under the new key if rotation is required
Example fix
// before
const chain = new ProofChain(process.env.PROOF_KEY); // undefined if unset -> throws
// after
const signingKey = process.env.PROOF_SIGNING_KEY;
if (!signingKey || signingKey.length < 32) {
throw new Error('PROOF_SIGNING_KEY must be set to a >=32-char secret');
}
const chain = new ProofChain(signingKey); Defensive patterns
Strategy: validation
Validate before calling
const signingKey = process.env.PROOF_SIGNING_KEY;
if (!signingKey || signingKey.trim().length < 32) {
throw new Error('PROOF_SIGNING_KEY is missing or too weak; generate with: openssl rand -hex 32');
}
const chain = new ProofChain(signingKey); Type guard
function isValidSigningKey(key: unknown): key is string {
return typeof key === 'string' && key.trim().length > 0;
} Prevention
- Generate keys with openssl rand -hex 32 and store them in a secret manager
- Validate secret presence in CI/smoke checks so misconfiguration surfaces before runtime
- Never fall back to a default or empty key; the constructor's fail-fast is the security control
When it happens
Trigger: new ProofChain('') or new ProofChain(undefined as any); reading the key from an unset environment variable; tests constructing the chain without injecting a secret; config loading that silently yields '' for missing values.
Common situations: Missing PROOF_SIGNING_KEY-style env var in CI or a new environment; .env files not loaded before construction; deployment manifests that omit the secret reference.
Related errors
- ArtifactLedger requires an explicit signingKey — hardcoded d
- ConformanceRunner requires an explicit signingKey
- EvolutionPipeline requires an explicit signingKey — hardcode
- TruthAnchorStore requires a signingKey in config. Anchors ca
- INVALID_SECRET_LENGTH
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/2c8cbeb3cb06868a.
Report an issue: GitHub.