Gateman
Documentation/Verify bot protection

Verify bot protection

capability_id: anti_bot.verify
display_name: Verify bot protection
ui_capability_key: verify_bot_protection
scope: anti_bot.verify
endpoints:
  - provider: turnstile
    method: POST
    path: /turnstile/get
  - provider: recaptcha
    method: POST
    path: /recaptcha/get
operations:
  turnstile: turnstile.credentials.get
  recaptcha: recaptcha.credentials.get
billable: true
environment: not_applicable

Purpose and authorization

This capability supplies an authenticated Gateman application with the configured credentials needed to integrate bot protection with its selected provider. The application performs browser-widget integration and native provider verification itself.

Gateman does not receive browser challenge tokens, call a provider's verification API, or return a completed bot-verification result.

Each request MUST use authenticated Contract v1 transport and the anti_bot.verify scope. The scope authorizes the two credential-bundle routes below. It does not require secrets:read or the provider's general Allow app retrieval setting.

Cloudflare Turnstile and Google reCAPTCHA currently have independent credential routes under this capability. Provider selection is made by the endpoint. This capability does not provision provider widgets, sites, domains, or provider accounts.

Implementation contract

Cloudflare Turnstile: POST /turnstile/get

POST /turnstile/get
Content-Type: application/json
X-GM-App: app_example
X-GM-Ts: 1791748800
X-GM-Sig: <Contract-v1-signature>

Intended body:

{}

An empty HTTP body is also accepted by the current implementation. No request parameters are supported. Browser tokens, remote IP addresses, hostnames, actions, scores, and other provider-native values MUST NOT be sent to this route. A non-empty JSON object is rejected.

Successful response:

{
  "ok": true,
  "site_key": "configured-site-key",
  "secret_key": "configured-secret-key"
}

Google reCAPTCHA: POST /recaptcha/get

POST /recaptcha/get
Content-Type: application/json
X-GM-App: app_example
X-GM-Ts: 1791748800
X-GM-Sig: <Contract-v1-signature>

Intended body:

{}

An empty HTTP body is also accepted. No request parameters are supported. A non-empty JSON object is rejected. Provider selection occurs because the application chose /recaptcha/get, not through a request field.

Successful response:

{
  "ok": true,
  "site_key": "configured-site-key",
  "secret_key": "configured-secret-key"
}

Malformed JSON returns HTTP 400 with {"ok":false,"error":"Invalid JSON"}. Any non-empty request object returns HTTP 400 with {"ok":false,"error":"This endpoint accepts no parameters"}.

Credentials

Turnstile uses these application-scoped configured names:

  • TURNSTILE_SITE_KEY
  • TURNSTILE_SECRET_KEY

reCAPTCHA uses:

  • RECAPTCHA_SITE_KEY
  • RECAPTCHA_SECRET_KEY

Both providers MAY be configured for one application. The site key is used by the provider widget or browser integration. The secret key is for trusted server-side use only. Applications MUST NOT expose a secret key to browser code, public responses, client-side bundles, logs, or prompts.

Gateman returns the configured bundle to the authenticated backend application; it does not return a provider verification result.

Environment behavior

These routes are environment-independent:

  • no environment field is required or accepted;
  • production, staging, and development do not select different bundles;
  • configured credentials are shared across those Gateman environment labels;
  • Gateman does not simulate verification or capture provider requests;
  • there is no environment-specific credential fallback.

Staging and development do not automatically select provider test credentials. If an application requires provider test credentials, it must configure and manage that provider arrangement itself.

Application verification responsibilities

The integrating application MUST:

  1. Integrate the selected provider's widget or challenge in the browser.
  2. Receive the browser-generated challenge token.
  3. Submit that token from its trusted backend directly to the provider's verification API.
  4. Interpret the provider's native response.
  5. Apply the resulting decision to the protected application action.

For Turnstile, the native server-side interface is Cloudflare Siteverify. For classic reCAPTCHA integrations, the native interface is Google Siteverify.

The application MUST NOT treat successful Gateman credential retrieval as evidence that a visitor passed a challenge. Gateman does not implement a provider-neutral token-verification request or response format, reCAPTCHA Enterprise verification, verification sessions, visitor tracking, or a universal human_verified result.

Provider-native requirements

Turnstile requires server-side Siteverify validation. Cloudflare documents that Turnstile tokens are single-use and time-limited; the application must process the provider's success, error, and contextual response fields as appropriate for its integration.

