Configuration
Mint reads environment settings at startup.
Mint reads policy and capability declarations from configured files.
Use declarations for caller identity, destinations, aliases, and protocol rules.
Use environment settings for process behavior and custody selection.
Configuration layers
Section titled “Configuration layers”Mint applies configuration in this order:
- Complete declaration-path flags passed to
mint serveormint doctor. - Environment variables.
- Built-in defaults.
The four declaration-path flags are --policy-path, --call-guards-path, --capabilities-path, and --aliases-path.
Supply all four flags together.
Mint validates explicit aliases and capabilities before serving.
A configured MINT_CALL_GUARDS_PATH must exist and parse.
An unset call-guards path uses optional .mint/call-guards.yaml.
The systemd unit supplies stable declaration paths through ExecStart.
Do not put credential values in declaration files.
Do not put credential values in command arguments.
Declaration files
Section titled “Declaration files”| Declaration | Owns | Required shape |
|---|---|---|
| Policy | Actor, service, method, path, alias, scheme, and private-network rules | Versioned YAML with a deny default |
| Aliases | Non-secret names for custody entries | Versioned YAML with alias descriptions |
| Capabilities | Local bearer capability hashes and scopes | Version 2 YAML |
| Call guards | Operational call caps by actor and service | Version 1 YAML |
The policy uses first-match evaluation.
An unmatched request receives the configured deny result.
The capability file must be empty in Tailnet mode.
The call-guard file separates availability controls from credential policy.
Legacy policy limits remain a compatibility path.
Mint warns when a policy still contains legacy limits.
Prefer evidence-based call guards with positive time windows.
Every deployed legacy limit currently declares a daily window_seconds: 86400.
The deployment carries no process-lifetime caps.
Windowing an existing legacy limit does not move it into the call-guard file.
The deployed call-guard file still declares guards: [].
Environment variables
Section titled “Environment variables”The following values come from BrokerConfig::from_env.
| Variable | Default | Effect |
|---|---|---|
MINT_BIND_ADDR | 127.0.0.1:4949 | Listener address |
MINT_POLICY_PATH | .mint/policy.yaml | Policy declaration |
MINT_CAPABILITIES_PATH | .mint/capabilities.yaml | Capability declaration |
MINT_AUDIT_LOG_PATH | .mint/audit.log | Active audit segment |
MINT_CALL_GUARDS_PATH | .mint/call-guards.yaml when unset | Operations guard declaration |
MINT_UPSTREAM_TIMEOUT_MS | 10000 | Upstream connection and body-read deadline |
MINT_MAX_RESPONSE_BODY_BYTES | 8388608 | Response body limit |
MINT_SECRET_TIMEOUT_MS | 3000 | Custody resolution deadline |
MINT_BREAKER_THRESHOLD | 3 | Consecutive host failures before opening |
MINT_BREAKER_OPEN_SECS | 30 | Host breaker open interval |
MINT_DRAIN_BOUND_MS | 10000 | Graceful shutdown drain bound |
MINT_TAILSCALE_BIN | /usr/local/bin/tailscale | Whois executable |
MINT_TAILSCALE_SOCKET | /var/run/tailscale/tailscaled.sock | Whois control socket |
MINT_AUDIT_RECOVERY_INTERVAL_MS | 5000 | Audit recovery retry interval |
MINT_AUDIT_DISK_FLOOR_BYTES | 268435456 | Doctor disk-pressure floor |
MINT_FIRECRAWL_BASE_URL | https://api.firecrawl.dev | Typed-action vendor base URL |
MINT_FIRECRAWL_SCRAPE_TIMEOUT_MS | 30000 | Typed-action scrape deadline |
MINT_FIRECRAWL_INTERACT_TIMEOUT_MS | 60000 | Typed-action interact deadline |
MINT_FIRECRAWL_STOP_TIMEOUT_MS | 15000 | Typed-action stop deadline |
The release readiness command also reads MINT_HEALTH_WAIT_MS.
Its default is 120000 milliseconds.
Its maximum is 3600000 milliseconds.
Invalid core numeric settings fall back to their defaults.
Rotation settings use stricter validation.
Audit rotation and retention
Section titled “Audit rotation and retention”Set MINT_AUDIT_ROTATE_MAX_BYTES to rotate after a positive byte bound.
Set MINT_AUDIT_ROTATE_MAX_AGE_SECS to rotate after a positive age bound.
Set MINT_AUDIT_RETAIN_MAX_SEGMENTS to retain a positive segment count.
Unset rotation settings disable rotation and retention.
Retention without byte or age rotation fails startup.
Zero, negative, malformed, or non-UTF-8 rotation values fail startup.
The ledger keeps an append-only hash chain across rotated segments.
See operations for audit commands.
Authentication modes
Section titled “Authentication modes”SharedSecretAuth
Section titled “SharedSecretAuth”SharedSecretAuth accepts a declared bearer capability.
It accepts only loopback connections.
It is local-only.
Use MINT_AUTH_MODE=shared-secret or MINT_AUTH_MODE=dev for local development.
An unset MINT_AUTH_MODE also selects this zero-configuration local mode.
A valid token from a non-loopback peer still fails.
TailnetWhoisAuth
Section titled “TailnetWhoisAuth”TailnetWhoisAuth resolves the connection peer through tailscale whois.
It ignores caller-supplied identity headers.
An unresolved peer fails closed.
It uses bounded whois work.
It is the production mode.
Set MINT_AUTH_MODE=tailnet in the production host environment.
Keep the production capabilities declaration empty.
Any unrecognized set value fails toward Tailnet mode.
A typo cannot silently select bearer authentication.
Custody backends
Section titled “Custody backends”Mint resolves aliases through one selected backend.
| Backend | Selection | Custody boundary |
|---|---|---|
| Keychain | Unset or MINT_SECRET_BACKEND=keychain | macOS login keychain |
| Env | MINT_SECRET_BACKEND=env or environment | Runtime-provided MINT_SECRET_* names |
| Directory | MINT_SECRET_BACKEND=directory | Explicit directory or service-private credentials |
Keychain mode uses MINT_SECRET_ACCOUNT when present.
Keychain mode otherwise uses the process account convention.
Directory mode prefers MINT_SECRET_DIRECTORY.
Directory mode otherwise uses CREDENTIALS_DIRECTORY.
Directory mode fails when neither directory is available.
Do not copy custody files into a release bundle.
Do not print custody values during a self-test.
Reloadability
Section titled “Reloadability”A SIGHUP reloads policy and capabilities as one atomic generation.
A request uses one complete declaration snapshot.
A rejected candidate leaves the last-known-good snapshot active.
A rejected reload emits a sanitized audit event.
A SIGHUP also retries an unhealthy audit sink immediately.
The background recovery loop retries the audit sink at a fixed interval.
The following settings require restart:
- Bind address.
- Authentication mode.
- Custody backend and account.
- Custody directory.
- Call guards.
- Timeouts.
- Breaker settings.
- Drain bound.
- Audit rotation, retention, disk floor, and recovery interval.
- Typed-action endpoint and timeouts.
Use operations for the reload procedure.
Validation
Section titled “Validation”Use mint policy check <policy-file> for static policy validation.
Use mint doctor for effective startup checks.
Use mint release preflight for an immutable candidate bundle.
Doctor reports pass, fail, and skip for named checks.
Doctor never prints resolved custody values.
Read verification for each check's proof boundary.
Source map
Section titled “Source map”- Broker configuration defines settings and defaults.
- Mode and backend parsing defines authentication and custody selection.
- Environment loading defines precedence inputs and validation.
- Authenticator boundary enforces loopback bearer access.
- Tailnet authentication resolves peer identity with a timeout.
- Atomic reload defines snapshot ownership.
- Reload implementation defines successful and rejected reloads.
- CLI path validation defines complete flag precedence.
- Doctor checks define effective startup checks.
- Policy declaration defines the version, deny default, and legacy-limit windowing rationale.
- Alias declaration defines non-secret alias names.
- Capability declaration keeps production bearer capabilities empty.
- Call-guard declaration defines the versioned operations shape and the empty deployed guard list.
- Legacy call-limit ratchet pins zero process-lifetime legacy limits.