What Cloak's daemon actually does — and what lives in the vault
Cloak is an open-source, local-first secrets layer for MCP-based AI agents whose defining behavior is that an agent can use a stored credential without the model ever receiving its raw value. In Cloak v1.1.2 , an agent can call the Stripe API without the model ever seeing STRIPE_SECRET_KEY: a background daemon attaches the credential to the outbound request and returns only the upstream HTTP response, not the key. That separation is the whole product.
The work is split across two local components. cloakd — the daemon — owns the encrypted vault, policy enforcement, the outbound HTTPS calls, and the audit log. cloak-mcp — the MCP bridge — exposes only metadata and proxy calls to the calling process (Claude Desktop, Cursor, Codex, and similar). The model can request "proxy this request authenticated with STRIPE_SECRET_KEY," but the secret itself stays inside cloakd.
It ships as cloakward/cloak under Apache-2.0, with v1.1.2 released June 18, 2026, and the repo showing 15 stars and 148 commits at review time . It is local-only: no account, no cloud sync, no telemetry .
The timing is not accidental. The official MCP 2025-06-18 spec warns that the protocol itself cannot enforce authorization and that implementors must build access controls in code . Cloak is one concrete implementation of the separation-of-authority pattern that fills that gap.
cloakd is a separate binary — and why Cloak's threat boundary depends on it

Cloak's threat boundary is enforced by process separation: three distinct binaries split the work so the model-facing component never touches the vault. The chain is cloak (the CLI/admin tool), cloak-mcp (the MCP bridge the model talks to), and cloakd (the daemon that alone owns the encrypted vault, policy checks, the audit log, and outbound HTTPS) . cloak-mcp reaches cloakd only over local IPC (a Unix domain socket), so a compromised bridge cannot read secrets directly — it can only ask the daemon to act .
That boundary holds only if the daemon trusts who it is talking to, so cloakd authenticates the calling peer before issuing any session token. It pins the installed cloak and cloak-mcp binaries by hash; substituting either binary produces fail-closed behavior rather than a silent grant . Peer authentication is OS-specific: on macOS it uses audit tokens and CodeDirectory hashes, while on Linux it requires SO_PEERPIDFD, available in kernel 6.5 and later — older kernels fail closed .
Once a peer is verified, the daemon issues a session token of 32 random bytes, base64url-encoded, with a 30-minute default TTL . Policy is evaluated before any vault read, and denied calls are written to the audit log without decrypting the stored value — the secret never leaves its sealed state on a rejected request .
| Binary | Role | Touches the vault? |
|---|---|---|
cloak | CLI / admin (setup, import, allow/deny) | No — instructs the daemon |
cloak-mcp | MCP bridge, model-facing | No — forwards requests over UDS |
cloakd | Daemon: vault, policy, audit, outbound HTTPS | Yes — sole owner |
The design choice is that authority lives in one auditable process. A prompt-injected agent can still ask cloakd to perform allowed actions, but it cannot bypass cloakd to read raw values — and any tampering with the binaries that talk to it trips the fail-closed path .
Why Cloak has no get_secret — and what the callable functions do instead
Cloak exposes no get_secret, read_secret, or vault.show because the model never needs the raw value to act on it. The documented v1.x MCP surface is exactly six callable tools, and every one returns metadata, computed headers, an upstream response, a derived credential, or an audit entry — never a stored secret . The agent asks cloakd to do something with a credential; it does not ask to see one.
| Tool | What it returns | Raw value exposed? |
|---|---|---|
list_secret_names | Names only | No |
get_secret_metadata | Metadata (type, host scope) | No |
sign_request | Computed auth headers | No |
proxy_authenticated_http_request | Upstream HTTPS response | No |
mint_short_lived_token | Derived short-lived credential | Yes — by design |
query_audit | Audit-log entries | No |
The proxy is the workhorse: proxy_authenticated_http_request supports bearer, basic, and custom-header auth modes, but query-string auth is explicitly disabled because URLs commonly land in server logs . mint_short_lived_token is the deliberate exception — it can hand a derived value back to the MCP client. AWS STS is implemented; GitHub App and GitLab PAT schemas exist but return not-supported errors in the v1.x surface .
"Extensible functionality should be handled in code, not exposed to the model" — a principle Cloak operationalizes by keeping authority in tools that act rather than tools that reveal (source: Cloak MCP tools spec).
Capability alone is not authority. Every stored value starts denied; access is granted per-name, per-host with cloak allow <name> <host> and revoked with cloak deny . So an agent can hold all six tools and still reach nothing until you scope a key to a host. v1.1.0 (June 11, 2026) added policy hot-reload with fail-closed handling of malformed policy files, so a broken rule denies rather than silently opens access .
Vault encryption: XChaCha20-Poly1305, Argon2id, and a BIP-39 recovery seed

