Skip to content

Latest commit

 

History

214 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Phantom — Stop AI agents from leaking your API keys

Phantom

Delegate more to AI without putting real keys in agent context.

Phantom replaces project secrets with scoped phm_ placeholders. Applications use those placeholders through an authenticated local proxy, while agents use value-blind MCP tools for inventory, diagnostics, and governed requests.

GitHub stars CI npm License: MIT

Quick start · Delegate safely · Why Phantom? · MCP setup · Docs · phm.dev


Watch the 45-second demo  ·  🛡 Security model  ·  📋 Threat model  ·  💬 Discussions

Why Phantom?

AI coding agents routinely work in repositories that also contain local credentials. Once a real API key enters an agent context, transcript, tool call, or generated file, you have lost control of where that value may persist.

Traditional secrets managers focus on keys at rest and in transit. Phantom adds a boundary for agent context:

  • 🔒 Designed to keep real keys out of the LLM — project dotenv files contain phm_ tokens, agents use value-blind MCP metadata, and the proxy injects values only into scoped authenticated requests.
  • Fast local setupnpx phantom-secrets init protects a project without requiring an account, DNS changes, or a custom CA.
  • 🧰 Agent-native integrations — setup helpers and value-blind MCP workflows for Claude Code, Cursor, Windsurf, and Codex, plus project instructions for GitHub Copilot.
  • 🦀 Open source, local-first, MIT — secrets use the native OS credential store when it is available, with an explicit encrypted-file fallback. Optional cloud sync encrypts vault payloads client-side before the server stores them.

Used by developers who don't want to choose between delegating to AI and not pasting their Stripe key into a chat window.

Project status and trust boundary

Phantom's implemented user-facing surfaces are the CLI, vault, authenticated local proxy, MCP server, and optional cloud/team workflows documented below. Cloud and team behavior additionally depends on the deployed service, account plan, and provider configuration; source code alone is not deployment or customer-acceptance evidence. The conversation facade is intentionally narrow:

  • phantom_do is proposal-only. It canonicalizes a closed Cargo action and reports its digest, effect, and activation blockers; execute is hard denied.
  • phantom_setup_workspace can propose setup, create a bearerless request, and report authenticated status. Applying a request remains a separate trusted-terminal operation.
  • Advanced MCP tools remain a compatibility catalog with their own explicit confirmation and out-of-band approval gates. They are not governed by the conversation facade's capability card.
  • phantom grant provides shipped, trusted-terminal provider grant workflows for obtaining and vaulting provider credentials after human consent. A provider grant is credential lifecycle configuration; it is not an execution-kernel authority grant, a broker lease, or permission for an agent to execute work.
  • The authority, broker, runtime, session, and evidence crates are inactive, fail-closed foundations. They do not establish live Locus authority, broker credentials, execute agent actions, or produce externally trusted receipts today.

See the documentation map, architecture, security policy, and threat model for the evidence behind those boundaries.

Quick Start

$ npx phantom-secrets init
# Auto-detects .env, .env.local, or .env in subdirectories
# Stores real secrets in the native credential store or encrypted vault,
# then rewrites .env with phantom tokens
# Auto-configures Claude Code MCP server if detected

$ phantom agent doctor
# One human-readable readiness check for AI-agent safety

$ phantom exec -- claude
# Authenticated proxy running on an ephemeral 127.0.0.1 port
# App/test processes use phantom tokens; agents use value-blind metadata

For a task contract you can hand to Claude Code, Codex, Cursor, Windsurf, or Copilot, use the safe delegation quickstart and the copyable policy and task templates. Teams evaluating a controlled rollout can start with the enterprise adoption guide.

Windows

The same core commands work on native Windows. npx phantom-secrets init installs via npm as on macOS/Linux. WSL is a separate Linux environment with its own filesystem and credential-store context.

After phantom start --daemon, the CLI detects your shell and prints the matching env-var syntax. For reference:

PowerShell:

$env:OPENAI_BASE_URL = "http://127.0.0.1:PORT/openai/_phantom/TOKEN/"
$env:PHANTOM_PROXY_PORT = "PORT"
$env:PHANTOM_PROXY_TOKEN = "TOKEN"

cmd.exe:

set OPENAI_BASE_URL=http://127.0.0.1:PORT/openai/_phantom/TOKEN/
set PHANTOM_PROXY_PORT=PORT
set PHANTOM_PROXY_TOKEN=TOKEN

Git Bash / WSL: use the export X=Y syntax from the main quick-start.

Notes:

  • PHANTOM_PROXY_TOKEN is the proxy session authenticator. By default, phantom exec and phantom start include it in local *_BASE_URL values as /_phantom/TOKEN/ so unmodified SDKs work. Header-aware clients can set PHANTOM_PROXY_HEADER_AUTH_ONLY=1 and send x-phantom-proxy-token: $PHANTOM_PROXY_TOKEN instead.
  • If phantom.exe is blocked by Windows application-control policy, do not automatically remove Mark-of-the-Web. First verify the archive checksum and both binary identities against the release metadata. If local policy permits the verified binaries, a user may then remove the mark explicitly with PowerShell: Get-ChildItem "$env:USERPROFILE\.phantom-secrets\bin\*.exe" | Unblock-File.
  • The pre-commit hook installed by phantom init is a #!/bin/sh script. Native git from the command line invokes it via Git for Windows' bundled sh.exe, which is what the official Git for Windows installer ships. GUI clients (GitHub Desktop, some IDE integrations) may run with a stripped-down PATH that lacks sh.exe and silently skip the hook — for these, run commits from a terminal, or use phantom check --staged directly. CI is the durable safety net regardless.
  • The release workflow defines x64 and ARM64 Windows ZIPs, and the npm and PowerShell installers map both targets. A workflow definition is not evidence that an exact archive was published, signed, or passed native acceptance. See the platform support matrix.

How It Works

  .env file (AI read denied)       OS Keychain / Vault
  +--------------------------+      +---------------------+
  | OPENAI_API_KEY=phm_a7f3  | ---> | sk-real-secret-key  |
  | STRIPE_KEY=phm_c9d1...   |      | sk_live_real-key... |
  +--------------------------+      +---------------------+
           |                                 |
           v                                 v
  App / test process                Phantom Proxy (127.0.0.1)
  +--------------------------+      +------------------------------+
  | Loads phm_ tokens        |      | Intercepts HTTP requests     |
  | Agent gets MCP metadata  | ---> | Replaces phm_ with real keys |
  | Makes API calls to proxy |      | Forwards over TLS to real API|
  +--------------------------+      +------------------------------+
  1. phantom init reads .env, stores real secrets in the native OS credential store or encrypted-file fallback, and rewrites .env with phm_ tokens
  2. phantom exec -- claude starts a local reverse proxy, sets SDK-compatible service base URLs such as OPENAI_BASE_URL=http://127.0.0.1:PORT/openai/_phantom/TOKEN/, exposes PHANTOM_PROXY_TOKEN to the child process, and launches the command
  3. API calls hit the proxy, which authenticates the local session, removes the local auth token before forwarding, replaces phantom tokens with real secrets, and forwards over TLS
  4. When the session ends, the proxy shuts down and the proxy session token is invalid. Phantom tokens remain worthless placeholders outside an authenticated proxy session.

Phantom does not grant AI tools permission to read .env or other dotenv files. phantom setup removes legacy Phantom-managed dotenv read grants and preserves deny rules; agents use value-blind MCP inventory instead.

Provider grants

phantom grant is the shipped CLI boundary for obtaining provider credentials after a human completes the provider's consent flow. The issuance engine returns credential roots only to the CLI, which writes them directly to the vault and prints metadata rather than values.

phantom grant add github-app
phantom grant add vercel-integration --client-id <PUBLIC_CLIENT_ID> \
  --client-secret-env VERCEL_INTEGRATION_CLIENT_SECRET --team <TEAM_ID>
