Public configuration
display_name: Public configuration
scope: client:read
endpoint:
method: POST
path: /config/get
billable: false
environment: required
There is no separate capability_id, ui_capability_key, or operation identifier for this route. client:read is a baseline application scope; Public Configuration is not a separately selectable console capability.
Purpose and authorization
Public Configuration returns a fixed bundle of intentionally non-secret provider configuration for the authenticated application. The values are appropriate for client-facing use, but the Gateman endpoint is not anonymous.
The application MUST authenticate with Contract v1 and MUST have the client:read scope. Gateman resolves configuration using the authenticated immutable app_id; an application cannot select another application's values.
This route does not require secrets:read, a credential-request identifier, or any provider Allow app retrieval setting. Those controls belong to POST /secrets/get. Provider operation scopes such as stripe:use and anti_bot.verify are also independent. Retrieving a publishable or site key does not authorize a provider operation.
Public Configuration returns only eligible public configuration values. Private provider credentials are not available through this endpoint.
Implementation contract
Request
POST /config/get
Content-Type: application/json
X-GM-App: app_example
X-GM-Ts: 1710000000
X-GM-Sig: <Contract-v1-signature>
The request MUST use ordinary signed Contract v1 authentication. The X-GM-Credential-Request-ID header is not required for this route. If supplied, it is accepted but not validated or used by the /config/get authentication or route path; it does not affect signature verification, request processing, or the response. Clients SHOULD ordinarily omit it. An X-GM-Idempotency-Key MAY be supplied and is covered by the Contract v1 signature, but this route has no endpoint-specific idempotency ledger.
The JSON body MUST contain exactly one field:
{
"environment": "staging"
}
Accepted values are production, staging, and development. The value is required, is normalized by trimming and lowercasing, and is signed as part of the request body. Additional fields are rejected. The caller MUST NOT submit configuration names: this route returns a predefined bundle and is not a list-all or caller-selected credential operation.
The four official Gateman clients can inject the configured environment for environment-aware routes. A direct implementation MUST inject the same field and MUST sign the exact transmitted JSON bytes.
Eligible values
| Provider | Stored name | Response field |
|---|---|---|
| Stripe production | STRIPE_PUBLISHABLE_KEY | config.stripe.publishable_key |
| Stripe test | STRIPE_PUBLISHABLE_KEY_TEST | config.stripe.publishable_key |
| Cloudflare Turnstile | TURNSTILE_SITE_KEY | config.turnstile.site_key |
| Google reCAPTCHA | RECAPTCHA_SITE_KEY | config.recaptcha.site_key |
Stripe selection is environment-aware:
| Request environment | Selected Stripe value |
|---|---|
production | STRIPE_PUBLISHABLE_KEY |
staging | STRIPE_PUBLISHABLE_KEY_TEST |
development | STRIPE_PUBLISHABLE_KEY_TEST |
There is no fallback between Stripe production and test values. Turnstile and reCAPTCHA site keys use their shared configured values across environments; there are no additional environment-specific site-key names.
The route MUST NOT disclose Stripe secret keys, Stripe webhook secrets, Turnstile secret keys, reCAPTCHA secret keys, private provider credentials, arbitrary custom credentials, or provider configuration metadata.
Successful response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: no-store
{
"ok": true,
"config": {
"stripe": {
"publishable_key": "pk_test_example"
},
"turnstile": {
"site_key": "0x_example"
},
"recaptcha": {
"site_key": "6Lc_example"
}
}
}
The values above are fictitious examples. Values that are not configured or otherwise unavailable are omitted. Empty provider groups are omitted, and an entirely empty configuration is valid:
{
"ok": true,
"config": {}
}
Errors
Gateman returns the shared JSON error shape for errors generated by this route:
{
"ok": false,
"error": "Invalid JSON"
}
The applicable outcomes are:
| Condition | Status and response error |
|---|---|
| Missing or invalid authentication, stale timestamp, inactive application, or source-IP rejection | HTTP 401; the authentication error, such as Missing required auth headers, Invalid signature, Unknown app, or Authentication failed. |
Missing client:read | HTTP 401, Scope not allowed. |
| Application concurrency limit | HTTP 429, app_concurrency_limit_exceeded, with Retry-After: 1. |
| Application concurrency guard unavailable | HTTP 503, app_concurrency_guard_unavailable. |
| Invalid JSON | HTTP 400, Invalid JSON. |
| Missing environment | HTTP 400, Application environment is required. |
| Unsupported environment | HTTP 400, Unsupported application environment. |
Any field other than environment | HTTP 400, This endpoint accepts only environment. |
| Public configuration rate-limit dependency unavailable | HTTP 503, Public configuration rate limit unavailable. |
| Dedicated request-frequency limit exceeded | HTTP 429, public_config_rate_limit_exceeded, with Retry-After. |
| Public configuration retrieval failure | HTTP 500, Public configuration unavailable. |
Unavailable individual values do not produce an error; they are omitted from an otherwise successful response. There are no name-selection or excessive-name errors because callers cannot submit names.
Rate limits, accounting, and runtime reuse
Public Configuration is non-billable. It does not create a billable operation reservation or completion record, and it does not consume the monthly billable operation allowance.
The endpoint has a separate fixed-window limit of 10 requests per application per UTC hour. The 11th request in the current UTC-hour window returns:
HTTP/1.1 429 Too Many Requests
Retry-After: <seconds until the UTC-hour window ends>
{
"ok": false,
"error": "public_config_rate_limit_exceeded"
}
Authenticated, valid requests reaching this limiter consume its capacity, including requests that return an empty configuration. Rate-limit rejections also increment the limiter's attempt counter under the current implementation. Authentication and request-validation failures that occur before the limiter do not consume its capacity. The shared application concurrency guard also applies.
HTTP response caching and application-managed runtime reuse are different:
- Gateman returns
Cache-Control: no-store, which governs HTTP response caching. Applications MAY retain extracted public configuration values in application-managed runtime state and reuse them as appropriate. - An application SHOULD retrieve configuration at initialization or deliberate refresh points rather than repeatedly during ordinary user interactions.
- An application MAY deliberately persist the values according to its own security and freshness decisions.
- The application SHOULD reuse the values for later application operations and MUST NOT request them for every page load, user interaction, payment operation, or anti-bot render.
- A deliberate refresh MUST respect the 10-request-per-UTC-hour limit.
- A Gateman configuration change is visible on the next uncached retrieval; it does not automatically update values already retained by the application.
Gateman does not provide a universal runtime TTL, freshness guarantee, storage mechanism, or invalidation protocol. The WordPress integration's 12-hour success cache and 15-minute error cache for Stripe publishable-key status are integration-specific choices, not a universal Gateman contract.
Official clients do not automatically retry. A caller implementing retries MUST account for the dedicated request-frequency limit and SHOULD avoid unnecessary repeated retrievals.
Implementation outcome
A correct integration produces these independently assessable outcomes:
- It authenticates and retrieves the fixed public configuration bundle for its own application.
- It sends the required environment and receives the correct Stripe production/test publishable key for that environment.
- It handles missing values and omitted provider groups without assuming that every provider is configured.
- It keeps private provider credentials out of client-facing configuration.
- It reuses public configuration in application-managed runtime state instead of requesting it for every user interaction; this is distinct from HTTP response caching.
- It refreshes deliberately while respecting the request-frequency limit and the HTTP
no-storeresponse policy. - It handles authentication, concurrency, rate-limit, storage, and validation errors according to their actual HTTP status and error string.
- It does not treat Public Configuration retrieval as permission to perform a Stripe, Turnstile, reCAPTCHA, or other provider operation.
Implementation instructions for agents
- SHOULD use an official Gateman client where appropriate. A direct HTTP implementation MUST conform to Contract v1.
- The integration MUST use authenticated
POST /config/getwith theclient:readscope and a requiredenvironmentofproduction,staging, ordevelopment. - It SHOULD ordinarily omit
X-GM-Credential-Request-IDfor this route. It is not required and, if supplied, is not validated or used by the/config/getauthentication or route path. - It MUST NOT submit configuration names or add a caller-controlled field selector; the response bundle is fixed.
- It MUST use the Stripe production value only for
production, and the Stripe test value forstaginganddevelopment. - It MUST treat Turnstile and reCAPTCHA site keys as shared configured values and MUST NOT invent environment-specific site-key names.
- It MUST handle omitted values and provider groups explicitly.
- It MUST keep private provider credentials out of this configuration path and MUST NOT grant
secrets:readmerely to retrieve public values. - It MUST NOT require provider Allow app retrieval settings for this route.
- It SHOULD retrieve configuration at initialization or deliberate refresh points and MAY retain extracted values in application-managed runtime state for reuse. This is distinct from HTTP response caching.
- It MUST respect the 10-request-per-UTC-hour limit and handle
Retry-Afteron429responses. - It SHOULD NOT add automatic retries that poll the endpoint repeatedly.
- It MUST NOT treat a returned public key as provider API authorization.
- It MUST NOT convert the endpoint into an anonymous configuration service, general credential store, or CDN.
Reusable AGENTS.md block
<!-- gateman:begin capability=public-configuration -->
- Retrieve public provider configuration only through authenticated
`POST /config/get` using the application's baseline `client:read` scope.
- Supply exactly one required JSON field: `environment`, with value
`production`, `staging`, or `development`.
- The response is a fixed bundle. Handle omitted Stripe, Turnstile, and
reCAPTCHA values; do not request names or expect private credentials.
- Stripe uses the production publishable key for `production` and the test
publishable key for `staging` and `development`. Turnstile and reCAPTCHA
site keys are shared across environments.
- Gateman remains authenticated even though returned values are public. This
route does not require `secrets:read` or provider **Allow app retrieval**.
- `X-GM-Credential-Request-ID` is not required for this route. Applications
SHOULD ordinarily omit it; if supplied, it is not validated or used by the
`/config/get` authentication or route path.
- Retrieve at initialization or deliberate refresh points rather than
repeatedly during ordinary user interactions. Applications MAY retain
extracted values in application-managed runtime state and reuse them.
- Gateman returns `Cache-Control: no-store`, which governs HTTP response
caching; it does not prohibit application-managed runtime reuse. Do not
assume a universal local TTL or automatic invalidation guarantee.
- The route is limited to 10 requests per application per UTC hour. Respect
`Retry-After` on `429` responses and do not add unnecessary automatic
retries.
- Public Configuration does not authorize Stripe, Turnstile, reCAPTCHA, or
other provider operations. Keep private provider credentials separate.
- Full reference: https://docs.getgateman.com/public-configuration/
<!-- gateman:end capability=public-configuration -->
