The mfa.* family (2 verbs). Every verb enters through the one front door: it is capability-checked, permission-checked, scope-checked and audited before it runs (see Security & permissions). Each entry below lists its capability, risk class (which fixes the minimum autonomy level), the minimum caller permission, its availability tier, whether it is idempotent, and any outbound egress.
Enrollmfa.enroll
| Property | Value |
|---|---|
| Capability | actor.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
, Sensitive ([2026] CC-OPBOX 30). Enrol the ACTING actor in TOTP MFA:
generate a 20-byte secret, AEAD-encrypt it (INV-7, AAD-bound to the actor), store it, and return the
base32 secret + the otpauth:// provisioning URI for the authenticator. The secret is returned ONCE here
(enrolment); never by a read verb. Re-enrol overwrites with a fresh secret. Self only (the acting actor).
Call POST /v/mfa.enroll with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool mfa.enroll.
Verifymfa.verify
| Property | Value |
|---|---|
| Capability | actor.read |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
([2026] CC-OPBOX 30). Verify a TOTP code against the ACTING actor’s
enrolled secret (a +/-1 window skew tolerance, RFC 6238). Reads + decrypts the secret to check; does NOT
return it, and does NOT gate anything (the enforcement fork is reserved). { code } -> { verified }.
Call POST /v/mfa.verify with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool mfa.verify.