phantom grant list
phantom grant status

Provider endpoints are selected from a closed production allowlist. Provider client secrets are named by environment variable and are never accepted as command-line values. grant list and grant status are metadata-only. phantom grant revoke currently fails closed before local mutation because remote revocation is not wired for the supported providers.

In these docs, provider grant means the credential and renewal state created by this CLI flow. Authority grant means the inactive, value-free execution authority type in phantom-authority. A provider grant cannot be reinterpreted as an authority grant, Locus credential, broker lease, or execution permit. See the design-era grant lifecycle specification; the issuance contract is the original design contract and retains design-era status language.

MCP Integration (Claude Code, Cursor, Windsurf, Codex)

Phantom ships an MCP server so AI coding tools can inspect value-blind metadata and request gated lifecycle operations. MCP responses do not return real secret values.

  • Conversation facadephantom_capability reports authority and hard denials for the small facade (not the separately gated advanced compatibility catalog); phantom_do canonicalizes one closed Cargo action and reports the exact activation blockers without executing it; phantom_setup_workspace proposes an exact value-blind plan, creates a bearerless apply request after revalidation, or reads authenticated request status. Proposal checks or hardens machine-local Phantom state and reports whether it provisioned the seal key; MCP never claims or applies the request.
  • Vaultphantom_list_secrets, phantom_status, phantom_init, phantom_add_secret_interactive, phantom_add_secret (deprecated; refuses plaintext), phantom_remove_secret, phantom_rotate, phantom_copy_secret
  • Detection + diagnosticsphantom_doctor, phantom_why, phantom_check, phantom_env, phantom_validate_secret, phantom_validate_all
  • Local-to-cloudphantom_wrap, phantom_unwrap, phantom_sync, phantom_cloud_push, phantom_cloud_pull, phantom_cloud_status
  • Teamsphantom_team_list, phantom_team_create, phantom_team_members, phantom_team_invite, phantom_team_key_publish, phantom_team_vault_push, phantom_team_vault_pull
  • Advanced audit, rotation, expiry, and compliance — audit analytics/recent events/anomalies/leak incidents, staged and provider rotation, validation scheduling, expiry enforcement, and compliance status tools

Mutating tools require an explicit confirm: true parameter so a prompt-injected agent can't silently mutate state. Real secret values are never accepted as MCP tool arguments; new secrets are entered out-of-band in a trusted terminal.

Workspace setup is deliberately split across trust boundaries. MCP can call phantom_setup_workspace with phase=propose, then phase=request_apply using the exact returned plan_id and pre_state_id. That creates only a value-free request outside the repository. Apply it from an attached trusted terminal with phantom workspace apply --request <ID>; MCP has no claim or apply operation and receives no bearer or approval token.

One command per AI client — Phantom writes the right config file in the right place:

phantom setup --client claude     # .claude/settings.local.json (project)
phantom setup --client cursor     # ~/.cursor/mcp.json
phantom setup --client windsurf   # ~/.codeium/windsurf/mcp_config.json
phantom setup --client codex      # ~/.codex/config.toml
phantom setup --client claude --print   # snippet to stdout for any other client

If phantom-mcp isn't on PATH, Phantom falls back to npx -y phantom-secrets-mcp so the config still works on a fresh machine. Restart the AI tool after running phantom setup so it picks up the new config.

Phantom works with any tool that supports the Model Context Protocol.

Cloud Sync + Dashboard

Sync vaults across machines with end-to-end encryption. The server never sees plaintext.

$ phantom login
# Opens GitHub OAuth (device code flow)

$ phantom cloud push
# Encrypted client-side, uploaded to phm.dev

$ phantom cloud pull   # on another machine
# Downloaded and decrypted locally

$ phantom open
# Opens https://phm.dev/dashboard — read-only view of your projects,
# vault sizes, last sync, plan tier, and team membership.