The vault is a SQLite WAL database with per-record AEAD sealing using XChaCha20-Poly1305-IETF, with per-record subkeys derived through Argon2id and libsodium . The practical consequence: the on-disk file alone is not enough to mount an offline attack. A keychain-backed pepper sits outside the database, so a stolen SQLite file cannot be dictionary-attacked without also extracting the OS keychain item — two separate compromises, not one .
Recovery is deliberately unforgiving. At vault creation Cloak shows a 24-word BIP-39 seed exactly once, and there is no secondary recovery path — lose the seed and the encrypted records are unrecoverable . That is a design choice, not an oversight: a backdoor recovery mechanism would be a second attack surface against the same secrets.
Outbound HTTP is owned entirely by the daemon via reqwest/rustls. Redirects are disabled, a 30-second total timeout applies, and an SSRF backstop rejects loopback, private, link-local, cloud metadata-service, and ULA destinations — even under DNS-rebinding against an otherwise allowlisted hostname . So a poisoned DNS answer cannot redirect an authenticated request at `169.254.169.254` to lift cloud credentials.
Audit entries are hash-chained JSONL, and `cloak audit verify` detects mutated, deleted, or reordered lines . That gives you tamper-evidence on the record of which secret reached which host.
"There has been no third-party security audit." — Cloak project, THREAT_MODEL.md (source: cloakward/cloak)
The cryptographic stack is credible and specific, but its strongest assurances still live in the project's own repository and tests rather than an external review .
macOS and Linux only — no Windows daemon installer in v1.1.2
Cloak ships as a platform-specific binary set, and as of v1.1.2 it runs only on macOS and Linux — there is no Windows daemon installer . The release matrix covers five build rows: macOS arm64, macOS x86_64, Linux glibc x86_64, Linux musl x86_64, and Linux glibc arm64 . Because the threat boundary depends on the daemon owning HTTPS, where cloakd can actually start matters as much as the crypto behind it.
Signing and provenance are not uniform across those rows. Every release carries cosign keyless signatures and SLSA L3 provenance, and macOS stable builds are additionally Developer ID-signed and notarized . The two non-mainline Linux tiers are also thinner: Linux musl x86_64 and Linux glibc arm64 ship the CLI and daemon binaries only — the MCP bridge binary is not bundled in those tiers, so the agent-facing path is not turnkey there .
| Build row | Daemon + CLI | MCP bridge binary | Notarized |
|---|---|---|---|
| macOS arm64 / x86_64 | Yes | Yes | Yes (stable) |
| Linux glibc x86_64 | Yes | Yes | — |
| Linux musl x86_64 | Yes | No | — |
| Linux glibc arm64 | Yes | No | — |
| Windows | No | No | — |
On Windows, cloakd refuses to start, tracked as issue #2, and no installer artifacts are published . npm publishing is also paused until audited native binaries exist per platform, so there is no npx shortcut yet . Where it does run, cloak setup auto-detects Claude Desktop, Claude Code, Cursor, Windsurf, Continue.dev, Zed, and Codex and wires the MCP config for you .
Injection persists — here's the honest gap in Cloak's protection

