ruvnet/ruflo · error

invalid-policy-trust-key

Error message

invalid-policy-trust-key

What it means

The per-project policy trust key file exists but its contents are not the expected 32 bytes — the key material is corrupted or was written by something other than the 32-byte randomBytes generator. HMAC authentication of the policy state is impossible with it, so trustKey() refuses to use it.

Source

Thrown at v3/@claude-flow/cli/src/services/policy-runtime.ts:88

  renameSync(temporary, file);
}

function trustPaths(projectRoot: string): { key: string; anchor: string } {
  const trustRoot = join(userInfo().homedir, '.config', 'ruflo', 'policy-trust');
  const projectId = createHash('sha256').update(realpathSync(projectRoot)).digest('hex');
  const dir = join(trustRoot, projectId);
  return { key: join(dir, 'anchor.key'), anchor: join(dir, 'state.anchor.json') };
}

function trustKey(projectRoot: string, create: boolean): Buffer | undefined {
  const { key } = trustPaths(projectRoot);
  if (!existsSync(key)) {
    if (!create) return undefined;
    mkdirSync(dirname(key), { recursive: true, mode: 0o700 });
    writeFileSync(key, randomBytes(32), { mode: 0o600, flag: 'wx' });
  }
  const material = readFileSync(key);
  if (material.length !== 32) throw new Error('invalid-policy-trust-key');
  return material;
}

function stateAuthentication(state: PolicyState, key: Buffer): string {
  return createHmac('sha256', key).update(JSON.stringify(state)).digest('hex');
}

function verifyStateAnchor(projectRoot: string, state: PolicyState | undefined): void {
  const { anchor } = trustPaths(projectRoot);
  if (!existsSync(anchor)) return;
  if (!state) throw new Error('policy-state-missing-for-anchored-project');
  const key = trustKey(projectRoot, false);
  if (!key) throw new Error('policy-trust-key-missing');
  const record = JSON.parse(readFileSync(anchor, 'utf8')) as { authentication?: string };
  const expected = stateAuthentication(state, key);
  const actual = record.authentication ?? '';
  if (!/^[a-f0-9]{64}$/.test(actual)
    || !timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(actual, 'hex'))) {

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Supply the correct policy trust key
  2. Regenerate and re-register the trust key if it has rotated

Example fix

Configure a valid policy trust key (correct format and provenance) before performing trust-sensitive policy operations.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at v3/@claude-flow/cli/src/services/policy-runtime.ts:88 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/eda95c9f5d674060. Report an issue: GitHub.