avp

Alt Vault Protocol, an open zero-knowledge spec for sharing alts across clients.

AVP threat model

This document states what the Alt Vault Protocol defends against, what it deliberately does not, and the residual risks an operator or implementer should understand. It is informative; the normative contract is SPEC.md. To report a vulnerability, follow SECURITY.md.

AVP shares alt accounts across clients through a zero-knowledge, federated server. All cryptography happens on the client; the server stores only ciphertext, per-member wrapped keys, public keys, version and epoch counters, and opaque signatures. The threat model follows from that single design choice.

Assets

In rough order of sensitivity:

  1. The alt plaintext. The account credentials inside the encrypted payload (accessToken, and the username, uuid, bans, and provenance fields around it). This is what AVP exists to protect.
  2. The repository data key. The per-repo symmetric AES-256 key that encrypts the payload. Anyone who holds it can read every alt in the repo.
  3. Member private keys. Each member’s Ed25519 identity key (authenticates, and is the member id) and X25519 key (unwraps the data key).
  4. Bearer tokens. Short-lived, per-host credentials that authorize vault operations.
  5. Metadata. The membership roster (public keys), repository sizes, and access patterns. Lower value, and partly exposed to the server by design (see Non-goals).

Actors and trust boundaries

Adversaries

A1. Passive network observer

Capability: reads traffic between client and server.

Defended: payloads and wrapped keys are encrypted (AES-256-GCM, X25519 + HKDF wrap); the data key and plaintext never appear on the wire. Transport MUST be TLS, so even the ciphertext envelope and bearer tokens are not exposed in transit.

Residual: without TLS, an observer sees ciphertext, public keys, counters, and bearer tokens. TLS is mandatory for exactly this reason.

A2. Active network attacker (MITM)

Capability: intercepts, modifies, replays, or reorders messages.

Defended: authentication is an Ed25519 challenge over a single-use, short-TTL nonce, so a captured auth exchange cannot be replayed. Every payload binds (repoId, payloadVersion, keyEpoch) into the AES-GCM AAD, so an envelope cannot be replayed under a different repository, version, or epoch without failing authentication. Tampering with ciphertext fails the GCM tag.

Residual: an attacker who also controls or impersonates the server is covered by A4. Bearer tokens are themselves bearer credentials, so TLS plus short token lifetimes are required to limit a capture-and-reuse window (see A8).

A3. Honest-but-curious server

Capability: sees and stores everything the protocol sends it, and tries to learn the alts.

Defended: zero-knowledge is an invariant (SPEC §10). After a create and push, no stored value decodes to a plaintext alt field. The server holds ciphertext, base64 wrapped-key blobs, raw public keys, counters, and opaque signatures, and can decrypt none of it. Provenance (sourceClient, sourceUser) lives inside the encrypted payload, so cross-client attribution does not weaken this.

Residual: the server learns metadata: the membership roster (a set of public keys), repository and payload sizes, and the timing and frequency of operations. AVP does not hide this from the server it talks to. See Non-goals.

A4. Malicious server

Capability: in addition to A3, returns wrong, stale, or withheld data, and serves chosen key material.

Defended: it still cannot read or forge plaintext (it has no data key). Against the specific attack of serving a wrong X25519 key for a member (to trick an inviter into wrapping the data key to an attacker), §9 key binding defends: the IdP signs each member’s two public keys, and a joiner verifies the binding before wrapping. This verification SHOULD be done always and MUST be done when the repository’s host is one the client does not itself operate.

Residual: a malicious server can still attack availability and freshness. It can withhold updates, serve a stale but validly-encrypted manifest and envelope, or refuse service. The monotonic payloadVersion and the epoch-bound AAD let a client detect a rollback of content it can compare against, but a client with no independent reference cannot, on its own, distinguish “no newer version exists” from “the server is hiding it.” Detecting equivocation or stale-state attacks requires out-of-band comparison or version pinning, which AVP does not currently specify.

A5. Malicious or careless member (insider)

Capability: a current member with the data key.

Defended: nothing, by design, with respect to the contents of their own repository. Membership is the trust boundary: every member can decrypt every alt. Integrity of writes is bounded by optimistic concurrency (a member cannot silently clobber a concurrent write).

Residual: a member can exfiltrate every alt they can see, and under the v1 policy any member may invite another (the addMember authorization is “any member”). Treat repository membership as a full grant of read access to everything in that repository, present and future, until the member is removed.

A6. Removed member

Capability: a former member who retains keys and anything they previously pulled.

Defended: removeMember rotates the data key to a new epoch and re-wraps it only to the remaining members. The removed member’s old wrapped key cannot derive the new epoch’s data key, and the epoch in the AAD makes a stale-epoch envelope fail authentication. They lose access to all future writes.

Residual: there is no backward secrecy. A removed member keeps every alt they already decrypted while a member. Rotation protects new data, not old. Rotate credentials (the alts themselves) out of band if a departure requires revoking access to data already shared.

A7. Compromised IdP

Capability: controls token issuance and key-binding signatures.

Defended: the IdP is an explicit trust anchor, not an attacker AVP defends against. It is the smallest sensible anchor: tokens carry only sub and kind, with no account or role claims, and a vault server authorizes purely on membership.

Residual: a compromised IdP can mint a token for any identity (authenticating as anyone at the transport layer) and can forge key bindings, defeating the A4 defense. In the current single-issuer model a repository trusts one IdP, named out of band in the repo locator. Cross-issuer trust (pinned-issuer sets, web-of-trust) is deferred (SPEC §12). Run the IdP with the same care as any signing authority, and rotate its key set if it is suspected compromised.

A8. Stolen bearer token

Capability: possesses a valid, unexpired token.

Defended: tokens are scoped to a single host and to the bearer’s repository memberships, and are short-lived. They never leave TLS.

Residual: until it expires, a stolen token impersonates its subject at that host. Keep token TTLs short and transport encrypted; a longer TTL is a longer theft window.

A9. Stolen member private key

Capability: possesses a member’s Ed25519 and/or X25519 private key.

Defended: out of scope for the protocol (see Non-goals); how a client stores keys at rest is a client concern.

Residual: whoever holds the Ed25519 key can authenticate as that member; whoever holds the X25519 key can unwrap every data key wrapped to that member. A stolen private key is a full member compromise and is handled the same as A5 plus removal (A6) once detected.

Cryptographic assumptions

AVP assumes the standard security of its primitives and their correct, side-channel-aware implementation:

Non-goals

AVP deliberately does not provide:

Residual risks and open items

These are tracked as open items in SPEC.md §12 and are the most useful places to contribute a security review:

Found something exploitable? Please follow SECURITY.md rather than opening a public issue.