Classic reCAPTCHA response tokens are single-use and time-limited. reCAPTCHA v3 returns a score and action. Applications using score-based verification MUST establish and apply their own appropriate score and action policy. The application is also responsible for any provider-required hostname or other context checks.

Gateman does not enforce hostname, action, score, cdata, expiry, or replay rules.

Operation and replay obligations

The operation identifiers are:

ProviderOperationAccounting
Turnstileturnstile.credentials.getOne operation per admitted retrieval
reCAPTCHArecaptcha.credentials.getOne operation per admitted retrieval

Each admitted credential retrieval consumes one Gateman operation, whether the bundle is returned successfully or the accepted request fails because the credentials are missing or unavailable. Authentication, scope, malformed request, concurrency, and allowance rejections before operation admission do not consume an operation. Direct provider verification does not consume a Gateman operation.

The optional X-GM-Idempotency-Key is part of Contract v1 signing, but these routes do not implement a Gateman idempotency replay ledger. Repeating a retrieval performs another retrieval and consumes another operation. Do not borrow Email or SMS idempotency semantics for this capability.

Applications SHOULD securely reuse retrieved credentials and obtain updated credentials when their configuration changes. Credential retrieval SHOULD NOT occur for every visitor interaction or verification attempt. The routes use Gateman's shared application concurrency controls. No universal cache TTL or cache implementation is prescribed.

Verification tokens and verification results are not credential bundles and MUST NOT be treated as reusable credentials.

Errors and responses

The following are the relevant current Gateman-generated outcomes:

ConditionHTTPPublic behavior
Invalid JSON400Invalid JSON
Non-empty request parameters400This endpoint accepts no parameters
Missing configured credentials503Provider-specific missing-credentials error
Credential retrieval failure500Provider-specific credentials-unavailable error
Authentication or scope failure401Request rejected by Contract v1 authentication
Application concurrency exceeded429app_concurrency_limit_exceeded with Retry-After
Application concurrency guard unavailable503app_concurrency_guard_unavailable
Operation allowance exhausted403monthly_operation_limit_reached
Accounting unavailable503Operation accounting unavailable

Turnstile and reCAPTCHA provider verification failures are not Gateman responses. They are returned by the provider to the integrating application, which must decide whether to reject, retry with a fresh token, or apply another provider- and action-specific policy.

Implementation outcome

A correct integration should:

  1. Authenticate to Gateman with anti_bot.verify.
  2. Retrieve the selected provider's configured credential bundle.
  3. Keep the secret key on its trusted backend.
  4. Use the site key in the provider widget or browser integration.
  5. Submit browser challenge tokens directly to the provider from the backend.
  6. Interpret native provider results in the context of the protected action.
  7. Avoid unnecessary repeated Gateman credential retrievals.

Implementation instructions for agents

  • Select /turnstile/get or /recaptcha/get according to the customer's chosen provider; do not invent a generic verification endpoint.
  • Use authenticated Contract v1 transport with the anti_bot.verify scope and the supported empty request body.
  • Handle the route's HTTP status and Gateman error body before using returned credentials.
  • Keep secret_key backend-only and use site_key only for the provider's supported browser integration.
  • Perform native token verification directly with the selected provider.
  • Apply provider-required hostname, action, score, expiry, and other checks in the application where that provider and integration require them.
  • Do not treat credential retrieval as proof that a visitor passed a challenge.
  • Reuse credentials securely where appropriate and do not make a Gateman credential request for every visitor or token.

Reusable AGENTS.md block

<!-- gateman:begin capability=anti_bot.verify -->
- Use authenticated Contract v1 with the `anti_bot.verify` scope.
- Retrieve credentials from the selected provider route: `POST /turnstile/get`
  or `POST /recaptcha/get`, using the supported empty request body.
- Gateman supplies `site_key` and `secret_key`; it does not receive browser
  challenge tokens or perform provider verification.
- Keep `secret_key` on the trusted backend and never expose it to browser code,
  public responses, or client-side bundles.
- Use `site_key` in the selected provider's supported widget or challenge.
- Submit browser tokens directly from the backend to the selected provider's
  native verification API and apply that provider's required checks.
- Do not treat Gateman credential retrieval as proof that a visitor passed.
- Reuse retrieved credentials securely; do not request them for every visitor.
- Full capability reference:
  https://docs.getgateman.com/capabilities/anti_bot.verify/
<!-- gateman:end capability=anti_bot.verify -->