Cloud sync uses ChaCha20-Poly1305 with a client-side passphrase derived via Argon2id. The server stores only ciphertext.

Team vaults (Pro)

Multiple developers can share a single E2E-encrypted vault per project. Server only ever stores ciphertext + per-member ciphertext shares.

$ phantom team create "engineering"
# Creates a team; you become the owner.

$ phantom team invite <team_id> <github-username>
# Invites by GitHub login.

$ phantom team key-publish <team_id>
# Registers your X25519 public key on the team.
# (Run once per team; the private key stays in the OS keychain.)

$ phantom team vault-push <team_id>
# Encrypts the current project's vault with a fresh symmetric key,
# wraps that key (X25519 + ChaCha20-Poly1305) for every member that
# has a registered public key, then uploads.

$ phantom team vault-pull <team_id>   # on a teammate's machine
# Pulls, decrypts the per-member share with their private key,
# decrypts the vault, writes secrets locally.

Team memberships and member lists are visible in the read-only dashboard at phm.dev/dashboard/team.

Command Reference

Command Description
phantom init Import .env secrets into vault, rewrite with phantom tokens. --all <DIR> protects every git repo with a .env under <DIR> in one go (with --dry-run to preview, --jobs N / -j N to control parallelism)
phantom exec -- <cmd> Start an authenticated proxy and run a command with secret injection
phantom start / stop Manage proxy lifecycle (standalone/daemon mode)
phantom list Show secret names stored in vault (never values; --json for machine-readable output)
phantom add <KEY> Add a secret through a hidden trusted-terminal prompt; use --stdin only with a trusted producer
phantom remove <KEY> Remove a secret from the vault
phantom reveal <KEY> Print a secret value (or --clipboard to copy)
phantom status Show proxy state, vault info, and mapped services
phantom rotate Regenerate all phantom tokens (old ones become invalid). With --name <KEY> (and optional --provider <VENDOR>): rotate the real credential at the vendor — see Rotating real provider credentials
phantom grant add <provider> Run a trusted-terminal provider consent flow, vault the issued credential roots, and store renewal metadata without printing values. See Provider grants.
phantom grant list / status Read provider-grant names, providers, lifecycle state, and expiry metadata without returning credential values.
phantom grant revoke <provider> Reserved remote-revocation surface; currently fails closed before local mutation because provider revocation is not wired.
phantom doctor Check configuration and vault health (--fix to auto-repair). Reports install source, vault backend, audit-log status, Argon2 params, and MCP wiring per client
phantom agent report Emit a read-only AI-agent readiness report (--json for automation). Reports unsafe, protected, verified, team-ready, or compliance-ready
phantom agent doctor Human-readable agent readiness view backed by the same policy engine
phantom agent setup Preview or apply safe defaults for agent use (--dry-run first, --apply to write changes)
phantom workspace plan [--json] Build an exact sealed setup plan and create a value-free pending request; does not change the workspace or vault
phantom workspace apply --request <ID> Recompute and claim the exact request in an attached trusted terminal, require typed confirmation, then apply transactionally with rollback on failure
phantom workspace status --request <ID> [--json] Read authenticated, value-free request state
phantom check Scan for unprotected secrets (pre-commit hook, --staged, --runtime)
phantom sync Push secrets to Vercel / Railway (--dry-run --json previews safely; --only PATTERN filters by glob, repeatable)
phantom pull Pull secrets from Vercel / Railway into vault
phantom setup Wire Phantom into an AI client. --client claude (default), cursor, windsurf, or codex. Add --print to emit the config snippet to stdout
phantom env Generate .env.example for team onboarding
phantom export Export to a new encrypted backup with a hidden terminal prompt, or --passphrase-file <PRIVATE_FILE> for bounded automation; plaintext export and argv passphrases are disabled
phantom import Restore an encrypted backup with a hidden prompt or --passphrase-file <PRIVATE_FILE>, or migrate from --from doppler|infisical|dotenvx|1password|env --file <path>. Add --force to overwrite existing secrets
phantom audit show Print recent audit events (--last N, --op OP, --name NAME, --json). Requires PHANTOM_AUDIT=1
phantom audit tail Follow the audit log live (--op, --name filters)
phantom audit path Print the absolute path to the audit log file
phantom audit verify Verify HMAC-SHA256 chain integrity; exits 1 if tampering detected
phantom login Authenticate with Phantom Cloud via GitHub OAuth
phantom logout Clear cloud credentials
phantom cloud push Push encrypted vault to Phantom Cloud
phantom cloud pull Pull and decrypt vault from Phantom Cloud
phantom wrap Wrap package.json scripts with phantom exec automatically
phantom unwrap Restore original package.json scripts
phantom watch Watch .env files and auto-detect new unprotected secrets
phantom why <KEY> Explain why a key is or is not protected
phantom copy <KEY> Copy a secret to another project's vault
phantom team list/create/members/invite Team vault management
phantom team key-publish <id> Register your X25519 pubkey on a team (once per team)
phantom team vault-push <id> Push current project to shared team vault (E2E encrypted per-member)
phantom team vault-pull <id> Pull team vault into local vault
phantom open [page] Open phm.dev pages in browser (dashboard, billing, team, docs, github, …)
phantom upgrade Self-replace this binary with the latest GitHub release (--check-only to inspect first)
phantom completion <shell> Print a shell-completion script (bash, zsh, fish, powershell, elvish)

