Skip to content

Permissions

This is TOVIO's headline differentiator: some files in a shared repository can be readable only by the right people — enforced by mathematics, not by a server you have to trust. Anyone can clone the whole repo; the protected files stay ciphertext to anyone without clearance.

This page explains how that works conceptually — clear files versus policy-protected files, the three cryptographic tiers, and what the Key Authority is and, importantly, is not.

Phase note

The Phase 1 Tier-0/Tier-1 permission layer is implemented and exercised offline and over TLS in an authorized source checkout; no generally available binaries or packages have been published. The Tier-2 CP-ABE engine has passed its enterprise KA conformance and internal-review gate, but remains behind the separately licensed, default-off release boundary and is not generally available. Threshold/KMS/HSM behavior remains a later Enterprise evidence gate.

flowchart LR
    F["file at path P"] --> M{"policy manifest matches P?"}
    M -- no --> C["clear object<br/>(plaintext)"]
    M -- yes --> E["policy object<br/>(encrypted, DEK wrapped per identity)"]
    E -.-> R{"my identity satisfies policy?"}
    R -- yes --> D([✓ decrypt locally])
    R -- no --> X[["✗ opaque everywhere<br/>(even a full clone)"]]

More diagrams for the full permission and review flow: Permission & review workflows.

Clear files vs policy objects

Start from the default, because it's the common case: most files have no policy. They are stored in the clear — well, content-addressed and packed like any object, but not encrypted — and anyone with repository access can read them. You never think about keys or encryption. This is the experience for the overwhelming majority of a repository's files, and it should feel exactly like Git.

A policy is an access rule you attach to a path, for example config/production/**. The moment a path has a policy, files there become policy objects: they are automatically encrypted so that only identities who satisfy the policy can read them — even if someone clones the entire repository. You don't manage keys or run an encryption step by hand. You declare who should be able to read, and TOVIO does the rest.

Mental model

A .gitignored secret file plus an external secrets manager — but the file genuinely lives in the repo, syncs like everything else, and its protection is enforced by cryptography rather than by a server's access checks.

Encryption happens at snapshot time, not commit time

Because the working copy is continuously snapshotted with no staging area, a policy-protected path must be matched and encrypted as it is snapshotted — so plaintext never lands in a tracked tree even for a moment. This is a normative rule, not an optimization: it's how TOVIO guarantees a secret can't slip into history between edit and commit.

The three cryptographic tiers

The permission system has three tiers, chosen to fit the size and trust model of who you're working with. They share one envelope format, so moving up a tier adds a header type rather than re-encrypting your world.

No Key Authority. No ceremony. Content is encrypted with age semantics — ephemeral X25519 key agreement plus ChaCha20-Poly1305 — and the root of trust is your own key, generated silently at tovio init. The word "ABE" never appears. For a single developer, ABE would be the wrong tool for the job: there's only one principal, so there's nothing to express a policy about. Solo mode permanently and deliberately skips it.

A hybrid envelope, with a Key Authority as an authorization oracle. Each protected object gets a random Data Encryption Key (DEK); the content is encrypted with AES-256-GCM under that DEK. The DEK is then wrapped once per authorized recipient via X25519 — one small wrapped copy per person who's allowed to read.

  • Granting access = add a wrapped DEK copy for the new recipient.
  • Revoking access = rotate the DEK and re-wrap for the remaining recipients (re-encrypt on rotate — the same trade-off every envelope system, age included, makes).

CP-ABE behind the Enterprise boundary — attribute-based encryption where a policy expression like (role:sr-engineer AND clearance:production) OR (group:on-call AND incident:active) is evaluated cryptographically at decrypt time. This earns its heavier cost only with many principals and dynamic, policy-driven attributes. The enterprise KA implementation uses CIRCL TKN20 and has passed its conformance and internal-review gate. The public client keeps Enterprise crypto default-off, no release artifact enables it, and threshold/KMS/HSM authority remains a later profile.

Why one envelope for all three

The envelope format is ABE-forward. CP-ABE uses an abe recipient/header type in the same object structure, so enabling an accepted Enterprise profile does not require migrating every Tier-1 payload or re-encrypting public history. Tier 1 can currently be exercised from an authorized source checkout; it is not a generally available product release.

What the Key Authority is — and is not

The Key Authority (KA) is the part people most often misunderstand, usually by imagining it as more powerful than it is. So let's be precise.

The KA is progressive: it only exists when your collaboration model needs it. tovio init asks a single question to pick one of three collaboration modes, or takes the answer non-interactively as --mode simple|team|agentic. The Enterprise KA in the last row is a separately licensed profile, not a fourth --mode value:

Collaboration profile KA form What it does
Simple — --mode simple (solo) None No KA at all. Encryption (if any) uses your own key.
Team — --mode team Authorization oracle Maintains the identity-to-public-key registry; decides whose wrapped DEK copies are included for each policy. Never holds plaintext or content keys.
Agentic — --mode agentic Oracle + token issuer As Team, plus issues and validates agent capability tokens.
Enterprise — not an init mode CP-ABE KA; later threshold/KMS profile The CP-ABE KA is implemented behind the Enterprise release boundary. k-of-n and HSM/KMS authority remain later, evidence-gated profiles.

What the Key Authority IS

  • A registry of which identity owns which public key.
  • An authorization oracle: it decides whose wrapped DEK copies go into a policy object — i.e., who's on the allow-list.
  • Optional and progressive: a solo repo has none; it appears only when you first declare a policy or add a collaborator.
  • Offline-friendly: it's consulted only when reading or granting a policy-protected object. Public objects never touch it, and core VCS operations never require the network.

What the Key Authority is NOT

  • It is not a server that holds your secrets. In Tier 1 it never sees plaintext or content keys — only public keys and allow-list decisions.
  • It is not the thing that decrypts your files. Decryption happens on your machine with your key; the KA can't do it for you and can't do it to you.
  • It is not always-on. No KA mode requires the network for core version control.

The honest residual risk

There is one limit worth stating plainly, because TOVIO states it plainly itself. In Tier 1, the KA is trusted not to wrap a DEK for an unauthorized identity. The math stops the Forge and the network from reading your secrets, but a genuinely malicious Key Authority could add an attacker to the allow-list. Only Tier 2 (CP-ABE) closes that gap cryptographically, by embedding the policy in the ciphertext itself so even the authority can't grant access it shouldn't. This is a documented residual risk for the Tier-1 public profile. The Enterprise CP-ABE implementation is not a generally available mitigation until its release boundary and remaining commercial gates are accepted.

How this is not like a permissions server

The contrast with conventional access control is the whole point:

  • A conventional Git host's permission is a rule the server enforces. Bypass the server — clone a backup, compromise the host, subpoena the provider — and the file is right there in plaintext.
  • A TOVIO policy is enforced by encryption in the stored and synced object graph. The protected payload remains ciphertext on the Forge, in unauthorized clones, and in object backups. Authorized working copies, approved runner inputs, and explicitly disclosed agent context may contain plaintext and must be secured as separate endpoints.

That's why the Forge object store does not directly decrypt protected payloads.

Where to go next

Last reviewed September 9, 2026

Suggest an improvement to this page Not for security reports — see disclosure