---
title: "Settings | FoxAuth"
description: "Every server setting, grouped the way the console groups them, with its default and the flag it depends on."
canonical: "https://foxauth.dev/docs/reference/settings/"
lastmod: "2026-10-16T14:32:47+03:00"
---
Settings

Documents unreleased changes made after v1.1.0 (commit 16f191bb)

This page is generated from the main branch. The published image
ghcr.io/redfox-soft/oauth-server-ts:latest is v1.1.0
and may not have everything listed here.

Settings are edited in the console under Settings and take effect in the instance that saves them. Each card below says so, and names the reason where a setting has to wait for the next start instead. When a flag is off, the capability's endpoint is not served at all.

Grants & flows
Which OAuth and OpenID flows this server issues tokens through.

authorization.allowOmittingSingleRegisteredRedirectUri
Allow omitting a single registered redirect_uri
Let a client with one registered redirect_uri omit it from requestsTypebooleanDefaultfalseRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
When a client has exactly one registered redirect_uri, allow authorization and token requests to omit redirect_uri and resolve it to that single value. Off by default (secure).

clientCredentials.enabled
Enable client_credentials grant
Accept grant_type=client_credentials at the token endpointTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables grant_type=client_credentials on the token endpoint.

deviceFlow.enabled
Enable Device Authorization Grant (RFC 8628)
Serve the device authorization grant for input-constrained devicesTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables the Device Authorization Grant.

deviceFlow.charset
User-code charset
Which characters generated user codes are drawn fromTypeenumDefault"base-20"Optionsbase-20, digitsRequiresdeviceFlow.enabledTakes effectwhen you save itDetails
Character set for generated user codes. "digits" suits a device paired from a numeric keypad or a TV remote; "base-20" packs more entropy into the same number of characters.

deviceFlow.mask
User-code mask
The shape of a generated user codeTypestringDefault"****-****"RequiresdeviceFlow.enabledTakes effectwhen you save itDetails
Template for user codes; * is replaced by a random charset char. Every * is one character of entropy, so shortening the template to spare the person typing it also shortens what an attacker has to guess.

ciba.enabled
Enable CIBA flow
Serve the client-initiated backchannel authentication flowTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables Core CIBA flow.

ciba.deliveryModes
Token delivery modes
How a client collects a CIBA token once the user approvesTypestring-arrayDefault["poll"]Optionspoll, pingRequiresciba.enabledTakes effectwhen you save itDetails
Supported CIBA token delivery modes.

conformIdTokenClaims
Conform ID Token claims
Carry end-user claims in an ID Token only where the spec requiresTypebooleanDefaulttrueRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
When on, an ID Token carries End-User claims only where the requested response_type is id_token. Turning it off includes scope-derived claims in ID Tokens issued from other response types. On by default (spec-conformant).

Request security
How an authorization request is proven, bound and protected.

pkce.required
Require a PKCE code challenge
Demand proof of possession on every authorization requestTypebooleanDefaulttrueRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
On by default, and it governs only clients that authenticate at the token endpoint: a client registered with no client authentication is always required to send a code_challenge, and no setting here changes that. Turning this off is your assertion that your authenticating clients implement the OpenID Connect nonce mechanism correctly — OAuth 2.1 permits dropping the demand only for a confidential client and only where the authorization server has that assurance. Prefer leaving it on: a code challenge is the stronger protection, because it lets this server refuse an injected authorization code before issuing any token, where nonce leaves the client to reject an ID token afterwards. The reason to turn it off is OpenID Connect Basic certification, whose test suite sends a challenge in one module of thirty-five.

par.enabled
Enable PAR (RFC 9126)
Serve the pushed_authorization_request endpointTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables the pushed_authorization_request endpoint.

par.allowUnregisteredRedirectUris
Allow unregistered redirect_uris via PAR
Let authenticated PAR clients use redirect_uris they never registeredTypebooleanDefaultfalseRequirespar.enabledRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Lets authenticated PAR clients use unregistered redirect_uri values (no sector_identifier_uri).

