You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+
## Project Overview
6
+
7
+
zerolease is a lightweight, agent-aware credential vault with lease-based access control, written in Rust. It's designed for AI agent orchestration environments where untrusted tools need time-bounded, scope-limited access to credentials. Supports deployment on developer laptops (Unix domain socket + OS keychain), QEMU VMs (TCP + token auth), and VM-isolated environments (vsock + AWS KMS).
8
+
9
+
**Status**: Early development — core traits, types, and multiple backend implementations are functional. The workspace includes storage backends for rusqlite, PostgreSQL, and AWS Secrets Manager.
Transport is a separate abstraction (`VaultListener`/`VaultConnector`) over Unix domain sockets, TCP, and vsock. Authentication is pluggable via the `Authenticator` trait.
49
+
50
+
### Request Flow
51
+
52
+
Agent -> Transport -> Handshake (ClientHello/ServerHello) -> Authenticator (PeerIdentity + token -> ConnectionIdentity) -> Vault -> PolicyEngine (deny-by-default, first-match) -> SecretStore (encrypted blob) -> decrypt with DEK -> create Lease + LeaseGuard -> AuditLog -> return LeaseGrant to agent.
53
+
54
+
### Key Design Decisions
55
+
56
+
-**Newtype IDs**: `SecretId`, `AgentId`, `LeaseId`, `SecretName`, `DomainScope` are all newtypes preventing accidental misuse at compile time. All UUID-based IDs use v7 (time-ordered).
57
+
-**Zeroize-on-drop**: Secret values use `SecretString`/`Zeroize`. `LeaseGuard` is not Clone, not Serialize, and redacts in Debug output.
58
+
-**Envelope encryption**: KMS-backed deployments use a local DEK encrypted by KMS, avoiding a KMS round-trip per secret operation.
59
+
-**DomainScope restriction**: Credentials are scoped to target domains (exact match, wildcard subdomain `*.example.com`, or localhost:port).
60
+
-**Policy model**: Deny-by-default, flat grant list, first-match-wins. Designed for auditability.
61
+
-**Transport↔Auth separation**: Transports provide `PeerIdentity` (UID/PID, CID, or token hash). The `Authenticator` maps this to `ConnectionIdentity` (role + agent binding). TCP transports include a bearer token in `ClientHello`.
62
+
-**Storage↔Audit decoupling**: `SecretStore` and `AuditLog` are independent — pick each backend separately. AWS SM provides only `SecretStore`; pair with `TracingAuditLog`.
63
+
64
+
### Feature Flags (core crate)
65
+
66
+
-`vsock` — enables tokio-vsock for VM communication (Linux only)
67
+
-`kms` — enables AWS KMS key source
68
+
69
+
### Code Quality Principles
70
+
71
+
- Idiomatic Rust. Clippy clean. Experienced Rust developers should feel at home.
72
+
- Prefer well-tested, well-established dependencies from known community members.
73
+
- Tidy, efficient code. Well-named variables and functions. Readable by humans and agents.
74
+
- Memory and CPU efficient — no needless clones. Compatible with the zeroclaw philosophy.
75
+
- Use Rust types to prevent bugs (newtypes, enums, exhaustive matching).
76
+
- A little macro-writing goes a long way for readability (`col!`, `parse_params!`, `json_response!`).
Copy file name to clipboardExpand all lines: README.md
+69-51Lines changed: 69 additions & 51 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,17 +12,45 @@ When AI agents use tools that need credentials — API tokens, SSH keys, databas
12
12
13
13
## Design
14
14
15
-
The vault is a single Rust process that agents connect to over Unix domain sockets (on developer machines) or vsock (in Firecracker/QEMU VMs). Credentials never leave the vault as plaintext over a network — the transport is local to the host or hypervisor.
15
+
The vault is a Rust library that agents connect to over Unix domain sockets (developer machines), TCP with token auth (QEMU VMs), or vsock (Firecracker). Credentials never leave the vault as plaintext over a network — the transport is local to the host or hypervisor.
16
16
17
17
**Encryption.** Secrets are encrypted at rest using `AES-256-GCM` or `XChaCha20-Poly1305` (configurable per secret, with algorithm migration support). The data encryption key is managed by a pluggable key source: OS keychain for developer machines, AWS KMS for production, or an environment variable for CI.
18
18
19
19
**Policy.** Access is deny-by-default. A flat list of grant rules specifies which agents can access which secrets for which domains. First match wins. The policy format is intentionally simple — easier to audit than a policy language.
20
20
21
21
**Leases.** Every credential access goes through a lease. Leases have a TTL, an optional use count, and a list of allowed target domains. The vault tracks active leases in memory, enforces per-agent caps, and garbage-collects expired ones. Secret values are zeroized from memory when the lease guard is dropped.
22
22
23
-
**Authentication.** Connections are authenticated via a pluggable `Authenticator` trait that maps transport-level peer identity to roles. Three roles exist: Admin (full access), Agent (bound to a single identity, can only use leases), and Orchestrator (trusted to assert agent identity per request, for systems like Slack bots acting on behalf of multiple users).
23
+
**Authentication.** Connections are authenticated via a pluggable `Authenticator` trait that maps transport-level peer identity to roles. Three roles exist: Admin (full access), Agent (bound to a single identity, can only use leases), and Orchestrator (trusted to assert agent identity per request). TCP transports present a bearer token in the handshake; UDS/vsock rely on OS-level identity.
24
24
25
-
**Audit.** Every lease grant, secret access, revocation, and policy denial is emitted as a structured `tracing` event (observable via any tracing subscriber) and optionally persisted to a queryable SQLite audit log.
25
+
**Audit.** Every lease grant, secret access, revocation, and policy denial is logged. The core crate includes `TracingAuditLog` (emits structured `tracing` events for external log aggregation). Queryable backends are available in the store crates.
26
+
27
+
## Workspace
28
+
29
+
zerolease is a Cargo workspace. The core crate defines traits; storage and provider crates are chosen at compile time.
TCP listeners bind to `127.0.0.1` only. The `TokenAuthenticator` maps pre-registered tokens to connection identities. Raw tokens are never stored — only SHA-256 hashes.
cargo +nightly fuzz run fuzz_read_frame -- -max_total_time=60
84
-
cargo +nightly fuzz run fuzz_protocol_deser -- -max_total_time=60
85
-
cargo +nightly fuzz run fuzz_domain_scope -- -max_total_time=60
102
+
# OS keychain integration test
103
+
cargo test -p zerolease keysource::keychain -- --ignored
86
104
```
87
105
88
106
## Wire protocol
89
107
90
-
The protocol is JSON over length-prefixed frames (4-byte big-endian length + payload). Each connection begins with a version handshake. Requests carry a UUID v7 identifier for correlation. Eight methods are supported: `store_secret`, `request_lease`, `access_secret`, `revoke_lease`, `revoke_all_for_agent`, `list_secrets`, `renew_lease`, `delete_secret`.
91
-
92
-
See the module documentation (`cargo doc --open`) for protocol details and type definitions.
108
+
JSON over length-prefixed frames (4-byte big-endian length + payload). Each connection begins with a `ClientHello`/`ServerHello` handshake (TCP clients include a bearer token). Requests carry a UUID v7 identifier for correlation. Eight methods: `store_secret`, `request_lease`, `access_secret`, `revoke_lease`, `revoke_all_for_agent`, `list_secrets`, `renew_lease`, `delete_secret`.
93
109
94
110
## Security
95
111
96
-
The vault has been through an adversarial security audit with all findings resolved:
97
-
98
-
- Secret material is zeroized on drop (`Zeroize`, `SecretString`, `Zeroizing<Vec<u8>>`)
99
-
- Decryption errors are generic (no information leakage about failure cause)
112
+
- Secret material zeroized on drop (`Zeroize`, `SecretString`, `Zeroizing<Vec<u8>>`)
113
+
- Decryption errors are generic (no information leakage)
- SQL injection prevented by parameterized queries
105
118
- Debug impls redact secret material
106
119
- Role-based access control prevents agents from calling admin operations
107
-
- Agent identity is bound at the transport level, not self-asserted
108
-
- Wire protocol fuzz-tested (~3.5 million executions, zero crashes)
120
+
- Agent identity bound at transport level, not self-asserted
121
+
- Auth tokens stored as SHA-256 hashes, never in plaintext
122
+
- TCP listener binds localhost only
123
+
124
+
## Status
125
+
126
+
Early development. Trait definitions and core types are stable. Concrete backend implementations are functional. Integration-level documentation and a standalone server binary are planned.
0 commit comments