ruvnet/ruflo · error · Error
approval issuance requires an authenticated human identity a
Error message
approval issuance requires an authenticated human identity adapter; the local TTY is not an identity credential
What it means
The `policy approve` operation ALWAYS throws this — it is intentionally unimplemented. Per ADR-324, approval issuance requires a genuine authenticated human identity (an identity adapter), and a local TTY does not constitute an identity credential. The CLI deliberately refuses to mint approvals from a terminal to prevent privilege escalation via whoever happens to be at the keyboard.
Source
Thrown at v3/@claude-flow/cli/src/commands/policy.ts:89
});
}
if (operation === 'evaluate') {
return print(await evaluatePolicyRequest(argJson<PolicyRequest>(args[1], 'evaluate'), root));
}
if (operation === 'rule' && args[1] === 'add') {
requireInteractiveAdministrator();
const rule = argJson<PolicyRule>(args[2], 'rule add');
await upsertPolicyRule(rule, root);
return print({ success: true, ruleId: rule.id });
}
if (operation === 'budget' && args[1] === 'set') {
requireInteractiveAdministrator();
const budget = argJson<BudgetLimit>(args[2], 'budget set');
await setPolicyBudget(budget, root);
return print({ success: true, budgetId: budget.id });
}
if (operation === 'approve') {
throw new Error(
'approval issuance requires an authenticated human identity adapter; '
+ 'the local TTY is not an identity credential',
);
}
if (operation === 'revoke') {
requireInteractiveAdministrator();
if (!args[1]) throw new Error('revoke requires an approval id');
return print({ success: await revokePolicyApproval(args[1], root), approvalId: args[1] });
}
if (operation === 'audit') {
const state = loadPolicyState(root);
return print({ receipts: state.receipts });
}
if (operation === 'verify') return print(await verifyPolicyLedger(root));
throw new Error(`unknown policy operation: ${operation}`);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
output.printError(message);View on GitHub (pinned to 6b01dc5a68)
Solutions
- Do not call `policy approve` from the CLI — it is unsupported by design.
- Obtain approvals through the authenticated identity adapter path referenced in ADR-324 (e.g. an external identity provider / policy service), not the local terminal.
- If you only need to remove an existing approval, use `policy revoke <id>` from an interactive terminal instead.
Example fix
// before ruflo policy approve action-123 // after — approvals are issued via the identity adapter, not the CLI # revoke (the supported interactive inverse) works: ruflo policy revoke approval-abc
Defensive patterns
Strategy: validation
Validate before calling
// The approve operation is intentionally unsupported. Block it in your dispatcher.
const UNSUPPORTED_POLICY_OPS = new Set(['approve']);
function dispatchPolicy(op: string): void {
if (UNSUPPORTED_POLICY_OPS.has(op)) {
throw new Error(`policy '${op}' is unsupported from the CLI; use the identity adapter (ADR-324)`);
}
} Type guard
const isCliSupportedPolicyOp = (op: string): boolean => !['approve'].includes(op) && ['init','migrate','status','rule','budget','revoke','audit','verify'].includes(op);
Try / catch
// No retry — this branch throws unconditionally. Treat as a programming error.
if (op === 'approve') {
throw new Error('do not call policy approve from the CLI; route through the identity adapter');
} Prevention
- Never call `policy approve` — by design it always fails.
- Issue approvals only through the authenticated identity adapter path.
- Use `policy revoke` for the interactive inverse.
When it happens
Trigger: Calling `ruflo policy approve <anything>` from any context. The branch is unconditional; it throws before any argument parsing for the approve subcommand.
Common situations: Operators expecting a manual override command, scripts trying to pre-approve an action, or assuming approval is symmetric with revoke (which IS supported interactively).
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- policy administration requires an interactive local terminal
- policy-${decision.enforcedOutcome}:${decision.reason}; recei
- --token-stdin: no input received on stdin
- ${label} requires a JSON argument
- ${label} must be valid JSON
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/038ae0bcad96a5f4.
Report an issue: GitHub.