The local vault
for AI agents.
Akasha intercepts sensitive data in agent tool calls and replaces it with
vault:// tokens. Your secrets stay on your machine, encrypted
and audited, with the vault key wrapped against a future quantum attack.
See it work
Found, vaulted, used — without exposure.
Akasha finds credentials sitting in plaintext, vaults them on your confirmation, then runs a real command with one it never reveals — and records the access against a token digest.
Why Akasha
Secrets stay home.
Agents get tokens.
The agent asks for AWS. The broker serves the credential one operation at a time, and the vault stays the only copy on disk.
Nothing leaves the machine
The vault is a local SQLite file encrypted with XChaCha20-Poly1305. Its key lives in your OS keychain, so it never lands on disk or leaves the machine.
Brokered per operation
For git, GitHub and AWS, the agent's tooling calls back through akasha helper each time it needs the credential. The broker returns the bytes for that one operation. It writes nothing to disk and leaves nothing in the environment. Where no broker exists, vault_session hands back a short-lived file instead: mode 0600, on RAM-backed storage where the platform allows it, one-hour TTL, swept on expiry.
MCP-native, zero code
One command writes the MCP config. Claude Code, Codex and Cursor have vault_session, vault_wrap and the other vault tools natively.
Every touch audited
Every wrap, retrieve and session goes to a hash-chained JSONL log with the tool, the task, and the reasoning the agent supplied. akasha logs --verify walks the chain. The log is tamper-evident, not tamper-proof.
Beneath the MCP stack
akasha exec injects vaulted credentials into other MCP servers at launch, so your GitHub or Postgres server holds no plaintext token in its config.
Cross-agent grants
Delegate over A2A with only tokens on the wire. Grants are single-use, restricted to a named tool, and expire in minutes.
Integrate
Two lines from any agent.
Claude Code needs none.
# The agent asks for AWS. It gets a session file, not a key in its context.
vault_session(provider="aws", profile="default")
→ {
"env": {
"AWS_SHARED_CREDENTIALS_FILE": "…/sessions/aws-default.creds", # RAM-backed
"AWS_PROFILE": "default"
},
"expires_at": "2026-06-11T15:02:11Z" # 1h TTL, audited
}
from akasha import Akasha
vault = Akasha(agent_id="support-bot-v2", api_key="agt_…")
# Scan content before it reaches a tool or the LLM
result = vault.wrap("send_email", "card 4111111111111111")
# result.clean_content → "card vault://e4f5g6h7"
# Retrieve safely — zeroed after the block, tool enforced
with vault.use(result.token, tool="stripe_charge") as secret:
stripe.charge(secret.value)
# Store anything discovery didn't find
$ akasha put env:stripe STRIPE_API_KEY
# Run any process with vaulted credentials injected
$ akasha exec --with aws:default -- aws s3 ls
$ akasha exec --with env:stripe -- ./charge.sh
# Tail the audit log
$ akasha logs
Be the vault the other MCP servers run on
MCP servers cannot see each other's traffic, but they all need credentials. Akasha sits underneath them, brokering those secrets and recording who used what, so nothing sits in plaintext in your config. Git and AWS resolve the credential per operation. A token-only server gets it injected at launch.
// Instead of a hardcoded token in your MCP config:
"github": {
"command": "akasha",
"args": ["exec", "--with", "env:github",
"--", "github-mcp-server"]
}
Plugins
Integrate any login as data.
No provider is compiled in. Each one is a YAML file describing how its credential works.
Adding a provider means writing a file
AWS, GitHub or a bespoke internal API: each is a data-only plugin saying how its credential is shaped, where to find it, and how to hand it over. One git-credential-helper mechanism covers GitHub, GitLab and Bitbucket without new code.
An untrusted plugin stays inert until you approve it, either by hash with
akasha template trust or by an Ed25519 signature from a publisher you already trust.
# ~/.akasha/templates/datadog.yaml
kind: provider
name: datadog
credential:
fields:
api_key: {secret: true}
deliver:
- mode: env
env: {DD_API_KEY: "{api_key}"}
Provenance
Every entry carries a reason.
Alongside the access, the log records the task the agent was doing and the reasoning it gave.
{
"token": "vault://abc12345",
"action": "VAULTED",
"category": "CreditCard",
"risk": "critical",
"agent_id": "support-bot-v2",
"tool_name": "send_email",
"task": "Process refund for order #8821",
"reasoning_trace": "User requested refund. Order verified. Initiating.",
"triggered_by": "user message: 'I want my money back'"
}
Detection
Matched on the way through.
Patterns ship with the binary. Add your own in ~/.akasha/patterns.yaml.
| Category | Sample match | Risk |
|---|---|---|
| SSN | 429-21-0001 | critical |
| Credit card | 4111111111111111 | critical |
| API key (AWS) | AKIA… | critical |
| API key / password | sk-… / password: … | high |
| PII (email, phone) | user@example.com | medium |
| Risky tool watchlist | send_email, charge_card, … | varies |
Control
Rules the daemon checks first.
A local policy file, consulted before any secret moves. Allow, deny, or ask.
Three verbs, gated separately
broker resolves a credential for one operation. Git and AWS use it.
The broker writes nothing to disk, and each use gets its own audit record. The
default policy allows it. session materializes a credential for a
whole session as a file the tool reads until the TTL removes it. The starter
policy that setup installs denies it to agents where a broker exists.
retrieve is a raw read of any vaulted entry by token. The default
policy denies it, because it is the one verb that reaches the whole vault.
That is attribution and drift protection, not containment. The daemon runs as
you, and so does the agent. A process running as your user can read the vault
key from the OS keychain without going through Akasha. Two things narrow that:
a vault passphrase, and akasha run, which sandboxes the agent away
from the keychain and the vault.
Rules match on action, agent, tool, provider, instance, category, risk, caller and brokerable, and the first match wins.
An ask raises a native approval dialog that fails closed if nobody
answers, so risky handoffs wait for a human while routine ones go through.
# ~/.akasha/policy.yaml — what `setup` installs. First match wins.
default: allow
rules:
# raw read of any vaulted entry → deny
- {action: retrieve, effect: deny}
# an agent uses the per-operation route, not a session file
- {action: session, caller: agent, brokerable: true, effect: deny}
# delegating a high-risk secret onward → a human decides
- {action: grant, min_risk: high, effect: ask}
- {action: grant, effect: allow}
# broker has no rule: it falls through to `default: allow`
Security