# tsafe

> Local secret runtime, encrypted developer vault, process-scoped secret
> injection, and bounded MCP command gateway for agentic development.

[![crates.io](https://img.shields.io/crates/v/tsafe.svg)](https://crates.io/crates/tsafe)
[![docs.rs](https://docs.rs/tsafe/badge.svg)](https://docs.rs/tsafe)
[![License: AGPL-3.0-or-later](https://img.shields.io/badge/License-AGPL%20v3+-blue.svg)](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:

| Binary | Purpose |
|---|---|
| `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

| Concept | Meaning |
|---|---|
| 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:

| Tool | Purpose |
|---|---|
| `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

| Property | Implementation |
|---|---|
| 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

| Command | What it does |
|---|---|
| `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

| Artifact | Default shape |
|---|---|
| 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

| Crate | Role |
|---|---|
| `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

| Goal | Install |
|---|---|
| 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.