dpop.enabled
Enable DPoP (RFC 9449)
Sender-constrain tokens with application-layer proof-of-possessionTypebooleanDefaultfalseTakes effectwhen you save itDetails
Sender-constrains tokens via application-layer proof-of-possession.

dpop.requireNonce
Require DPoP nonce
Require a server-issued nonce in every DPoP proofTypebooleanDefaultfalseRequiresdpop.enabledTakes effectwhen you save itDetails
Requires a server-provided DPoP nonce. The secret the nonces are derived from is managed by the server; there is nothing to supply.

responseMode.jwt.enabled
Enable JARM
Return authorization responses as a signed JWT (JARM)TypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables JWT Secured Authorization Responses.

fapi.enabled
Enable FAPI behaviours
Apply the extra Authorization Server behaviours of the FAPI profileTypebooleanDefaultfalseTakes effectwhen you save itDetails
Extra Authorization Server behaviours defined in the FAPI profile.

encryption.enabled
Enable encryption features
Allow encrypted UserInfo, ID Tokens and Request ObjectsTypebooleanDefaultfalseTakes effectwhen you save itDetails
Encrypted UserInfo/ID Tokens and signed/encrypted Request Objects.

claimsParameter.enabled
Enable the claims parameter
Accept and validate the claims request parameterTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables use and validation of the claims parameter.

mTLS.enabled
Enable mTLS features (RFC 8705)
Authenticate clients by TLS certificateTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables Mutual TLS client authentication / certificate-bound tokens. TLS ends at the proxy in front of this server, so the client certificate arrives in a header the proxy sets; see "Trust the proxy’s certificate header".

mTLS.trustProxyCertificateHeader
Trust the proxy’s certificate header
Read the client certificate from the header the proxy setsTypebooleanDefaultfalseRequiresmTLS.enabledRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Whether the client certificate is read from the `Client-Cert` header (RFC 9440) or, failing that, a base64 `x-client-cert`. This one has a wrong answer in each direction. Turn it ON only when the TLS-terminating proxy in front of this server verifies the client certificate, sets the header, and removes or overwrites any copy an incoming request already carries: with it on and a proxy that passes the header through, anyone can send a certificate — which is public — and authenticate as a self-signed TLS client or present a stolen certificate-bound token. Leave it OFF and no certificate is ever read, so the mTLS methods and certificate binding cannot succeed.

mTLS.certificateBoundAccessTokens
Certificate-bound access tokens
Bind issued access tokens to the client certificateTypebooleanDefaultfalseRequiresmTLS.enabledTakes effectwhen you save itDetails
Requires mTLS enabled.

mTLS.selfSignedTlsClientAuth
self_signed_tls_client_auth method
Accept the self_signed_tls_client_auth methodTypebooleanDefaultfalseRequiresmTLS.enabledTakes effectwhen you save itDetails
Requires mTLS enabled.

mTLS.tlsClientAuth
tls_client_auth method
Accept the tls_client_auth methodTypebooleanDefaultfalseRequiresmTLS.enabledTakes effectwhen you save itDetails
Requires mTLS enabled.

requestObjects.enabled
Enable Request Objects (JAR)
Accept authorization parameters inside a signed request objectTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables the request (Request Object) parameter.

requestObjects.requireSignedRequestObject
Require signed request objects
Refuse authorization requests that are not signed request objectsTypebooleanDefaultfalseRequiresrequestObjects.enabledTakes effectwhen you save itDetails
Requires signed request objects for all authorization requests.

resourceIndicators.enabled
Enable Resource Indicators (RFC 8707)
Let a client name the resource server a token is meant forTypebooleanDefaulttrueTakes effectwhen you save itDetails
Enables Resource Indicators features.

richAuthorizationRequests.enabled
Enable RAR (RFC 9396)
Accept fine-grained authorization_details on a requestTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables the authorization_details parameter, per RFC 9396 (published May 2023). Requires at least one authorization details type below, and requires Resource Indicators — details are only assigned to an access token bound to a resource server.