Rotating real provider credentials

phantom rotate --name <KEY> re-issues the actual credential at the vendor — not just the phantom token. The new value goes straight into the encrypted vault (the same write path as phantom add), the phm_ token in .env is refreshed, an audit event is recorded, and the value is never printed.

# 1. Tell Phantom how to rotate the secret (once, in .phantom.toml):
#    [phantom.secrets.STRIPE_SECRET_KEY.rotation_provider]
#    provider = "stripe"
#    api_key_env = "STRIPE_ROTATION_ADMIN_KEY"   # env var OR vault secret of this name

# 2. Rotate. Provider comes from the config block; --provider overrides.
phantom rotate --name STRIPE_SECRET_KEY
phantom rotate --name STRIPE_SECRET_KEY --provider stripe --sync

# Metadata-only JSON for scripting (no value, ever):
phantom rotate --name STRIPE_SECRET_KEY --json

The bootstrap credential named by api_key_env (the key used to call the vendor's rotation API) is resolved from the process environment first, then from the vault under the same name — so it never has to live in your shell profile. It is zeroized after the call and never echoed.

The same flow is exposed to AI agents via the phantom_rotate_provider MCP tool (gated behind confirm: true plus an out-of-band phantom mcp-approve token; the response contains status metadata only).

Provider support matrix

Provider Support Notes
vercel Automated Mints a new user/team API token and verifies it (2xx-only); the old token is best-effort revoked only AFTER the new value is stored in the vault (authenticating as the old token itself), with audit events when revocation is skipped or fails
google Automated Adds a new Secret Manager version with a freshly generated value (rotates a GSM-stored secret, not an external Google credential); refuses Google-issued credential names (*APPLICATION_CREDENTIALS*, *SERVICE_ACCOUNT*); disabling old versions is still manual
github Automated for GitHub App installation tokens Requires account_id = App installation ID and a freshly minted App JWT as the bootstrap credential (App JWTs expire ~10 min). Minted tokens expire in 1 h — phantom stamps that expiry on the stored secret. Classic and fine-grained PATs have no rotation API — rotate those at github.com/settings/tokens
stripe Manual Stripe exposes no public key-mint/roll API; the CLI errors with the dashboard link (mock path remains for tests)
aws Manual (for now) Real IAM rotation needs SigV4 signing + access-key-pair handling, not yet implemented; the CLI errors with the AWS CLI/console steps (mock path remains for tests)
sentry Manual Token creation is web-session-only at the vendor; the CLI errors with the exact dashboard page to use
supabase Manual Personal access tokens are minted only at supabase.com/dashboard/account/tokens

phantom rotate --batch extends this to every secret whose TTL falls inside the rotation window, with per-provider rate limits and a shared audit batch_id.

Features

  • Encrypted vault -- macOS Keychain, Linux Secret Service, or Windows Credential Manager, with a ChaCha20-Poly1305 encrypted-file fallback for CI and headless environments. Phantom does not claim Secure Enclave hardware binding. Argon2id uses m=64 MiB, t=3, p=1.
  • Phantom tokens -- 256-bit CSPRNG phm_ placeholders in .env, rotatable on demand
  • Authenticated proxy sessions -- each proxy run generates a fresh PHANTOM_PROXY_TOKEN; CLI-generated SDK URLs include it for compatibility, and header-aware clients can opt into x-phantom-proxy-token with PHANTOM_PROXY_HEADER_AUTH_ONLY=1
  • Bounded request replacement -- Supported request bodies are collected under explicit byte/time limits before scoped phantom-token replacement; oversized requests fail closed.
  • Full SSE/streaming support -- Response streaming preserved end-to-end for OpenAI, Anthropic, and other streaming APIs
  • Smart detection -- Heuristic engine distinguishes secrets (*_KEY, *_TOKEN, sk-*, ghp_*) from config (NODE_ENV, PORT)
  • Platform sync -- Push/pull secrets to Vercel and Railway
  • Pre-commit hook -- Blocks commits containing unprotected secrets
  • MCP server -- core vault, diagnostics, cloud, team, audit, rotation, validation, expiry, and compliance tools for Claude Code, Cursor, Windsurf, and Codex to manage secrets without seeing values
  • Cloud sync -- E2E encrypted zero-knowledge vault sync across machines
  • Export/import -- Encrypted backup and restore through a hidden terminal prompt or private bounded passphrase file; plaintext export and argv passphrases are disabled; import from Doppler, Infisical, dotenvx, 1Password, or plain .env via --from
  • Tamper-evident audit log -- PHANTOM_AUDIT=1 writes vault events as JSONL to ~/.phantom/audit.log. Each entry is chained with HMAC-SHA256; phantom audit verify detects tampering. phantom audit show/tail/path for log access.
  • Response scrubbing -- Scrubs configured secret values from supported API response paths before returning data to the caller
  • Script wrapping -- phantom wrap patches package.json so every npm script runs through the proxy
  • Watch mode -- phantom watch monitors .env files for new unprotected secrets
  • Multi-project scanner -- phantom init --all <DIR> protects every git repo with a .env under <DIR> in one command (with --dry-run); --jobs N controls parallelism
  • Multi-IDE setup -- phantom setup --client claude|cursor|windsurf|codex writes the right MCP config for each AI tool, or --print for a generic snippet
  • Agent readiness -- phantom agent doctor and phantom agent report --json answer whether a repo is safe for Claude Code, Codex, Cursor, Windsurf, and other agents
  • Enriched diagnostics -- phantom doctor reports install source, vault backend, audit-log status, Argon2 params, and MCP wiring per client
  • Secret explainer -- phantom why <KEY> explains detection heuristics
  • Cross-project copy -- phantom copy shares secrets between project vaults
  • Team vaults -- Shared vaults with role-based access control
  • Fail-closed service routing -- agentic proxy sessions accept Phantom's exact built-in OpenAI, Anthropic, Stripe, Supabase, and other reviewed routes; repository-defined destinations are rejected pending trusted-terminal approval support
  • Threat model -- See THREAT_MODEL.md for assets, actors, mitigations, and known gaps

Installation

npm (recommended)

$ npm install -g phantom-secrets

Or use directly with npx:

$ npx phantom-secrets init

Claude Code MCP

$ claude mcp add phantom-secrets-mcp -- npx -y phantom-secrets-mcp

Cargo

$ cargo install phantom-secrets

Architecture

The Rust workspace is organized as product crates plus fail-closed execution-kernel foundations. Presence in the workspace does not mean a foundation is activated in production.

Layer Crate Role and current status
Product phantom-core Config, dotenv parsing/rewriting, tokens, auth, cloud client, audit, validation, and shared policy.
Product phantom-vault VaultBackend trait, OS keychain and encrypted-file backends, and shared cryptography.
Product phantom-proxy Authenticated loopback reverse proxy with scoped token replacement, response scrubbing, and streaming support.
Product phantom-cli Operator CLI for initialization, proxy lifecycle, readiness, audit, import/export, sync, team, and workspace workflows.
Product phantom-mcp Stdio MCP server. The governed conversation facade is narrow; the advanced compatibility catalog uses separate legacy gates.
Product phantom-core/src/issuance, CLI grant Human-consent provider issuance, direct-to-vault root storage, and value-free provider-grant lifecycle metadata. No MCP provider-consent surface.
Setup kernel phantom-workspace Value-blind discovery, sealed planning, and recoverable trusted-terminal setup transactions. Non-Unix durable mutation fails closed.
Inactive foundation phantom-authority Closed authority contracts and deny-all production verification boundary. No live Locus verifier.
Inactive foundation phantom-locus-contract Value-free compatibility contract describing requirements for a future Phantom/Locus integration.
Inactive foundation phantom-broker Bounded broker protocol and durable replay/accounting primitives. No active transport, lease issuer, or runtime connection.
Inactive foundation phantom-runtime Closed engineering action schemas with a deny-all production executor.
Inactive foundation phantom-session Crash-explicit session journal. Not wired into active execution.
Inactive foundation phantom-evidence Value-free evidence and receipt primitives. Not externally anchored or wired into active execution.

apps/web contains the Next.js site and backend routes for cloud vault sync, GitHub device authentication, and Stripe billing. The repository source and local tests are separate evidence from the currently deployed state at phm.dev.

npm packages: phantom-secrets (CLI), phantom-secrets-mcp (MCP server).

CI runs locked, all-target workspace builds and tests on macOS, Linux, and Windows runner environments, plus formatting, Clippy, and npm release-mapping checks. Release builds and native end-to-end acceptance are separate evidence layers; see Platform support.

Security

  • Managed dotenv replacement -- after successful initialization, Phantom-managed dotenv values are tokens; unmanaged files, backups, logs, and external tools remain outside this claim
  • ChaCha20-Poly1305 encryption for file vault and cloud sync, Argon2id key derivation
  • Zero-knowledge cloud -- server stores only ciphertext; encryption key never leaves the client
  • 256-bit CSPRNG tokens -- phm_ prefix distinguishes Phantom tokens from supported real-key formats; random collisions are cryptographically negligible, not mathematically impossible
  • Proxy binds 127.0.0.1 only -- never exposed to the network
  • Secrets zeroized from memory after injection via the zeroize crate
  • Allowlist model -- proxy only injects secrets for explicitly configured service patterns

See SECURITY.md for the responsible disclosure policy and THREAT_MODEL.md for the full threat model (assets, actors, mitigations, known gaps, cryptography summary).

Pricing

Free Pro Enterprise
Local vaults Unlimited Unlimited Unlimited
Cloud vaults 1 Unlimited Unlimited
MCP server Yes Yes Yes
Cloud sync Yes Yes Yes
Team features -- Yes Yes
Price $0 $8/mo Contact us

Links

Contributing

We love PRs. Start with CONTRIBUTING.md, pick a good first issue, or open a discussion to talk through an idea. Be excellent to each other — see CODE_OF_CONDUCT.md.

Star history

Phantom Secrets star history

If Phantom saves you from leaking a key — or even just from worrying about it — please star the repo ⭐. It's the single biggest signal we use to know what to build next.

License

MIT — see LICENSE.

About

Stop AI coding agents from leaking your API keys. Local proxy + MCP that swaps real secrets for phm_ tokens — works with Claude Code, Cursor, Windsurf, and Codex.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

16 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages