# tsafe
> Local secret runtime, encrypted developer vault, process-scoped secret
> injection, and bounded MCP command gateway for agentic development.
[](https://crates.io/crates/tsafe)
[](https://docs.rs/tsafe)
[](https://github.com/0ryant/tsafe/blob/main/LICENSE)
`tsafe` is the bundle crate for the tsafe command-line suite. Install it when
you want the main `tsafe` CLI plus companion runtimes in one Cargo install path:
```sh
cargo install tsafe
```
For the smaller standalone CLI-only path, use:
```sh
cargo install tsafe-cli
```
`tsafe` is not trying to replace your canonical secret manager. It is the local
secret runtime between secret stores and commands: encrypted vaults, policy
contracts, process-scoped environment injection, audit receipts, and safe
model-facing command execution.
## Why it exists
The common unsafe workflow is simple:
```sh
DB_PASSWORD=secret node server.js
```
That can land in shell history, logs, `.env` files, chat transcripts, terminal
scrollback, or commits. `tsafe exec` makes the safer path ergonomic:
```sh
tsafe exec -- node server.js
```
The child process receives the authorized secrets. The parent shell, command
line, model context, and repository do not receive raw secret values.
## What this crate installs
`cargo install tsafe` builds these binaries from the same published release
line:
| `tsafe` | Local encrypted vault CLI, `exec`, contracts, audit, diagnostics |
| `tsafe-agent` | Local unlock session daemon for repeated commands |
| `tsafe-mcp` | Bound-contract MCP server for model-facing command execution |
| `tsafe-nativehost` | Browser native messaging host for extension workflows |
| `tsafe-tray` | Desktop tray status indicator for agent/vault state |
The `tsafe-cli` crate installs only the compiled `tsafe` binary. Agent-backed
sessions, MCP hosting, browser native messaging, and tray status require the
corresponding companion binary to be installed or bundled by your release
channel.
## Quickstart
```sh
tsafe init
tsafe set DB_PASSWORD
tsafe set API_TOKEN
tsafe exec -- node server.js
tsafe exec -- docker compose up
tsafe exec --contract api-server -- cargo test
```
Useful first checks:
```sh
tsafe doctor
tsafe build-info
tsafe explain exec
tsafe audit
```
## Core concepts
| Vault | Encrypted local secret store, separated by profile |
| Profile | Independent authority boundary such as `default`, `dev`, or `prod` |
| Exec | Runs a child command with selected secrets injected as environment variables |
| Contract | Named policy in `.tsafe.yml` for allowed secrets and command targets |
| Audit | Local JSONL receipts for security-relevant operations |
| Agent | Local TTL unlock session so repeated commands do not keep prompting |
| MCP | Model-facing command gateway bound to one profile, one contract, one workdir |
## Contracts and process-scoped execution
Without a contract or explicit key scope, `tsafe exec` can inject the active
profile's vault entries into the child process. For scripts, CI, and agentic
tools, prefer named contracts:
```yaml
# .tsafe.yml
contracts:
api-server:
profile: dev
allowed_secrets:
- DB_PASSWORD
- API_TOKEN
required_secrets:
- DB_PASSWORD
allowed_targets:
- "node server.js"
- "cargo test"
redact_output: true
```
Then run:
```sh
tsafe exec --contract api-server -- node server.js
```
Contracts keep authority reusable and reviewable. They also make dry-run and
plan surfaces easier to trust:
```sh
tsafe exec --contract api-server --dry-run -- node server.js
```
## MCP normal form
The MCP path is designed for model-facing command execution without exposing
raw vault material to the model. The supported normal form is bound at process
startup:
```sh
tsafe mcp serve --profile <profile> --contract <contract> --workdir <repo>
```
The bound MCP server exposes a small tool catalog:
| `show_exec_plan` | Show what would run and what authority is required |
| `run_contract_command` | Run a contract-authorized command under policy |
| `tsafe_mcp_status` | Report safe status and compiled capability metadata |
It does not expose `tsafe get`, `tsafe export`, profile switching, request-time
contract switching, or bulk vault dumps. Secret values may enter only the
bounded child process environment.
Generate a Codex MCP config entry without secret values:
```sh
tsafe mcp config codex \
--name tsafe-cordance \
--profile cordance \
--contract cordance-mcp \
--workdir C:\path\to\cordance
```
Use separate server instances for separate authority contexts. For example,
`tsafe-cordance` and `tsafe-cortex` should each have their own profile,
contract, workdir, audit stream, and process.
## Privacy and telemetry
tsafe does not phone home. It does not send product analytics, crash reports,
update pings, secret names, secret values, vault metadata, or command metadata
to a vendor service.
Audit logs are local per-profile JSONL receipts. `tsafe audit-export` can
project those receipts as JSONL, Splunk-compatible JSON, or CloudEvents JSONL,
but export formats are not hidden telemetry. Data leaves the machine only when
you explicitly run or configure a networked feature such as provider pull/push,
HIBP checks, one-time sharing, remote sync, webhook/NATS event adapters, or
your own log shipper.
Use `tsafe build-info --json` to inspect the compiled capabilities in the
binary you are actually running.
## Local security model
| Vault encryption | XChaCha20-Poly1305 |
| Key derivation | Argon2id |
| Team wrapping | age X25519 multi-recipient encryption |
| Key material | Zeroized on drop where represented in memory |
| Writes | Temporary file plus atomic rename |
| Audit | Append-only local JSONL receipts with integrity verification surfaces |
| Snapshots | Encrypted recovery snapshots for local vault state |
Threat model and feature docs live in the repository:
- <https://github.com/0ryant/tsafe/blob/main/docs/features/security.md>
- <https://github.com/0ryant/tsafe/blob/main/docs/features/export-and-exec.md>
- <https://github.com/0ryant/tsafe/blob/main/docs/features/workflows.md>
## Common commands
| `tsafe init` | Create an encrypted vault |
| `tsafe set <KEY>` | Store a secret, prompting securely when value is omitted |
| `tsafe get <KEY>` | Print or copy one secret for direct operator use |
| `tsafe list` | List secret names, never values |
| `tsafe exec -- <cmd>` | Run a child command with authorized secrets injected |
| `tsafe exec --contract <name> -- <cmd>` | Run under a named `.tsafe.yml` contract |
| `tsafe audit` | Inspect recent local audit receipts |
| `tsafe audit-verify` | Verify audit integrity coverage |
| `tsafe audit-export` | Export local receipts as JSON, Splunk JSON, or CloudEvents |
| `tsafe doctor` | Diagnose vault, agent, contract, and local runtime state |
| `tsafe build-info` | Show build profile and compiled capabilities |
| `tsafe mcp serve` | Start the bound-contract MCP server |
| `tsafe mcp config codex` | Emit a safe Codex MCP config entry |
Provider commands are feature/build dependent and may include Azure Key Vault,
AWS Secrets Manager, AWS SSM Parameter Store, Google Secret Manager, HashiCorp
Vault, 1Password, Bitwarden, and KeePass workflows. Run `tsafe build-info` and
`tsafe --help` for the exact binary in hand.
## Cloud and password-manager workflows
tsafe can pull secrets from canonical stores into the local encrypted runtime:
```sh
tsafe kv-pull
tsafe aws-pull
tsafe gcp-pull
tsafe vault-pull
tsafe op-pull <ITEM>
```
This is intentionally command-shaped. Network access happens when you run or
configure a networked feature; the default local vault, exec, audit, and MCP
surfaces do not imply a vendor control plane.
## Where files live
| Vault files | Platform data dir, under `tsafe/vaults/<profile>.vault` |
| Audit logs | Platform state dir, per-profile JSONL receipts |
| Config | Platform config dir, tsafe config JSON |
| Repo policy | `.tsafe.yml` and optional `.tsafe/tooling/keys.ini` |
Override vault location for tests or portable workflows with `TSAFE_VAULT_DIR`.
## Workspace crate map
| `tsafe` | Bundle crate for CLI plus companion binaries |
| `tsafe-cli` | Main `tsafe` command tree |
| `tsafe-core` | Vault, contracts, audit, crypto, profiles, and shared runtime |
| `tsafe-agent` | Local unlock session daemon |
| `tsafe-mcp` | MCP stdio server |
| `tsafe-tui` | Terminal UI and standalone `tsafe-ui` binary |
| `tsafe-nativehost` | Browser native messaging host |
| `tsafe-tray` | System tray companion |
| `tsafe-azure` | Azure Key Vault client |
| `tsafe-aws` | AWS Secrets Manager and SSM client |
| `tsafe-gcp` | Google Secret Manager client |
| `tsafe-bitwarden` | Bitwarden CLI-backed import client |
| `tsafe-collab` | Experimental team collaboration layer |
| `tsafe-attest` | Attestation and release-support surfaces |
## Install choices
| Main CLI only | `cargo install tsafe-cli` |
| CLI plus agent/MCP/nativehost/tray companions | `cargo install tsafe` |
| Agent binary only | `cargo install tsafe-agent` |
| MCP server binary only | `cargo install tsafe-mcp` |
| Native host binary only | `cargo install tsafe-nativehost` |
| Tray binary only | `cargo install tsafe-tray` |
For reproducible release checks, install a specific version:
```sh
cargo install tsafe --version 1.1.1 --locked
```
## Project links
- Repository: <https://github.com/0ryant/tsafe>
- Crates.io bundle: <https://crates.io/crates/tsafe>
- API docs: <https://docs.rs/tsafe>
- CLI crate: <https://crates.io/crates/tsafe-cli>
- MCP crate: <https://crates.io/crates/tsafe-mcp>
## License
AGPL-3.0-or-later for v1.1.0 and later. Pre-v1.1.0 releases remain available
under the original MIT-OR-Apache-2.0 terms; see the repository root license
files.