richAuthorizationRequests.types
Authorization details types
The authorization details types this server acceptsTypejsonDefault{}RequiresrichAuthorizationRequests.enabledTakes effectwhen you save itDetails
The authorization details types this server accepts, as a map of type identifier to a descriptor: {"https://scheme.example/payment":{"label":"Initiate a payment","fields":{"actions":{"required":true,"allowed":["initiate"]}},"allowUnknownFields":false}}. `label` is what the consent screen shows. Constraints may only name the RFC 9396 §2 common fields (actions, locations, datatypes, privileges, identifier); `identifier` is single-valued so it takes `required` only. Unknown fields are refused unless a type opts in.

Endpoints & discovery
Which protocol endpoints are served, and what discovery advertises.

introspection.enabled
Enable Token Introspection (RFC 7662)
Serve token introspection for opaque access and refresh tokensTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables introspection for opaque access tokens and refresh tokens.

jwtIntrospection.enabled
JWT introspection responses (RFC 9701)
Return introspection results as a signed JWTTypebooleanDefaultfalseRequiresintrospection.enabledTakes effectwhen you save itDetails
JWT responses for introspection. Requires Introspection enabled.

backchannelLogout.enabled
Enable Back-Channel Logout
Notify clients of sign-out over a back channelTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables OIDC Back-Channel Logout features.

userinfo.enabled
Enable the UserInfo endpoint
Serve the UserInfo endpointTypebooleanDefaulttrueTakes effectwhen you save itDetails
Enables the UserInfo endpoint.

jwtUserinfo.enabled
JWT UserInfo responses
Return UserInfo as a signed JWTTypebooleanDefaultfalseRequiresuserinfo.enabledTakes effectwhen you save itDetails
JWT responses for UserInfo. Requires UserInfo enabled.

revocation.enabled
Enable Token Revocation (RFC 7009)
Serve the token revocation endpointTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables Token Revocation.

globalTokenRevocation.enabled
Enable Global Token Revocation (Okta Universal Logout)
Let an upstream identity provider sign its users out of everything hereTypebooleanDefaultfalseRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Serves <issuer>/global-token-revocation at each project. An upstream identity provider of the project that you opted in (on its federation provider) can then end everything one of its users holds here: every session, refresh token and access token this server can revoke, with relying parties told by back-channel logout. The account is not deactivated; the user can sign in again. Switch it on when a project federates to Okta and you want Okta Universal Logout (Identity Threat Protection) to reach this server. The request must be a JWT signed by the provider’s own published keys; unsigned or shared-secret requests are always refused. This implements an expired individual Internet-Draft (draft-parecki-oauth-global-token-revocation-06, expired 2026-08-28) in the shape Okta sends, so its format may change. Off: the path is not served and discovery does not advertise it.

rpInitiatedLogout.enabled
Enable RP-Initiated Logout
Let a client start sign-out and return the user to itselfTypebooleanDefaulttrueTakes effectwhen you save itDetails
Enables OIDC RP-Initiated Logout.

