Principles
1
No plaintext at rest
Credentials are always encrypted in the database — XChaCha20-Poly1305 for zero-knowledge items, AES-256-GCM for server-managed items.
2
No decrypt before auth
Authentication, permission, expiry, locality, and storage-mode checks all run before any decryption.
3
No implicit access
Every agent–credential pair requires an explicit permission row. There are no wildcards, no roles, no inheritance.
4
No silent access
Every attempt — allowed, denied, expired, revoked — is appended to the audit log before the response is returned.
5
No secret exposure to LLMs
MCP tools inject secrets into subprocesses, never into model context.
Encryption modes
abadge supports two storage modes with distinct trust models.- Zero-knowledge
- Server-managed
The server never sees plaintext. All cryptographic operations happen in the browser or the local CLI daemon.
The server stores: wrapped root key, KDF salt + parameters, wrapped DEKs, and ciphertext. None of these is enough to decrypt without the master password (or recovery key).Recovery: a 256-bit recovery key (base32, shown once) independently wraps the root key. There is no server-side recovery.See Zero-knowledge encryption for the full hierarchy.
Comparison
Authentication
Human operators
The CLI never persists a human bearer token to disk.
Agents
Agents authenticate with Ed25519 public-key sessions — the only agent auth method. The agent generates an Ed25519 keypair locally; the server stores only the public key. For each session:POST /v1/agents/{agentId}/sessions/challenge → sign → POST /v1/agents/{agentId}/sessions/exchange → receive abs_... token (15-minute TTL). The SDK refreshes at T-2 minutes. The abs_... session token is the only credential that reaches the access.* surface.
Personal API keys (management surface). Users can mint personal API keys (abu_) from the dashboard org Settings page to script the management surface without a browser. An abu_ key resolves to a session identity, not an agent: it reaches only the management surface (organizations, profiles, items metadata, agents, permissions, audit, settings) and is structurally barred from access.* — it can never read a secret as an agent, and can never decrypt a zero_knowledge item (the server never holds the key). Like any account owner, it can owner-reveal its own server_managed plaintext via items.ownerReveal (the server holds those keys by design). The server stores a SHA-256 hash + 8-char prefix; the secret is shown once. Keys support an optional expiry and can be revoked.
Bearer resolution order on every request:
- Session cookie / bearer token → operator session (management surface)
abu_prefix → personal API key (prefix lookup, hash match) → session identity, management surface onlyabs_prefix → agent session token (hash lookup, TTL check) → agent identity (the only path toaccess.*)
Authorization
Access requires an explicit(agent, item, capability) permission row. There are no wildcards, no role-based inheritance, and no implicit grants.
The full decision flow is in Permissions and capabilities.
Delivery modes
- Environment injection
- File mounting
- Direct reveal
- MCP tools
use with delivery: env. The CLI or daemon spawns a subprocess with the secret in an env var. The secret lives only in process memory; the parent process drops the value after spawn.Network security
Credential handling on disk
Server breach impact
ZK items remain protected after a full server breach, assuming a strong master password. Server-managed items are exposed if the attacker also obtains the Worker’s
ENCRYPTION_KEY.
Stored data summary
Explicit non-goals (v1)
These are not protected against:- Local root/admin attackers reading process memory
- HSM or hardware-key integration
- Secure multi-party computation for shared secrets
- Tamper-evident audit log chaining
- Compromised build/deploy pipelines serving malicious JS
- Organization-level vault cryptography (each profile has its own root)