Configure credential verifiers

Diátaxis quadrant: How-to. Audience: integrators and operators running humanymous Gate (“Gate” after first mention) who want returning, verifiable clients to skip the friction the detection pipeline would otherwise impose.

Gate can trust-upgrade a request that proves possession out of band, forwarding it without a behavioral fight. Three independent mechanisms are supported, each off by default. This guide wires all three. They matter most alongside the attestation floor: with a verifier configured, a possession-holder clears an attested route without solving a Pass; without one, every user must.

A missing or invalid credential is never an accusation — it is a no-op. The request simply falls through to the normal detection pipeline. Possession is a fast-path, not a gate.

Demo keys for every mechanism are generated by go run ./scripts/gen-demo-keys. The reference ships a runnable compose overlay and a consistency check for each; production supplies its own enrollment.

WebAuthn — proof of possession by a registered passkey

A returning user asserts a registered WebAuthn credential; Gate verifies the ES256 signature and the monotonically advancing signature counter (a replayed, non-advancing assertion is rejected).

Enable it with -webauthn-creds <file>, one credential per line:

# creds.txt — "<credentialId> <base64url-SPKI-ECDSA-P256-public-key>"
demo-credential-1 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...

Bind the assertion to your site so one minted for another origin cannot be replayed:

export HMN_WEBAUTHN_ORIGIN=https://app.example.com   # empty = origin check off
export HMN_WEBAUTHN_RPID=app.example.com             # empty = RP-ID check off

The client presents the assertion in the Webauthn-Assertion header. Verify your wiring with node scripts/assert-webauthn.mjs (see deployments/compose/webauthn.yaml).

Because WebAuthn credentials are linkable, WebAuthn is also the mechanism the ceiling-guard #2 fan-out cap applies to: one credential fast-pathing from more than CredFanoutCap distinct /24 subnets (default 8) has its upgrade withheld on attested routes and reverts to Pass.

Privacy Pass — an unlinkable attestation token

A client redeems a Privacy Pass Private Access Token (RFC 9577) that a trusted issuer minted after the client proved humanity or attestation to the issuer. Gate verifies the token’s RSA blind signature against the issuer public keys.

Enable it with -pat-issuers <file>, a PEM file of one or more issuer public keys:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
-----END PUBLIC KEY-----

The client presents the token in the Authorization: PrivateToken token="<base64>" header. Verify with node scripts/assert-privacypass.mjs (see deployments/compose/privacypass.yaml).

Privacy Pass keyids are unlinkable by design, so the fan-out cap does not apply to PAT — capping it would collapse every redeemer worldwide onto one bucket.

Web Bot Auth — a signed, allow-listed automated agent

A cooperating automated client (a search crawler, a partner integration) signs its request with an HTTP Message Signature (RFC 9421) from a key you allow-list. A valid signature from an allow-listed key is a trust-upgrade; a signature that claims an allow-listed key but fails to verify is a forgery and is denied; an unknown key is neutral (falls through).

Enable it with -agent-keys <file>, one key per line:

# trusted.txt — "<keyid> <base64url-Ed25519-public-key>"
crawler-1 rOx3216xrKQ7uUDF3bECbY0Kk9Xl2c8...

The signature must cover the request line (not just the host), and a single-use nonce guards against replay. Verify with node scripts/assert-webbotauth.mjs (see deployments/compose/webbotauth.yaml).

Web Bot Auth is for clients that are supposed to fan out across many networks, so — like PAT — the fan-out cap does not apply.

Which one to reach for

Mechanism Flag Proves Fan-out cap applies
WebAuthn -webauthn-creds A specific registered device/passkey holds the credential. Yes (ceiling-guard #2)
Privacy Pass -pat-issuers The client redeemed an unlinkable humanity/attestation token. No (unlinkable by design)
Web Bot Auth -agent-keys An allow-listed automated agent signed this exact request. No (agents fan out by design)

You can enable any combination. On an attested route, a request carrying any one of them clears the floor without a Pass.