projects.addressForms
Address forms
Whether teams give projects a path, a subdomain, or eitherTypeenumDefault"path"Optionspath, subdomain, bothRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Which address a team may give a project. "path" serves it beneath this instance (https://auth.example.com/acme); "subdomain" serves it on a subdomain of this instance’s host (https://acme.auth.example.com), so every project has an origin of its own; "both" lets the team choose, with the subdomain offered first. Turn subdomains on only after you have pointed a wildcard DNS record and a wildcard TLS certificate for *.<this instance’s host> at the server: the server cannot see DNS or certificates, and without them a subdomain project is unreachable. Super administrators may always give any form, including a hostname of its own. Changing this never moves an existing project: one whose form is no longer offered keeps its address, and its team can still move it to a form that is.

projects.reservedHostnames
Reserved hostnames
Names in your domain that no project may be givenTypestring-arrayDefault[]RiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Hostnames beneath this deployment’s domain that no project may be assigned. The deployment’s own canonical host is always refused and does not need listing; this is for everything else you run under the same domain — a marketing site, a status page, a staging instance — which this server has no way to discover. Empty by default, deliberately: a guess would either refuse a name you meant to use for a tenant or admit one that shadows something you already serve. Names are compared in normalised form, so case and a trailing dot do not matter. A project subdomain is refused when its full name is listed here.

registration.enabled
Enable Dynamic Client Registration
Let a client register itself at runtimeTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables Dynamic Client Registration.

registration.issueRegistrationAccessToken
Issue registration access token
Issue a registration access token to a new clientTypebooleanDefaulttrueRequiresregistration.enabledTakes effectwhen you save itDetails
Whether a registration access token is issued.

clientIdMetadataDocument.enabled
Accept a URL as a client identifier
Let a client identify itself with a document it hostsTypebooleanDefaultfalseTakes effectwhen you save itDetails
Accepts an https URL carrying a path component as a `client_id`, retrieves the JSON document it names, and uses that as the metadata for the client — creating no client record at all. This is the mechanism the current MCP authorization specification names first for a client with no prior relationship, and it is what lets an agent host connect with nothing to configure. Off by default because switching it on lets an unauthenticated caller make this server issue an outbound HTTP request; the egress is bounded (private, loopback and link-local addresses refused, every redirect hop re-checked, 5 KB, short timeout) and the cache headers on the retrieved document bound how long it is reused. Advertised as `client_id_metadata_document_supported` only while this is on, because a client checks for that member before attempting the mechanism and falls back otherwise.

registrationManagement.enabled
Enable registration management (RFC 7592)
Let a registered client update or delete itselfTypebooleanDefaultfalseTakes effectwhen you save itDetails
Enables update/delete for dynamically registered clients.

registrationManagement.rotateRegistrationAccessToken
Rotate registration access token
Issue a fresh registration access token on each updateTypebooleanDefaulttrueRequiresregistrationManagement.enabledTakes effectwhen you save itDetails
Enables registration access token rotation.

scopes
Supported scopes
Scopes advertised in discoveryTypestring-arrayDefault["openid","offline_access"]Takes effectwhen you save itDetails
Scopes advertised in discovery. Must include openid.

claims
Claims and the scopes that release them
Which claims each scope releases, and which stand aloneTypejsonDefault{"acr":null,"sid":null,"auth_time":null,"iss":null,"openid":["sub"],"email":["email","email_verified"],"profile":["name","family_name","given_name","middle_name","nickname","preferred_username","profile","picture","website","gender","birthdate","zoneinfo","locale","updated_at"],"phone":["phone_number","phone_number_verified"]}Takes effectwhen you save itDetails
Which end-user claims this server can release, and under which scope, e.g. {"openid":["sub"],"profile":["name","given_name","family_name"],"email":["email","email_verified"],"acr":null,"sid":null,"auth_time":null,"iss":null}. A member whose value is a list of claim names defines a scope: that scope is advertised in discovery and a client granted it receives those claims. A member whose value is null is a claim of its own, released when requested by name. `openid` is required and always carries `sub`. `amr` — the authentication methods a sign-in used — is always supported and needs no entry here: every ID token from a sign-in carries it, and listing or omitting it changes nothing. A claim an end user holds but no entry names is never released, which is why the claims you set on an account in a project reach a client only once a scope here names them. A new instance maps `profile`, `email` and `phone` to their OpenID Connect Core §5.4 claims, which is what a provisioned profile is released under; an instance that saved this setting before keeps exactly what it saved.

consent.scopeDescriptions
Descriptions of custom scopes
What each of your own scopes lets an app do, as the consent page says itTypejsonDefault{}Takes effectwhen you save itDetails
What each scope this instance defines lets an application do, in the words the consent page shows the person deciding, e.g. {"billing":"see your invoices and payment history"}. Write it to follow "The app will be able to": a verb, then what it acts on. Keys must be scopes defined under Supported scopes or Claims, and never a standard OpenID Connect scope (openid, profile, email, address, phone, offline_access, groups) — the page describes those itself. A requested scope with no description is still shown, by its technical name, under "Other permissions — not described", which is honest but tells the person nothing. To remove a scope that has a description, remove the description in the same save. Scopes of a protected resource you declared are described on that resource, not here.

acrValues
Authentication context values
Which acr value each authentication this server can distinguish is reported asTypejsonDefault{"password":"urn:foxauth:acr:pwd","multi_factor":"urn:foxauth:acr:mfa","federated":"urn:foxauth:acr:federated"}Takes effectwhen you save itDetails
Which Authentication Context Class Reference each authentication this server can distinguish is reported as, e.g. {"password":"1","multi_factor":"2","federated":"1"}. The server owns the distinctions and you own the names: a relying party matches a requested context against the one satisfied by exact string comparison, so values your applications already expect are what belong here. `acr_values_supported` is derived from these, so what is advertised is always what a sign-in can actually produce. Every distinction needs a value, no two may share one, and "0" is reserved by the specification for an authentication carrying no confidence that the same person is there. Note that a relying party which *requires* the multi-factor context is refused for anyone who signs in with a password alone — and whether a second factor is demanded is a project setting, not a property of the person, so an end user with one enrolled in a project that does not require it reports the password context. A federated sign-in is never gated by that setting at all.

clientAuthMethods
Client authentication methods
Client authentication methods advertised in discoveryTypestring-arrayDefault["client_secret_basic","client_secret_jwt","client_secret_post","private_key_jwt","none"]Optionsclient_secret_basic, client_secret_jwt, client_secret_post, private_key_jwt, noneTakes effectwhen you save itDetails
token_endpoint_auth_methods_supported (mTLS methods added when enabled).

Sign-in & abuse
End-user sign-in, and the limits that keep it from being abused.

cors.enabled
Enable cross-origin access for browser clients
Let browser apps read responses from this serverTypebooleanDefaulttrueRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Lets browser-based apps read responses from the metadata and key endpoints, and from the endpoints listed on an application’s browser origins. Closure normally comes from data — an application with no origins grants nothing — so this is an incident kill switch rather than the usual control.

rateLimit.enabled
Refuse a calling origin that exceeds its request allowance
Refuse a caller that exceeds its request allowanceTypebooleanDefaulttrueRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Refuses requests from one origin past its allowance inside a window, before the endpoint does any work. Allowances are tiered by route class, so the token endpoint and a static asset are not held to the same number. On by default; turn it off as an incident kill switch if it starts refusing traffic it should not.

rateLimit.trustedProxy
Take the caller’s address from the proxy headers
Read the caller address from proxy headersTypebooleanDefaulttrueRequiresrateLimit.enabledRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Whether Fly-Client-IP, the first hop of X-Forwarded-For, or X-Real-IP names the caller. This one has a wrong answer in each direction. Leave it ON when a proxy or load balancer sits in front of this server: with it off, every caller arrives as the proxy’s address, so the whole internet shares one allowance and all traffic is refused within seconds. Turn it OFF only when the server is directly exposed: with it on, any caller can set the header to a fresh value per request and is never limited. Defaults to on, matching the shipped deployment.

rateLimit.maxTrackedOrigins
Origins remembered per route class
How many callers each route class tracks at onceTypenumber (origins)Default10000RequiresrateLimit.enabledTakes effectwhen you save itDetails
How many distinct origins each class tracks at once, capping the limiter’s own memory. Bounded on purpose: the key comes from the caller, so an unbounded tally would itself become the memory-exhaustion vector this feature exists to prevent. Past the bound the least recently seen origin is forgotten and gets a fresh allowance. Lower it on a small machine.

rateLimit.strict.max
Strict allowance — requests per window
Allowance for token, authorization and other costly routesTypenumber (requests)Default60RequiresrateLimit.enabledTakes effectwhen you save itDetails
Applies to the unauthenticated and expensive surface: token issuance, authorization, dynamic registration, device and CIBA, and every end-user door that checks a secret or sends mail. Raise it if a legitimate server-to-server integration behind a single address, or many users behind one corporate NAT, start seeing refusals.

rateLimit.strict.windowSeconds
Strict allowance — window length in seconds
Window the strict allowance is measured overTypenumber (seconds)Default60RequiresrateLimit.enabledTakes effectwhen you save itDetails
The period the strict allowance is measured over. A caller timing requests around the boundary can send close to twice the allowance across two adjacent windows; that is normal for this kind of limit and not a defect.

rateLimit.ordinary.max
Ordinary allowance — requests per window
Allowance for userinfo, admin and other ordinary routesTypenumber (requests)Default300RequiresrateLimit.enabledTakes effectwhen you save itDetails
Applies to everything not classified strict or public: userinfo, introspection, revocation, the administration API, the MCP surface, and the rest of the end-user screens. Any endpoint added without an explicit classification lands here, so it is sized for a mixed session rather than for one endpoint.

rateLimit.ordinary.windowSeconds
Ordinary allowance — window length in seconds
Window the ordinary allowance is measured overTypenumber (seconds)Default60RequiresrateLimit.enabledTakes effectwhen you save itDetails
The period the ordinary allowance is measured over.

rateLimit.public.max
Public allowance — requests per window
Allowance for assets, discovery and the key setTypenumber (requests)Default1200RequiresrateLimit.enabledTakes effectwhen you save itDetails
Applies to the cheap public surface — static assets, the discovery document, the key set — and to every cross-origin preflight. Sized to clear the administration console’s full page-and-asset load from one address. Raise it if the console stutters while loading.

rateLimit.public.windowSeconds
Public allowance — window length in seconds
Window the public allowance is measured overTypenumber (seconds)Default60RequiresrateLimit.enabledTakes effectwhen you save itDetails
The period the public allowance is measured over.

loginThrottle.failureCap
Failed password attempts allowed per window
Wrong passwords one address may try before sign-in shutsTypenumber (attempts)Default5Takes effectwhen you save itDetails
How many wrong passwords one address may submit before the sign-in door shuts for that address. Once shut it refuses every attempt, including one with the correct password, until the window ends — and the refusal looks exactly like an ordinary wrong password, so it tells an attacker nothing. Raising this hands a guessing attack proportionally more tries; lowering it locks out people who mistype. Matches the verification code’s attempt cap by default.

loginThrottle.windowSeconds
First lockout length in seconds
How long sign-in shuts the first time an address runs outTypenumber (seconds)Default900Takes effectwhen you save itDetails
How long the door stays shut the first time an address runs out of attempts, and the length each further lockout doubles from. This is also the shortest wait an honest user who trips the throttle will face, so it is the number to lower if legitimate lockouts are the complaint. A project that requires a one-time code stays at this length however often it is tripped, because a guessed password there does not sign anyone in.

loginThrottle.windowCeilingSeconds
Longest lockout length in seconds
The longest sign-in will ever shut for one addressTypenumber (seconds)Default3600Takes effectwhen you save itDetails
The longest the door will ever shut, however many times one address has run out of attempts. With the defaults the lockouts run 15 → 30 → 60 minutes, which holds a sustained attack to roughly 120 guesses a day. Cannot be shorter than the first lockout, and cannot exceed 24 hours — beyond that the counter would be forgotten before its own lockout ended, which would reopen the door. Someone locked out this long can still get straight back in by completing a password reset.

federation.enabled
Enable sign-in through an upstream identity provider
Let a project offer sign-in through an upstream providerTypebooleanDefaultfalseTakes effectwhen you save itDetails
Lets a project offer sign-in through external OpenID Providers configured on that project, alongside or instead of its password form. Off by default: this is the only capability that lets an outside party’s assertion produce a session here, and with it off no federation route is served and no provider button renders, whatever a project holds. Configuring providers stays available either way, so a provider can be prepared before switching this on and removed after switching it off.

Diagnostics
What this server records when something fails, and where it goes.

errorStore.enabled
Record internal server faults
Keep a durable record of unexpected internal faultsTypebooleanDefaultfalseTakes effectwhen you save itDetails
Keeps a durable record of unexpected internal faults so a failure can be diagnosed after it happened rather than only while it is happening. Routine client rejections — a bad grant, a wrong password, an expired code — are correct behaviour and are never recorded, so every entry is a defect. Off by default; with it off nothing is written and the /admin/api/errors paths are not served at all.

errorStore.retentionDays
Retention window (days)
How long a recorded fault is keptTypenumber (days)Default30RequireserrorStore.enabledTakes effectwhen you save itDetails
How long a recorded fault is kept. The window runs from when the fault was last seen, not when it was first seen, so a fault that is still happening does not age out mid-life.

errorStore.maxGroups
Maximum distinct faults retained
How many distinct faults are kept at onceTypenumber (faults)Default10000RequireserrorStore.enabledTakes effectwhen you save itDetails
How many distinct faults are kept. At the limit the least recently seen fault is evicted — never the oldest by creation, which would discard a long-running problem in favour of one that happened once this morning.

errorStore.samplesPerGroup
Occurrences kept per fault
Full occurrences retained per distinct faultTypenumber (occurrences)Default10RequireserrorStore.enabledTakes effectwhen you save itDetails
How many full occurrences are retained for each distinct fault: the earliest, plus the most recent ones. The occurrence count stays exact however many are discarded — this bounds the detail kept, never the tally.

errorStore.queueDepth
Pending write queue depth
How many records may await writingTypenumber (records)Default500RequireserrorStore.enabledTakes effectwhen you save itDetails
How many records may await writing. Recording never delays a response, so faults are queued rather than written inline — which makes this also the loss bound: an abruptly killed process can lose at most this many records, and a full queue counts what it could not accept so an operator can see that recording fell behind.

errorStore.originCaptureLevel
Caller address detail
How much of the caller address a record keepsTypeenumDefault"anonymized"Optionsomitted, anonymized, fullRequireserrorStore.enabledTakes effectwhen you save itDetails
How much of the caller’s network address a record keeps, because an address is personal data. "omitted" stores none and says so; "anonymized" stores a value that cannot be reversed to the address but is still the same for two requests from one origin, so a single misbehaving deployment is still identifiable; "full" stores the address. Defaults to anonymized.

sentry.enabled
Report recorded faults to Sentry
Also send every recorded fault to a Sentry projectTypebooleanDefaultfalseRequireserrorStore.enabledTakes effectwhen you save itDetails
Sends every fault the error store records to an external Sentry project, so a failure raises an alert instead of waiting to be found here. This is an additional destination, never an alternative: the fault is recorded locally first and the outbound event is built from that record, which is why this cannot be switched on unless the error store is. Only the endpoint, the kind of failure and the reference are sent — never a request URL, header, cookie, body, or any end-user identity. Off by default; requires the ingestion credential below.

Integrations
Outbound services, and machine access to this console.

mcp.enabled
Enable the administrative MCP control plane
Let an AI agent administer this server over MCPTypebooleanDefaultfalseTakes effectwhen you save itDetails
Serves this control plane to an AI agent over MCP at /mcp, as an OAuth 2.1 protected resource of this server. An agent acts as the administrator who authorized it and gets exactly that account’s permissions: every operation runs through the same routes, the same checks and the same audit trail as the console, and each entry records both the operator and the agent. Deleting a project is withheld from agents entirely and stays console-only. Off by default — with it off, neither /mcp nor its metadata document is served.

scim.enabled
Enable SCIM 2.0 provisioning
Let an enterprise directory manage a project’s users over SCIMTypebooleanDefaultfalseTakes effectwhen you save itDetails
Serves SCIM 2.0 /Users at each project’s <issuer>/scim/v2, so an enterprise directory such as Microsoft Entra ID or Okta can create, update, deactivate and delete the project’s end users through a provisioning connection you set up on the project. A deactivation over SCIM ends the user’s sessions and tokens at once. Off by default, because it lets a third party’s system write to end-user accounts. With it off no SCIM path or metadata document is served; connections can still be prepared and are kept.

scim.secretCredentials
Allow client-secret credentials for SCIM
Used by Entra and Okta OAuth modes; a deviation from IPSIE §4.1TypebooleanDefaulttrueRequiresscim.enabledRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Lets a provisioning connection hold a client secret and obtain its SCIM token with it. Microsoft Entra ID’s OAuth2 Client Credentials Grant and Okta’s OAuth 2 client-credentials mode both authenticate this way, so turning this off stops those connections from obtaining a token. A replaced secret keeps working until the directory has moved to the new one, at most 24 hours. The OpenID IPSIE SCIM profile (§4.1) requires a signed JWT client assertion instead, which the key credential provides — turn this off if you certify against IPSIE and no connection uses a secret. Turning it off does not delete secrets; turning it back on restores them.

scim.staticTokens
Allow static tokens for SCIM
For directories without an OAuth option; a deviation from IPSIE §4.1TypebooleanDefaulttrueRequiresscim.enabledRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Lets a provisioning connection hold a bearer token that the directory presents directly — for an Okta organisation without the OAuth 2 option for SCIM (its HTTP Header mode), or Entra’s long-lived bearer mode. Turning this off disconnects every connection that uses one. Each token expires after 90 days or a year, chosen when it is issued (RFC 7644 §7.4), and a replaced token keeps working until the directory has moved to the new one. The OpenID IPSIE SCIM profile (§4.1) requires a short-lived OAuth access token instead — turn this off if you certify against IPSIE and no connection uses a static token. A static token is stored only as a hash; turning this setting off does not delete it.

scim.strict
Strict SCIM: refuse non-conformant requests
On only to certify against the profiles; breaks Entra and Okta defaultsTypebooleanDefaultfalseRequiresscim.enabledRiskChanging this has a security consequence; the console asks for confirmation.Takes effectwhen you save itDetails
Off (the default), the server accepts the request forms Entra ID and Okta actually send: a PATCH without a path, an operation name in capitals, true or false written as a string, a manager given as a bare id or cleared with an empty string, attributes this server does not store (they are ignored), and a password (ignored, never stored). On, each of those is refused with 400 and the server declares conformance to the SCIM 2.0 Interoperability Profile (§6.5.1.1) and the OpenID IPSIE SCIM profile (§6.1.2). Turn it on only if you certify against those profiles: with it on, Okta cannot deactivate users or create them, and Entra with its default attribute mappings fails.

scim.rateLimit.max
Per-connection allowance — requests per window
SCIM requests one connection may send per windowTypenumber (requests)Default3000Requiresscim.enabledTakes effectwhen you save itDetails
How many SCIM requests one provisioning connection may send per window before it receives 429 with Retry-After. Counted per connection, not per address, because Entra and Okta send many customers’ traffic from a few addresses. Must allow at least 25 requests a second together with the window (an IPSIE requirement); a lower value is refused. The default, 3,000 a minute, is 50 a second.

scim.rateLimit.windowSeconds
Per-connection allowance — window length in seconds
Window the per-connection SCIM allowance is measured overTypenumber (seconds)Default60Requiresscim.enabledTakes effectwhen you save itDetails
The period the per-connection SCIM allowance is measured over. A longer window absorbs a directory’s bursts — an initial import sends far more than its steady rate — at the cost of letting one connection spend the whole allowance at once.

Plans & limits
What each project’s plan lets its team create, and the plan catalogue.

plans.enabled
Enforce plans
Limit what each team may create by its project’s planTypebooleanDefaultfalseTakes effectwhen you save itDetails
Turns on the limits of each project’s plan: how many projects an administrator may own, how many applications and APIs a project may hold, whether it may use enterprise sign-in or name its own address, and the monthly active users at which it stops accepting new self-service sign-ups. Turn it on for a public instance where anyone may register as an administrator; leave it off for your own organisation’s instance. Limits apply only to a new creation, and never to a super administrator or a System project: nothing that already exists is switched off, and no existing user is ever refused a sign-in. Every project already records its plan, so turning this on changes no data, and turning it off keeps every assignment and the catalogue for next time.

plans.regularTeamsPerAdministrator
Teams per administrator
How many regular teams one administrator may ownTypenumber (teams)Default1Requiresplans.enabledTakes effectwhen you save itDetails
The number of regular teams one administrator may own while plans are on, counted over every team in which they have the owner role. Their personal team never counts. A team has no plan of its own, so this is one number for the whole instance rather than a plan limit. Lowering it removes nobody from a team they already own; it only refuses the next team, or the next time someone would make them an owner.

PreviousSecurity assuranceNextEndpoints
