How to enable API-key authentication

Problem: you want mcpgw to authenticate clients directly instead of relying on an external reverse proxy.

Solution: generate an API key, store only its Argon2id hash in mcpgw.yaml, and enable the auth: block.

Generate a key

mcpgw key generate --label=claude-desktop-prod --expires=2160h

The command prints the raw key once and a YAML entry:

auth:
  enabled: true
  keys:
    - id: "claude-desktop-prod"
      hash: "argon2id$v=19$m=65536,t=3,p=2$..."
      scopes: ["*"]
      created_at: "2026-05-01T14:23:01Z"
      expires_at: "2026-08-01T14:23:01Z"

Do not commit the raw KEY: value. Clients send it as:

Authorization: Bearer mcpgw_live_...

Use a custom header

For clients that cannot send Bearer auth:

auth:
  enabled: true
  header: X-MCPGW-Key
  scheme: ""
  keys:
    - id: "ci-pipeline"
      hash: "argon2id$v=19$m=65536,t=3,p=2$..."

With scheme: "", mcpgw reads the raw header value.

scopes is reserved for future per-key authorization. In this release, a valid non-expired key authenticates the client; policy rules still decide which tools are allowed.

Each gateway process permits two cache-miss API-key verifications at a time. Those Argon2id derivations are memory-intensive by design; pair API-key auth with input_rate_limit (enabled by the Helm chart) and an ingress rate limit when the gateway is reachable beyond a trusted private network.

Rotate keys

Add the new key entry, reload, update clients, then remove the old key entry and reload again:

docker kill --signal=HUP mcpgw

The auth store is swapped atomically on reload. Cached successful key checks are cleared on every swap, so removed keys stop working immediately after reload.

Verify

Missing, invalid, and expired keys return HTTP 401 with JSON-RPC error -32005 unauthorized and WWW-Authenticate: Bearer realm="mcpgw".

Successful requests include auth_key_id and auth_result: "ok" in the audit log. Failed auth attempts include auth_result: "missing", "invalid", or "expired".