Self-hosted credential proxy for agent workloads
One host holds the keys. Agents hold markers.
Mint is one small Rust service on a dedicated host in your Tailscale network. It keeps provider credential values in a single operator-owned file and substitutes non-secret markers in outbound request headers. Literal keys never appear in agent configuration, environment files, startup commands, prompts, or routine tool output.
Authorization: Bearer __mint.openai.default__
A non-secret alias marker. Within your systems, the credential value is stored only on the Mint host.
The boundary, stated plainly
Any caller that can reach Mint can choose any HTTP(S) destination and use any alias. A reachable malicious agent can tell Mint to send a credential to a server it controls — over plain HTTP if it wants — and read the value back. Mint performs no caller authorization and does not prevent this.
Tailscale reachability and dedicated-host custody are the entire security boundary. A compromised Tailscale device can use every alias. Root on the Mint host owns every value.
What Mint removes is routine accidental disclosure of literal provider keys. That is the whole trade: deliberate exfiltration by a reachable caller is accepted, ordinary key handling on agent machines is eliminated.
How it works
One file, one route, no policy layer
Markers, not keys
An agent places __mint.<alias>__ in a request header. Aliases are 1–128
lowercase ASCII letters, digits, ., _, or -; they
are non-secret data and safe to keep in agent configuration. Mint scans each header value
once and replaces every valid marker from its immutable startup map. An unknown alias
fails with 400 unknown credential alias before any upstream contact;
malformed marker text forwards unchanged. Substitution never touches the path, query, or
body.
Dedicated-host custody
Every value lives in one alias=value file on the Mint host: a regular file,
mode 0600, owned by the Mint service account, at most 64 KiB, loaded
once at startup. Rotation means a trusted operator edits the file over Tailscale SSH and
restarts the service. There is no reload path, no backup, no CRUD API, and no web UI.
A generic proxy
Mint exposes exactly two routes:
GET /healthz
ANY /proxy/{scheme}/{host}/{*rest}
The caller chooses the method, destination, headers, query, and streaming body. Mint relays the upstream response — including error statuses — unchanged, and never follows redirects. There are no provider adapters, host allowlists, SSRF rules, budgets, or response scrubbing. Each exchange emits one bounded, value-free audit record to local journald.
curl http://100.64.0.10:4949/proxy/https/api.example.com/v1/models \
-H "Authorization: Bearer __mint.vendor.default__"
Mint listens on its host's explicit Tailscale address and forwards the resolved header to the caller-chosen upstream.
Canonical contracts
The repository is the authority
This site is a summary. The accepted design, threat model, HTTP contract, and deployment guide live in the repository; where the two disagree, the repository wins.
- Documentation and operator quickstart — on this site
- VISION.md — accepted design and threat model
- docs/api.md — complete HTTP and marker contract
- docs/deploy.md — operator deployment and rollback guide
- CONTRIBUTING.md — boundaries for changes