OAuth2 Authentication
This document describes the detailed usage of a specific policy. If you are using Apinizer policy structure for the first time or want to learn the general working principles of policies, we recommend that you first read the What is Policy? page.
Overview
What is its Purpose?
- Standardizes authentication in OAuth 2-based access to enterprise services, providing centralized control at the API Proxy (API Gateway) level.
- Manages different grant type needs under a single policy, providing project-based consistency.
- Controls access duration, refresh rights, and security boundaries by managing token and refresh token lifecycles according to organizational policies.
- Integrates identity and role sources with Secret Manager, API, LDAP, database, or OIDC Provider sources, making authorization processes compatible.
Working Principle
- Request Arrival: For each HTTP/HTTPS request arriving at the API Gateway, the source IP address of the request is detected.
- Policy Check: If the OAuth 2 Authentication policy is active, the system checks in the following order:
- Is a Condition defined? If so, is the condition met?
- Is the policy active (active=true)?
- Is a Variable used or is Apinizer default?
- OAuth 2 Flow Control: Verifies client credentials according to the selected grant type, retrieves identity or role data from Identity Role Group and Secret Manager information if necessary, and applies token generation/refresh rules.
- Decision Making:
- Match Found: An access token is created for the authorized client or the existing token is validated, and header enrichments are applied.
- No Match: Token generation or validation is rejected, and unauthorized access is logged.
- Error Handling: Returns customizable HTTP status code and error message for requests that do not comply with the policy rule.
Features and Capabilities
Basic Features
- Grant Type Management: Provides authentication suitable for different client types by supporting CLIENT_CREDENTIALS and PASSWORD flows.
- Token Lifecycle Control: Defines access token duration, refresh token rights, and refresh count according to project requirements.
- Identity Provider Integration: Provides authentication flexibility by working with Secret Manager, Identity Role Group, LDAP, API, database, or OIDC-based identity sources.
- Active/Passive Status Control: Easily change the active or passive status of the policy (active/passive toggle). In passive state, the policy is not applied but its configuration is preserved.
- Conditional Application: Determine when the policy will be applied by creating complex conditions with Query Builder (e.g., only for specific endpoints or header values).
Advanced Features
- Secret Manager-Based Assurance: Provides additional security and IP address tracking for passwordless flows by keeping credentials in a secure vault.
- Header Enrichment: Writes the authenticated user's identity and role information to customizable header fields.
- Method-Based Authorization: Defines special role sets for API methods and applies granular access control.
- Export/Import Feature: Export policy configuration as a ZIP file. Import to different environments (Development, Test, Production). Version control and backup capability.
- Policy Group and Proxy Group Support: Manage multiple policies within Policy Group. Bulk policy assignment to Proxy Groups. Centralized update and deploy operations.
- Deploy and Versioning: Deploy policy changes to live environment. See which API Proxies use it (Policy Usage). Proxy Group and Policy Group usage reports.
Usage Scenarios
| Scenario | Situation | Solution (Policy Application) | Expected Behavior / Result |
|---|---|---|---|
| M2M Service Token Management | Machine user wants to access backend | Grant Type = CLIENT_CREDENTIALS, Token Never Expires = false, Token Expires In = 15 min | Token is periodically renewed, services access in a controlled manner |
| User Password Authorization | End user logging in from mobile app | Grant Type = PASSWORD, Identity Role Group = RetailUsers, Check Client IP Address = true | Token without IP match is rejected, role-based header is set |
| Refresh Token Cycle | Long-term session needed | Token Never Expires = false, Refresh Token Allowed = true, Refresh Token Count = 5 | Continuous access is provided with refresh token, re-authentication is requested when limit is exceeded |
| Adding Roles to Header | Downstream service expects role information | Add Roles To Header = true, Roles Header Name = X-Authorized-Roles | Role list is carried in request header, target service does not need additional query |
| Secret Manager Integration | Credentials will be kept in Apinizer vault | Grant Type = PASSWORD, Authentication Provider = Secret Manager, Use Secret Manager For Authorization = true | Identity/role data is read from vault, password management becomes independent from application |
| Only Specific Endpoint | Admin API should only be accessed with admin role | Condition: Path = /api/admin/*, Enable Authorization = true, Method Access = role mapping | Non-admin calls return 403, admin methods are accessible |
| Audit-Focused Token Reset (optional) | Old tokens will be invalidated | Delete Previous = true, Clear Auth = true | When new token is generated, old tokens are cancelled, logging becomes easier |
Configuring Policy Parameters
In this step, users can create a new policy or configure existing policy parameters to define access rules. The defined parameters directly affect how the policy works (e.g., which IPs will be allowed, geographical restrictions, conditional activations, etc.). This way, the policy can be customized according to organization-specific requirements and managed centrally.
Creating New OAuth 2 Authentication Policy
Configuration Steps
| Step | Description / Operation |
|---|---|
| Step 1: Going to Creation Page | - Go to Development → Global Settings → Global Policies → OAuth 2 Authentication Policy section from the left menu. - Click the [+ Create] button at the top right. |
| Step 2: Entering Basic Information | Policy Status: Shows Active/Passive status. New policies are active by default. Name (Required): Example: Production_OAuth2Auth- Enter a unique name, does not start with space. - System automatically checks. Green check: available. Red X: existing name. Description: Example: "OAuth 2 CLIENT_CREDENTIALS flow for M2M services." - Max. 1000 characters. - Describe the purpose of the policy. |
| Step 3: Variable Usage | - In the action button area at the top of the page, you can use the [<> Variable] button to select dynamic values. - Using context/global variable expressions, you can manage policy parameters with variable-based values instead of fixed values. - This reduces manual update effort when values change and provides operational convenience. - For detailed information, review Dynamic Variables. |
| Step 4: OAuth 2 Flow Parameters | - Management (default: Manage From This Policy): One of two choices is selected. - Manage From ACL: Consumers, API clients and their ACL rows decide who may call; tokens follow the API client's settings. - Manage From This Policy: This policy's identity source, grant types and token settings decide; the API client settings are not used. - The Grant Type, identity source and token settings, as well as the browser login, Show API Key, client address check, URL parameters, clear authentication and add-user-to-header fields, are shown only while Manage From This Policy is selected. The Management choice is not shown when the identity source is OIDC. - Grant Type: Select CLIENT_CREDENTIALS or PASSWORD. - Identity Role Group: Shown for every grant type. In PASSWORD flow, select identity provider from Secret Manager, LDAP, Database, API, or OIDC; in CLIENT_CREDENTIALS flow only Secret Manager (default — unchanged token issuance and validation) or OIDC are offered. Selecting OIDC opens a searchable list of OIDC Provider records (name, description, vendor type); a Generic-vendor provider is a valid choice here too, since only its token validation is used. - OIDC with CLIENT_CREDENTIALS (IdP-issued tokens): the policy issues no tokens; the client presents the provider's access token as Authorization: Bearer and Apinizer validates it on every request (JWKS signature offline, introspection/userinfo online — opaque tokens are supported through introspection). Identity comes from the provider's Username Claim Path (or the introspection response for opaque tokens), roles from the provider's role source; Require Matching Consumer maps the identity to a Consumer for quota/ACL attribution. Delete Previous, token lifetime and refresh settings are hidden, and the proxy's /auth/* token endpoint answers 400 invalid_request. PASSWORD + OIDC keeps the previous behaviour.- Check Client IP Address: Make token's source IP match mandatory in Secret Manager flow. Validate ACL for Client: On by default. Shown when the identity source is Secret Manager or the Manage From ACL mode is selected; hidden for OIDC. When off, the policy only resolves and verifies the identity and does not check the consumer's access list (ACL) for this API Proxy or Proxy Group. See Identity-Only Mode (ACL Off). |
| Step 5: Token Lifecycle and Refresh Settings (If Any) | - Delete Previous: Cancel old tokens when new token is generated. - Token Never Expires: Leave open if unlimited token is needed; if closed, define duration and unit. - Refresh Token Allowed: Activate refresh right, determine count and duration. - Allow URL Parameters / Clear Auth: Configure URL parameter acceptance at token endpoint and clearing of old credentials. |
| Step 6: Header and Authorization Integration (If Any) | - Set Resolved Identity to Context: Determines whether the identity resolved by this policy (username/key) is recorded as the request identity. When on (default), this identity appears in traffic logs and subsequent policies and scripts. When off, the identity is used only for the necessary internal authentication/authorization checks and is not persisted as the request identity. - Add User To Header / User Header Name: Add authenticated user information to custom header. - Authorization Configuration: Configure method-based role assignments, authorization source (Secret Manager, API, LDAP, DB), and role header management. - Add Roles To Header / Roles Header Name: Determine header names to be transmitted for roles. |
| Step 7: Defining Condition (Optional) | - Go to Condition tab. - Conditions determine when the policy will be active. Examples: - Environment-based: Header = X-Environment, Operator = Equals, Value = production- API Key-based: Header = X-API-Key, Starts With = PROD-- Endpoint-based: Path = /api/admin/*If no condition is defined, policy is always active |
| Step 8: Error Message Customization (Optional) | - Go to Error Message Customization tab. - Customize the message to be returned when access is denied. Default: { "statusCode": 403, "message": "[Default error message]" }Custom: { "statusCode": 403, "errorCode": "[CUSTOM_ERROR_CODE]", "message": "[Custom message]" } |
| Step 9: Saving | - Click the [Save] button at the top right. Checklist: Unique name. Required fields filled. At least one OAuth 2 flow selection and required identity provider determined. Result: - Policy is added to the list. - Can be connected to APIs. - If global policy, automatically applied. |
For the description of Conditions and Error Message Customization panels, you can review the Conditions and Error Message Customization (Error Message Customization) sections on the What is Policy? page.
For a complete guide on all layers, priority order and scenario examples of the error message configuration system, see the Error Message Configuration Guide page.
Browser Login (authorization_code)
In Manage From This Policy mode, you can turn on the Browser login (authorization_code) switch in the policy. When the switch is on, a standard OAuth2 client (for example Claude Code or MCP Inspector) uses Apinizer as the authorization server. The user signs in on the /auth login page of the gateway, and the application gets a token on behalf of the user. The selected legacy grant (client credentials or password) keeps working.
- The users come from the identity source of the policy: Secret Manager, LDAP, database or API. When the identity source is OIDC, the switch is off.
- Token Never Expires must be off in the policy and the access token lifetime must be finite. If you allow a refresh token, the refresh lifetime must be finite too. Browser login never issues a token without an expiry.
- The client is an API client that belongs to an application. The
client_idis the client ID of this client. The application also needs an ACL row for the proxy. - You can use the switch only in the own token policy of an API Proxy. You cannot use it in a proxy group policy or in the policy of a method.
- After you turn the switch on or off, save the policy and redeploy the proxy. If you turn the switch off, the tokens issued by browser login become invalid immediately.
- Do not turn the switch on before all workers are upgraded.
- In Manage From ACL mode the switch is not shown. In this mode you turn on browser login in the API client of the application.
When you save the policy, you can see these error messages:
| Message | Meaning |
|---|---|
| The grant list of the token policy is not valid. It must name one legacy grant (client credentials or password), the same as the selected grant type, and can add browser login (authorization_code). | The grant list is not valid. |
| Browser login (authorization_code) on this policy needs a finite access token lifetime. When refresh is allowed, the refresh token also needs a finite lifetime. | A lifetime is not finite. |
| Browser login (authorization_code) is not available when the identity source is OIDC. Use the OIDC provider's own login. | The identity source is OIDC. |
| Browser login (authorization_code) is a setting of an API proxy's own token policy. It is not available on a proxy group policy. | The policy is on a proxy group. |
| Browser login (authorization_code) is a setting of the API proxy's token policy on the proxy itself. It is not available on a method's policy. | The policy is on a method. |
For a step-by-step setup, see MCP Gateway Browser Sign-In Without Keycloak. For the endpoints, see Token Service.
Accepting Delegated Tokens (Token Exchange)
The Accept delegated tokens (token exchange) switch lets an agent call this API proxy on behalf of a user. The agent uses a token that it got through token exchange. The switch is off by default. When it is off, the policy refuses a delegated token as before. Direct clients are not affected.
- The switch is shown in both Manage From ACL and Manage From This Policy modes. It is not shown when the identity source is OIDC.
- When you turn the switch on, two more fields appear.
- Allowed agents: Enter the client IDs of the API clients of the agents. For a legacy consumer, enter its username. Type a value and press Enter. An empty list admits no agent.
- Delegation chain depth: Select One agent or Up to two agents. The default is Up to two agents.
- The gateway reads this setting only from the active JWT and OAuth2 policies in the request policy list of the API proxy itself. It does not read policies on a method, on a proxy group or inside a policy group.
The gateway checks these points for a delegated token:
- The token is for this API proxy only. Its audience is the canonical address of this proxy.
- Every agent in the chain is in Allowed agents. The chain is not longer than the depth.
- Every agent is still active, and its tokens were not revoked.
- The user passes the access checks of this proxy as the request identity. When ACL check is on, the user needs an ACL row.
- The request runs with the current roles of the user. The scope of the token can only narrow them. A role without an OAuth scope name is not carried.
The gateway answers a refused token with the normal "token not valid" response.
The JWT policy validates delegated JWTs. The OAuth2 policy validates stored (opaque) delegated tokens. The token exchange issues the format that the target policy validates. The agent does not choose it.
For more information, see Token Exchange (RFC 8693).
Identity-Only Mode (ACL Off)
When Validate ACL for Client is off, the policy works in identity-only mode. It still resolves and verifies the identity, but it does not check the consumer's access list (ACL) for this API Proxy or Proxy Group.
| Still applied when ACL is off | Skipped when ACL is off |
|---|---|
| The consumer exists and is enabled. The consumer's organization and parent organizations are active. The consumer's validity (expire date) has not passed. The consumer's contracts have not passed their end date. The client IP is in the consumer's IP list (when Validate Client Address is on). The API Client owner is active. Role authorization (if enabled) and Limit Plan rules apply. The request is marked as authenticated and the resolved identity is written to the traffic log. | The consumer's access row for this API Proxy or Proxy Group (its expiry, environment enable switch, disallowed methods and proxies). API Client subscription and access grants (portal subscriptions). The traffic log does not show the subscription product and plan for these requests, because this information comes from the access row. |
With ACL off, every active consumer in the environment that passes the identity rules can call the API. There is no project boundary.
The option also applies to the token endpoints: token issuance for the PASSWORD grant follows the same switch.
LDAP, Database, API and OIDC identity sources never consult the ACL. The option has no effect with these sources.
On the security tab of an API Product, a policy with ACL off is reported with the existing "Managed from policy" status: authentication is managed from the policy, not the consumer store (ACL), so application credentials do not authorize there.
Deleting Policy
For the deletion steps of this policy and operations to be applied while in use, you can refer to the Removing Policy from Flow section on the Policy Management page.
Exporting/Importing Policy
For the export and import steps of this policy, you can refer to the Export/Import page.
Binding Policy to API
For the process of how this policy will be bound to APIs, you can refer to the Binding Policy to API section on the Policy Management page.
Advanced Features
| Feature | Description and Steps |
|---|---|
| Authentication with Secret Manager | - When PASSWORD grant is selected, mark the Secret Manager provider - Identities in the secure vault are matched through Identity Role Group dialog - When Check Client IP Address is active, token is only valid from the defined IP |
| Method-Based Authorization Mapping | - Enable Method Access in Authorization Configuration - All methods are automatically listed and role lists are assigned - Role-based method limits are reflected in Policy Usage reports |
| Header Enrichment and SSO Integration | - When Add User To Header is active, user identity is written to custom header - Share user role list with Add Roles To Header - Downstream services provide federation without additional query |
Best Practices
Things to Do and Best Practices
| Category | Description / Recommendations |
|---|---|
| Token Lifecycle | Bad: Token Never Expires left open, unlimited access Good: Token duration 24 hours, refresh token closed Best: Token 15 min, refresh token 3 rights, short-term access |
| Grant Type Selection | Bad: PASSWORD grant forced for every service Good: PASSWORD only in user-interactive APIs Best: CLIENT_CREDENTIALS in machine access, PASSWORD in mobile app |
| Header Management | Bad: Header names left as default, usage unclear Good: Header names documented Best: Header values not logged, compatible with downstream contract |
| Secret Manager Usage | Bad: Credentials entered manually Good: Secret Manager used but audit closed Best: Secret Manager + IP control + regular access log analysis |
| Authorization Configuration | Bad: Enable Authorization closed, all APIs accessible by everyone Good: Method-based role assignment done Best: Roles versioned with Policy Group and CI/CD pipeline |
Security Best Practices
| Security Area | Description / Warnings |
|---|---|
| Token Expiration | Use short-lived access tokens, reduce silent attack surface. |
| Refresh Token Protection | Limit refresh token count, activate Delete Previous for quick cancellation in case of leakage. |
| Secret Manager Access | Give access to identity vault only to authorized operation users, monitor audit logs. |
| Header Masking | Mask headers carrying user data in logs, prevent PII leakage. |
| IP and Condition Control | Narrow the policy with conditions and IP verification in production environment; do not leave open access. |
Things to Avoid
| Category | Description / Warnings |
|---|---|
| Defining Unlimited Token | Why to avoid: Attack surface increases. Alternative: Short-term token + refresh cycle. |
| Shared Secret Sharing | Why to avoid: If multiple clients use the same credentials, tracking cannot be done. Alternative: Generate secret per client and keep in Secret Manager. |
| Unconditional Global Transfer | Why to avoid: All APIs are affected, untested changes spread. Alternative: First try as local policy in test environment. |
| Breaking Header Standards | Why to avoid: Downstream services return errors. Alternative: Plan header changes together with consumer teams. |
Performance Tips
| Criterion | Recommendation / Impact |
|---|---|
| Token Generation Frequency | Recommendation: Do not keep token duration too short (e.g., below 5 min). Impact: Load on authentication service decreases. |
| Refresh Token Usage | Recommendation: Close unnecessary refresh cycles. Impact: Less reading on database and cache. |
| Secret Manager Calls | Recommendation: Cache Secret Manager requests. Impact: Delay and cost to secret store decreases. |
| Role List Size | Recommendation: Add only necessary roles to header. Impact: Response size decreases, network delay decreases. |
| Condition Usage | Recommendation: Avoid unnecessarily complex conditions, define specific filters. Impact: Policy evaluation time shortens. |
Client Id / Client Secret Management
When Manage From This Policy is selected, the Client Id and Client Secret values validated in token requests are the keys of the API Proxy, API Proxy Group, or Policy Group that this policy is attached to. The Show API Key option in the policy form opens a dialog where the current Client Id and Client Secret can be viewed, copied, and changed when needed. Both fields are read-only; use the eye button to show a value and the pencil button (Edit Client Id / Edit Client Secret) to change it.
Key Generation Type
When editing the Client Id or Client Secret, you type the name of the related record and select a key generation type:
- Automatic: The system generates a new random value.
- Manual: You type the value yourself. This is the only way to enter a key value by hand; a value consisting only of spaces is not accepted.
Changing a key is a critical operation: the Client ID will be changed and integrations that use the current value will stop working. You must confirm by typing the name of the related record, clicking Edit, then answering a final question ("Are you sure you want to change the key?"). The new key is kept as a draft; it is not valid until saved (Save, then confirm in the key dialog; Cancel discards the draft); after saving, the API Proxy, API Proxy Group, or Policy Group must be redeployed for the new keys to become active. Existing clients using this policy must also be reconfigured with the new Client Id/Client Secret values.
Consistency Across Screens
This Client Id / Client Secret viewing, copying, and editing experience (including the Automatic/Manual choice, name-confirmation, and final confirmation step) is identical to the key management sections on the API Proxy, Policy Group, and API Proxy Group screens. Whenever this OAuth 2 Authentication policy is attached to the policy list of an API Proxy, an API Proxy Group, or a Policy Group — whether selected as a global (shared) policy or created as a local policy specific to that API/Group — the Show API Key option in the policy form provides the same experience.
Token issuance and manual revocation (Manage From This Policy)
Delete Previous Token invalidates the client's earlier tokens only when a new token is issued. To revoke a specific token at any time, use the gateway POST /auth/revoke endpoint (RFC 7009) instead of a policy toggle; authenticate with the same proxy application key as for token issuance.
- Token issuance: Token Acquisition Methods (
POST /auth/token) - Introspection, revocation, and discovery: Token Introspection, Revocation, and Discovery (
/auth/introspect,/auth/revoke,/.well-known/oauth-authorization-server)
Token endpoints run at the root of your API Gateway access URL (\{gatewayAccessUrl\}/auth/token, \{gatewayAccessUrl\}/auth/revoke). Do not append /auth/token or /auth/revoke to an API Proxy client route path; proxied API calls use the client route, while token operations use the /auth-prefixed gateway endpoints.
Client Authentication — Authorization Basic Header Support (RFC 6749 §2.3.1)
Sending Credentials via Basic Authorization Header
Your client credentials (client_id and client_secret) can now be transmitted using HTTP Basic Authentication, following RFC 6749 standard compliance:
# With Basic Authorization header (new)
curl -u "my-client-id:my-secret" \
-d "grant_type=client_credentials" \
https://gateway.example.com/credential/token
Backward-Compatible Body Parameters
The legacy method of sending credentials in the request body remains fully supported:
# Via body parameters (backward compatible)
curl -d "grant_type=client_credentials&client_id=my-client-id&client_secret=my-secret" \
https://gateway.example.com/credential/token
Important Rules
- Mutual exclusivity: If you send both the Authorization Basic header AND
client_id/client_secretin the request body, the server rejects the request withinvalid_request(HTTP 400) per RFC 6749 §2.3.1 "MUST NOT". - Malformed headers: Invalid Base64 encoding or missing colon (
:) in the decoded credentials are rejected withinvalid_client(HTTP 401). - Non-Basic schemes: Authorization headers with schemes other than Basic (e.g.,
Bearer) are ignored; the server falls back to body parameters. - Resource owner password flow:
usernameandpassword(PASSWORD grant type) must always be sent in the request body; the Authorization Basic header is reserved for client credentials only.
Frequently Asked Questions (FAQ)
| Category | Question | Answer |
|---|---|---|
| General | Which grant types does the OAuth 2 Authentication Policy support? | CLIENT_CREDENTIALS and PASSWORD flows are supported; separate configuration can be made for each. |
| General | What happens if Manage From ACL is selected in the Management field? | Consumers, API clients and their ACL rows decide who may call; tokens follow the API client's settings. The grant type, identity source and token settings of the policy are not used and are not shown in the form. The authorization configuration is still shown in the form in this mode. The stored values of the clear authentication and add-user-to-header settings, which are hidden in the form, are still applied in this mode. |
| Technical | What additional settings are needed when Secret Manager is selected? | Identity set in vault should be selected through Identity Role Group, Check Client IP Address should be activated if necessary. |
| Technical | How is refresh token limit calculated? | Refresh Token Count field determines the allowed refresh count; new authentication is required when exceeded. |
| Usage | Does the change reflect immediately after binding the policy to API? | Deploy is required in global policy; in local policy, it reflects to API flow immediately after saving. |
| Usage | Is it safe to change header names? | Yes, but should be coordinated with downstream services; testing before change is recommended. |