Quickstart
This path uses loopback authentication and a synthetic environment value.
It does not use a real vendor credential.
Run every step in a disposable directory and one terminal.
1. Prepare the declarations
Section titled “1. Prepare the declarations”mkdir -p .mint
cat > .mint/capabilities.yaml <<'EOF'version: 2capabilities: []EOF
cat > .mint/policy.yaml <<'EOF'version: 1default: denyrules: - actor: "local-agent" service: "127.0.0.1:18080" method: ["GET"] allowed_schemes: ["http"] path: "/echo" aliases: ["secret://example/default"] require_placeholder: true allow_private_network: true effect: allowEOF
cat > .mint/call-guards.yaml <<'EOF'version: 1guards: - actor: "local-agent" service: "127.0.0.1:18080" max_calls: 10 window_seconds: 60EOFThe policy permits one synthetic destination.
The policy requires a Mint placeholder.
The default denies every other request.
The call guard bounds this local test window.
2. Start a synthetic receiver
Section titled “2. Start a synthetic receiver”Run this receiver in the current terminal.
python3 - <<'PY' &from http.server import BaseHTTPRequestHandler, HTTPServer
class Receiver(BaseHTTPRequestHandler): def do_GET(self): value = self.headers.get("Authorization", "") body = ("received=" + value + "\n").encode() self.send_response(200) self.send_header("Content-Type", "text/plain") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body)
def log_message(self, *_): pass
HTTPServer(("127.0.0.1", 18080), Receiver).serve_forever()PYRECEIVER_PID=$!The receiver returns the header it receives.
It represents a vendor without using a real service.
3. Issue a development capability
Section titled “3. Issue a development capability”Run this command before starting the broker.
cargo run -p mint-cli -- capability issue \ --path .mint/capabilities.yaml \ --actor local-agent \ --expires-at "2030-01-01T00:00:00Z"The command prints one raw capability in its own JSON result.
Read that value without saving it to a file.
read -r -s MINT_CAPABILITYexport MINT_CAPABILITYThe shell environment holds the temporary development capability.
Never put it in source, argv, or committed configuration.
4. Start Mint with synthetic custody
Section titled “4. Start Mint with synthetic custody”The generated value stays in the process environment.
export MINT_AUTH_MODE=shared-secretexport MINT_SECRET_BACKEND=envexport MINT_SECRET_EXAMPLE_DEFAULT="synthetic-only-value-$$"export MINT_BIND_ADDR=127.0.0.1:4949export MINT_POLICY_PATH=.mint/policy.yamlexport MINT_CAPABILITIES_PATH=.mint/capabilities.yamlexport MINT_CALL_GUARDS_PATH=.mint/call-guards.yamlexport MINT_AUDIT_LOG_PATH=.mint/audit.logcargo run -p mint-cli -- serve > .mint/mint.log 2>&1 &MINT_PID=$!sleep 2Do not print or copy the environment value.
5. Make the brokered request
Section titled “5. Make the brokered request”Use Python to read the capability from the environment.
This keeps the temporary capability out of the request command's argv.
MINT_CAPABILITY="$MINT_CAPABILITY" python3 - <<'PY'import osimport urllib.request
request = urllib.request.Request( "http://127.0.0.1:4949/proxy/http/127.0.0.1:18080/echo", headers={ "X-Mint-Capability": os.environ["MINT_CAPABILITY"], "Authorization": "Bearer __mint.example.default__", },)with urllib.request.urlopen(request) as response: print(response.status) print(response.read().decode())PYThe receiver gets the synthetic value.
The caller receives a scrubbed response.
The placeholder never leaves the intended request path.
6. Prove denial and readiness
Section titled “6. Prove denial and readiness”Call a path without a matching rule.
MINT_CAPABILITY="$MINT_CAPABILITY" python3 - <<'PY'import osimport urllib.errorimport urllib.request
request = urllib.request.Request( "http://127.0.0.1:4949/proxy/http/127.0.0.1:18080/blocked", headers={ "X-Mint-Capability": os.environ["MINT_CAPABILITY"], "Authorization": "Bearer __mint.example.default__", },)try: urllib.request.urlopen(request)except urllib.error.HTTPError as error: print(error.code)PYThe command must print 403.
The receiver must not receive a second request.
Run the readiness checks while Mint is running.
cargo run -p mint-cli -- doctor --self-test-alias secret://example/defaultDoctor prints one JSON object per check.
Doctor returns a nonzero exit code when a required check fails.
Stop both processes after the run.
kill "$MINT_PID" "$RECEIVER_PID"Source map
Section titled “Source map”- README.md, lines 225–284
- README.md, lines 286–307
- crates/mint-cli/src/main.rs, lines 43–54
- crates/mint-cli/src/main.rs, lines 325–345
- crates/mint-broker/src/config.rs, lines 7–32
- crates/mint-broker/src/config.rs, lines 97–111
- crates/mint-broker/tests/auth_boundary.rs, lines 74–143
- crates/mint-broker/tests/exfil.rs, lines 118–164
- crates/mint-broker/tests/response_scrub.rs, lines 31–167
- crates/mint-core/tests/config_scan.rs, lines 223–269