Cloak removes raw stored values from model context, but it does not make a hijacked calling process harmless. The separation-of-authority design keeps long-lived keys out of the model and provider logs; it does not neutralize a prompt-injected agent that already holds a valid session. That agent can still invoke every allowed proxy function, spend real money on proxy_authenticated_http_request calls, and mutate remote state through authenticated requests it is permitted to make . The vault stays sealed; the blast radius of an allowed action does not shrink.
Two surfaces are visible to the MCP client by design. mint_short_lived_token returns a derived credential to the caller — its AWS STS path surfaces minted STS credentials directly in the response — and proxied HTTP responses return upstream payloads, which can themselves contain sensitive data . These are intentional escape hatches, not leaks, but they mean an attacker who controls the agent can read whatever those tools legitimately return.
The threat model is explicit about what sits outside the boundary: root or kernel compromise, malicious same-user apps reading process memory or keychain items, user-pasted secret values, side channels, and any multi-tenant or network-exposed daemon configuration .
"There has been no third-party security audit." — Cloak threat model (source: THREAT_MODEL.md)
That candor matters as of v1.1.2, dated June 18, 2026 . The strongest claims — AEAD sealing correctness, peer pinning, SSRF backstops — live in the project's own repo and tests. The cosign-keyless signing and SLSA L3 provenance documented in the release process address supply-chain integrity, proving the binary you install matches the source . They say nothing about whether the vault implementation itself is correct. The practical posture follows from Cloak's own invariants: enforce strict host allowlists, prefer short-lived scoped credentials, watch the hash-chained audit log, and require manual review for high-risk actions.
Infisical, Runloop, and Aegis: other daemon-proxy implementations in the space
Cloak is not the only project removing raw secrets from agent context — the same separation-of-authority pattern is appearing across several independent tools, each with a different deployment model. The shared idea is consistent: a broker process owns the real credential and attaches it at the network boundary, so the model only ever sees a placeholder or the upstream response. Where these tools diverge is hosting (local-first vs. cloud), licensing (open-source vs. commercial), and whether they ship a vault encryption layer at all.
Infisical's Agent Vault is a credential-broker proxy that swaps dummy tokens for real credentials on outbound calls . The mechanism mirrors Cloak's proxy_authenticated_http_request, but the deployment is hosted rather than local-first, which trades the laptop threat model for centralized management. Runloop's Agent Gateway takes a similar runtime-injection approach as a commercial, hosted service, injecting credentials at the network boundary rather than exposing them to the agent .
Aegis is the closest analogue: an open-source MCP credential-isolation proxy that injects auth headers at the network boundary, comparable in scope to Cloak but without the per-record vault encryption — no XChaCha20-Poly1305, Argon2id, or BIP-39 recovery seed. That is the line that distinguishes Cloak : it pairs the proxy pattern with a sealed local vault, where the others largely stop at the boundary.
The convergence extends beyond products. A March 2026 arXiv healthcare paper independently describes credential-proxy sidecars that keep containerized agent workloads from reading raw secrets — academic and commercial work arriving at the same control without coordination. The takeaway for anyone choosing a tool: decide on hosted vs. local-first and whether you need vault-grade encryption, then enforce strict host allowlists and short-lived credentials regardless of which proxy you pick. The pattern is settling; the implementations are not yet interchangeable.
Frequently asked questions
Does Cloak prevent a compromised MCP agent from spending money or calling external APIs?
No. Cloak keeps raw stored values out of model context, but it does not neutralize a hijacked calling process. A prompt-injected agent can still invoke any allowed function — including proxy_authenticated_http_request and mint_short_lived_token — make outbound HTTP calls, spend money, mutate remote systems, or read sensitive upstream responses . The protection it offers is narrow and specific: it reduces credential-exfiltration risk, not execution risk. That is why the project recommends strict host allowlists, short-lived scoped credentials, audit-log monitoring, and manual review for high-risk actions on top of the proxy.
Is there a read_secret or get_secret function in Cloak's MCP surface?
No, by design. Cloak exposes exactly six model-callable functions — list_secret_names, get_secret_metadata, sign_request, proxy_authenticated_http_request, mint_short_lived_token, and query_audit — and none of them returns a raw stored value. They return metadata, computed headers, proxied HTTP responses, derived credentials, or audit entries instead. There is no read_secret, get_secret, or vault.show tool anywhere in the surface, and secrets are denied by default. mint_short_lived_token is the deliberate exception: it can hand back a derived credential (AWS STS implemented; GitHub App and GitLab PAT schemas present but returning not-supported), but never the long-lived stored key itself .
What cryptography does Cloak use to protect stored vault entries?
Cloak seals each vault record with XChaCha20-Poly1305-IETF AEAD, using per-record subkeys derived through an Argon2id KDF over libsodium, plus a keychain-backed pepper . The vault itself is a SQLite WAL database. Recovery is a single BIP-39 24-word seed shown once at vault creation — there is no secondary recovery path, so losing that seed means losing the vault . Session tokens issued to authenticated peers are 32 random bytes, base64url-encoded, with a 30-minute default TTL, and audit entries are hash-chained JSONL that cloak audit verify can check for mutation, deletion, or reordering.
Does Cloak work on Windows?
Not in v1.1.2. The cloakd daemon refuses to start on Windows, and no installer artifacts are shipped for that platform . The current supported targets are macOS (arm64 and x64) and Linux (glibc x64, musl x64, and glibc arm64), across five documented build rows . Linux musl and Linux arm64 currently ship CLI/daemon-only artifacts, while macOS arm64/x64 and Linux glibc x64 cover the main quickstart path. Windows developers have no first-party option today; the limitation is tracked as an open issue.
Has Cloak been independently audited for correctness?
Not yet. As of v1.1.2 — released June 18, 2026 — the project's threat model document explicitly states that no third-party security audit has been completed . The strongest correctness claims still live in Cloak's own repository, tests, and release process. Supply-chain controls are stronger: builds are documented as cosign-keyless-signed with SLSA L3 provenance, and macOS stable builds are Developer ID-signed and notarized . But provenance and signing protect the integrity of what you download — they say nothing about whether the vault implementation itself is sound.