Read a permission error and act on it
TVO-PERM-001 and TVO-PERM-002, line by line.
Written By Dustin
Last updated About 3 hours ago
TOVIO never emits a bare "permission denied". Every permission refusal names the expression, your attributes, the specific missing one, and the command that diagnoses it. Learning to read the four lines makes most access problems a one-minute fix.
TVO-PERM-001 — a read was denied
✗ Cannot read config/production/api-keys.env This file is policy-protected. Reading it requires: role=senior AND clearance=secrets Your identity (did:tovio:dustin) has: role=staff, team=backend You are missing the attribute: clearance=secrets Diagnose: tovio access check config/production/api-keys.env Request access: tovio access request config/production/** --attr clearance=secretsRead it bottom-up. The missing attribute is the answer; the last line is already the exact command to ask for it.
TVO-PERM-002 — a write was rejected
Fires when a change modifies a path whose write policy is not ANY and your change cannot carry a satisfying signature. It also covers attempts to modify the policy manifest itself.
tovio access check --write config/production/tovio access request 'config/production/**' --write --attr clearance=secretsThe rest of your change is unaffected — only the protected path is blocked.
Exit codes, if you are scripting
Codes are grouped by area, not by individual error. A permission refusal exits 13 — that covers the PERM, TOKEN, LOCK and IDENT areas. Key and crypto failures (KEY, CRYPTO) exit 11. So branching on 13 catches "you are not allowed", and 11 catches "your key cannot do it" — two different fixes, and worth distinguishing in automation.
Branch on the code field rather than the exit status when you need to be precise; the error catalog in the documentation is the authority for both.
When the error is not about policy at all
The one cause no error can name
If tovio policy test says the expression is satisfied but reads still fail, the grant is almost certainly newer than the commit. Grants are prospective — the recipient reads a protected path from its next commit, not retroactively. Commit the path and try again.
Machine-readable
tovio --json access check <path>The JSON error carries code, cause, a remediation list of ready-to-run commands, and a context object naming what was required, what you hold, and what is missing. Script against those fields rather than parsing the human text.
Redact before you share this
A permission error is unusually revealing. Before pasting one into a ticket, a chat, or the public feedback board, remove:
- The file path — it maps your internal directory structure.
- Every DID —
did:tovio:…/did:key:…identifies a person. - The attribute names and values in
policy_requires,your_attributesandmissing— together these disclose your organisation's role, team and clearance vocabulary, which is a map of who can reach what.
The error code and the shape of the problem are enough for anyone helping you. Never paste repository content, and never paste a recovery phrase or a key file under any circumstances.
The authority
Every code, its exact wording and its remediation live in the error catalog in the documentation. This article teaches you to read one; the catalog is the system of record and will not drift.