Architecture
Terms below (ContainmentRule, WorkloadIdentity, SecretStore) are
defined once on Concepts.
Four crates
Section titled “Four crates”The workspace declares exactly four members
(Cargo.toml:2-7): mint-core, mint-broker, mint-cli, mint-mcp.
mint-core— the shared library: aliases, policy, audit ledger, redaction, capability files, custody traits. It has zero path dependency on any other Mint crate (crates/mint-core/Cargo.toml:9-25).mint-broker— the data plane: the HTTP proxy and typed-action handlers, authentication, the circuit breaker, and the audit gate (crates/mint-broker/src/lib.rs:1-12). It depends onmint-core(crates/mint-broker/Cargo.toml:18).mint-cli— the operator-facingmintbinary:serve,policy check,audit tail/verify/reconcile,alias list,capability issue/revoke, adoption scanning, and release cutover (crates/mint-cli/src/main.rs:36-90). It depends on bothmint-brokerandmint-core(crates/mint-cli/Cargo.toml:17-18).mint-mcp— the stdio MCP server: read-only observability over the same declarations the CLI inspects (crates/mint-mcp/src/lib.rs:1-9). It depends only onmint-core(crates/mint-mcp/Cargo.toml:17) — it never linksmint-brokerand never touchesSecretStore(crates/mint-mcp/src/lib.rs:103-106).
graph TD
core["mint-core<br/>(aliases, policy, audit, redact, custody traits)"]
broker["mint-broker<br/>(HTTP proxy, typed actions, auth, breaker)"]
cli["mint-cli<br/>(mint binary: serve, audit, policy, alias, capability)"]
mcp["mint-mcp<br/>(stdio MCP: read-only observability)"]
broker --> core
cli --> broker
cli --> core
mcp --> core
mint-cli's mint binary hosts mint-broker in-process for mint serve
(crates/mint-cli/src/main.rs:930-958); there is no separate broker
binary. Four of the fleet's five operator faces ship from this graph —
this CLI, the broker's HTTP API, the mint-mcp MCP server, and the
misty-mint roster skill; an SDK wrapper and a UI are not built
(crates/mint-cli/src/main.rs:1-4).
Trust boundaries
Section titled “Trust boundaries”graph LR
subgraph agent["Agent-accessible surface"]
A1["Agent process<br/>(sends placeholders, never secrets)"]
A2["mint-mcp<br/>(read declarations + audit, no secrets)"]
A3["mint CLI observability<br/>(alias list, audit tail, policy check)"]
end
subgraph mint["Mint trust boundary (mint-broker process)"]
B1["Authenticate + evaluate ContainmentRule"]
B2["Resolve SecretStore alias"]
B3["Forward, then scrub response"]
B4["Write AuditEvent"]
end
subgraph custody["Custody backend"]
C1["Keychain / env / systemd credential"]
end
V["Vendor API"]
A1 -- "placeholder request" --> B1
B1 --> B2
B2 -- "resolve (never returned)" --> C1
B2 --> B3
B3 -- "credentialed request" --> V
V -- "response" --> B3
B3 --> B4
B4 -- "scrubbed response" --> A1
A2 -.->|"reads only"| B4
A3 -.->|"reads only"| B4
The boundary that matters is the one around mint-broker: raw vendor
credential bytes may exist only in the configured custody backend, inside
mint-broker's own process, or with the intended vendor while a request is
in flight (VISION.md:31-40). Everything left of that boundary —
the agent process, mint-mcp, and the CLI's observability commands — never
receives a resolved secret. mint-mcp in particular reads straight from
disk through the same loaders mint-cli uses and never constructs a
SecretStore (crates/mint-mcp/src/lib.rs:103-106).
Within mint-broker, request handling for both execution modes follows
the same admission order — audit-ready check, authenticate, evaluate
policy, prepare, then a detached task for everything that touches a
vendor — so a typed action can never skip a gate the proxy enforces
(crates/mint-broker/src/typed_effect.rs:50-56). See
Request flow for the exact sequence.
Source map
Section titled “Source map”| Claim | Source | Lines |
|---|---|---|
| Workspace members | Cargo.toml | 2-7 |
mint-core has no internal deps | mint-core/Cargo.toml | 9-25 |
mint-broker → mint-core | mint-broker/Cargo.toml | 18 |
mint-cli → mint-broker, mint-core | mint-cli/Cargo.toml | 17-18 |
mint-mcp → mint-core only | mint-mcp/Cargo.toml | 17 |
| Broker data-plane doc | lib.rs | 1-12 |
| mint-mcp is read-only | lib.rs | 1-9 |
| Four faces ship, SDK/UI do not | main.rs | 1-4 |
| Non-possession invariant | VISION.md | 31-40 |
| Typed action mirrors proxy admission order | typed_effect.rs | 50-56 |