# tsafe-core

Core library for the [tsafe](https://crates.io/crates/tsafe-cli) local secret
vault and authority runtime.

Provides the encrypted vault (Argon2id KDF + XChaCha20-Poly1305 by default,
AES-256-GCM via the `fips` feature), RBAC access profiles, an append-only audit
log with session-local HMAC links, CloudEvents eventing, OS keyring / biometric
integration, and all foundational data types.

The core crate writes local operator evidence; it is not a telemetry client.
CloudEvents types are projection/export records over local audit/event material,
not a vendor analytics lane, and they must never carry secret values.

For Agent Authority Firewall work, `tsafe-core` is the shared crate for
authority contracts, safe command execution decisions, refusal metadata, and
audit receipts. The MCP server lives in `tsafe-mcp`, but its bound MCP mode uses
the contract and authority types from this crate.

## Should you depend on this directly?

Most users should install the CLI:

```
cargo install tsafe-cli
```

Depend on `tsafe-core` when you need programmatic vault access from Rust code —
for example, tooling that reads or writes secrets as part of a build pipeline or
a custom secret-rotation job.

## Key types

| Type | Purpose |
|---|---|
| `Vault` | Open, read, write, rotate, and snapshot an encrypted vault file |
| `VaultFile` / `SecretEntry` | On-disk serde types (schema `tsafe/vault/v1`) |
| `SafeError` / `SafeResult<T>` | Typed error enum; all fallible APIs return this |
| `AuditLog` / `AuditEntry` | Append-only audit trail (`.audit.jsonl`) with session-local HMAC-SHA256 links |
| `RbacProfile` | `ReadOnly` vs `ReadWrite` access gating with role-scoped key derivation |
| `keyring_store` | OS credential store integration (Windows DPAPI / macOS Touch ID Keychain / libsecret) |
| `snapshot` | Point-in-time vault backups and restore |
| `gen` | Secure passphrase and token generation |
| `totp` | TOTP code computation |
| `events` | CloudEvents-compatible vault event emission |
| `contracts` | Authority contract evaluation (exec policy, network policy, trust levels) |
| `authority` | Bound MCP decisions, refusal payloads, receipt metadata, and authority mode |
| `deny_reason` | Stable denial reasons for policy, diagnostics, and command execution |

## Agent Authority Firewall foundations

Contracts are the policy source for `tsafe exec --contract NAME -- CMD` and for
the bound MCP normal form:

```sh
tsafe mcp serve --profile <profile> --contract <contract> --workdir <repo>
```

Each bound MCP server instance fixes one profile, one contract, and one workdir
at startup. Separate host entries such as `tsafe-cordance` and `tsafe-cortex`
should use separate server processes. No-secret diagnostic contracts are
represented by contracts that compile to zero required and zero injected
secrets while still carrying allowed targets, trust posture, redaction, and
audit behavior.

## Example

```rust
use std::path::Path;
use tsafe_core::vault::Vault;
use tsafe_core::errors::SafeResult;

fn read_secret(vault_path: &Path, password: &[u8], key: &str) -> SafeResult<String> {
    let vault = Vault::open(vault_path, password)?;
    vault.get(key)
}

fn write_secret(vault_path: &Path, password: &[u8], key: &str, value: &str) -> SafeResult<()> {
    let mut vault = Vault::open(vault_path, password)?;
    vault.set(key, value, &Default::default(), false)?;
    vault.save()?;
    Ok(())
}
```

Key names must start with a letter or underscore and may contain letters, digits,
`_`, `-`, `.`, and `/` (no consecutive separators). Namespace-style keys like
`myapp/DB_PASSWORD` and `github.com.token` are valid.

## Vault encryption

| Layer | Algorithm |
|---|---|
| KDF | Argon2id (m=65536 KiB, t=3, p=1 by default) |
| Cipher (default) | XChaCha20-Poly1305 |
| Cipher (`fips` feature) | AES-256-GCM |
| Key schedule | HKDF-SHA256 (purpose-separated sub-keys) |
| Team vault wrapping | age X25519 |

The vault file is plain JSON with all secret values individually encrypted.
Atomic writes (temp file + rename) prevent partial-write corruption.

## Feature flags

| Feature | What it adds | Default |
|---|---|---|
| `fips` | AES-256-GCM cipher via `aes-gcm`; XChaCha20-Poly1305 remains available | no |
| `nats` | NATS messaging backend for the events module | no |
| `biometric` | Activates the biometric-gated keyring path in `keyring_store` (macOS Touch ID / Windows Hello) | no |

## Logging

`tsafe-core` emits structured traces via the [`tracing`](https://docs.rs/tracing) crate.
No output appears unless a subscriber is installed by the caller. All
secret-bearing parameters (`password`, `value`, `key`) are skipped in every
`#[instrument]` call site.

## 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.

Repository: <https://github.com/0ryant/tsafe>
