API Gateways in Zero Trust Architecture: Identity, Policy, and Limits
API7.ai
September 18, 2026
An API gateway can be a policy enforcement point in zero trust architecture, but it is not the entire architecture. It can authenticate a credential, evaluate route-level policy, limit traffic, and pass verified context. The application must still authorize the requested object and business action, while identity, device, workload, and data systems supply decisions the gateway cannot invent.
The goal is not to "trust the gateway." The goal is to make every access decision use explicit evidence, minimum privilege, a defined policy owner, and observable failure behavior.
Key Takeaways
- Do not grant trust because traffic came from an internal network or passed through a gateway.
- Separate human, client, workload, network, and resource identity.
- Validate issuer, audience, signature, time, and required privileges for the exact API.
- Treat the gateway as one policy enforcement point; retain object and workflow authorization in the application.
- Define whether identity and policy dependency failures deny, retry, redirect, or use a bounded cached decision.
- Prevent direct backend access and strip caller-supplied identity headers before adding verified context.
Start with the Zero Trust Boundary
NIST SP 800-207 states that zero trust grants no implicit trust solely from physical or network location or asset ownership. Authentication and authorization are distinct functions performed before a session to an enterprise resource is established. NIST SP 800-207A applies this model to cloud-native access control with components such as ingress gateways, service meshes, identity-tier policies, and network-tier policies.
For an API, the protected resource is not merely a hostname. It may be one tenant's invoice, one payment action, one administrative operation, or one data field. Route admission can narrow access, but domain state determines the final decision.
sequenceDiagram
participant C as Client
participant G as API gateway enforcement point
participant I as Identity provider
participant P as Policy decision service
participant A as Application and resource
C->>G: Request plus credential
G->>I: Resolve keys metadata or active token state
I-->>G: Identity evidence
G->>P: Subject action resource and context
P-->>G: Permit or deny plus policy version
G->>A: Allowed request plus verified context
A->>A: Object and workflow authorization
A-->>G: Business response or denial
G-->>C: Bounded response with correlation ID
This is a responsibility diagram, not a requirement to make synchronous calls to both external systems on every request. Locally verified tokens, cached metadata, introspection, and policy caches have different revocation, freshness, and outage behavior. Document the selected path.
Keep Identities and Signals Separate
| Signal | What it can establish | What it cannot establish by itself |
|---|---|---|
| Valid access token | Claims signed or returned by the configured issuer under the validation rules | Current permission to every application object |
| mTLS client certificate | Possession of a private key for an accepted certificate identity | Human intent or business entitlement |
| Workload identity | Calling service or workload under the issuing trust domain | End-user authority carried by the request |
| Device posture | Device state reported by an approved posture system | User identity or API action correctness |
| Source IP | Network origin under the trusted-proxy configuration | Stable person, tenant, or workload identity |
| Request ID | A value for correlation | Authentication, authorization, or uniqueness when caller supplied |
Do not merge these into one "trusted user" field. Preserve provenance so a policy can distinguish an issuer-validated subject from a header, network observation, or application assertion.
Validate Tokens for the Intended API
RFC 9700 recommends sender-constrained and audience-restricted access tokens. Audience restriction reduces reuse at another resource server; sender constraint reduces use by a party that steals a bearer token. Neither replaces resource authorization.
At minimum, token validation should cover the expected issuer, signature and algorithm policy, expiration and not-before rules, the intended audience, and privileges needed by the route. A token that is cryptographically valid but minted for another API is not sufficient.
The following Apache APISIX 3.19.0 configuration is a schema-oriented excerpt for a machine-called API. It assumes the identity provider, Consumer context, upstream TLS, secret delivery, network policy, and application authorization are configured separately.
{ "uri": "/payments/*", "plugins": { "openid-connect": { "client_id": "payments-api", "client_secret": "$ENV://OIDC_CLIENT_SECRET", "discovery": "https://identity.example.com/.well-known/openid-configuration", "bearer_only": true, "use_jwks": true, "required_scopes": ["payments.read"], "claim_validator": { "issuer": { "valid_issuers": ["https://identity.example.com/"] }, "audience": { "required": true, "match_with_client_id": true } }, "ssl_verify": true, "set_access_token_header": false, "access_token_in_authorization_header": false, "set_id_token_header": false, "set_userinfo_header": false, "timeout": 3 } }, "upstream_id": "payments-api-verified-hop" }
In the openid-connect plugin, bearer_only defaults to false. The false path can use the authorization code flow and session behavior for an interactive client; the true path strictly requires a bearer access token and does not turn an API call into a browser login redirect. Select the path by client type rather than copying one setting across browser and machine APIs.
use_jwks defaults to false. On this bearer-token path, the false path uses token introspection; setting it to true with no public_key makes the plugin obtain the issuer's JWKS, verify the JWT signature locally, and skip introspection for the client-credentials flow. The example deliberately selects self-contained JWT verification. An introspection deployment needs a separately tested availability, authentication, cache, and revocation contract; it must not be described as local JWT signature validation.
The issuer allowlist pins the accepted JWT issuer. Both claim_validator.audience.required and claim_validator.audience.match_with_client_id default to false. With required: false, that flag alone does not require an aud claim; with true, the claim must be present. With match_with_client_id: false, the plugin does not compare the audience with client_id; with true, a string audience must equal payments-api, or an audience array must contain it. A missing or mismatched audience is rejected instead of admitting a token minted for another resource.
ssl_verify defaults to true in APISIX 3.19.0. The true path verifies the identity provider's TLS certificate; the false path disables that certificate verification and weakens the discovery, token, or introspection channel. Keep verification enabled in production and provision the correct CA trust. TLS verification authenticates the configured provider endpoint; it does not prove that an access token has the correct audience or that its subject may access a payment.
required_scopes rejects a validated token with HTTP 403 when any configured scope is missing. Scope is still a coarse privilege. The payment service must check the account, tenant, amount, workflow state, and action.
By default, set_access_token_header and set_userinfo_header are true, so available material is forwarded as X-Access-Token and X-Userinfo; setting either to false suppresses that header. set_id_token_header also defaults to true when an ID token is available, while false suppresses its unsigned, base64-encoded claims header. This example sets all three to false because the upstream does not need them. access_token_in_authorization_header defaults to false: when token propagation is enabled, false uses X-Access-Token, while true uses Authorization; it has no propagation effect here because set_access_token_header is false.
If another design forwards identity material, it is trusted only on an authenticated, bypass-protected gateway-to-application hop after caller-controlled copies are removed or overwritten. Forward the minimum claims needed by downstream policy, not a reusable token or complete identity document by default.
Define Policy Decision Ownership
Zero trust fails when every layer makes a partial, inconsistent decision. Assign each rule once:
- the identity provider owns credential issuance, authentication strength, and identity lifecycle;
- the gateway owns public route admission, protocol checks, coarse privilege, traffic budgets, and verified context propagation;
- a shared policy service owns cross-application contextual policy when it has authoritative inputs;
- the workload layer owns service-to-service identity and network reachability;
- the application owns object-level and workflow authorization;
- the data layer owns encryption, row or field controls, and durable audit evidence.
When multiple layers intentionally enforce the same invariant, name the authoritative decision and treat the others as defense in depth. Otherwise, a stale gateway rule may appear to authorize something the application denies, or a permissive application may rely on a route policy that is absent on another path.
Secure the Handoff to the Application
The gateway-to-application hop is a new trust boundary. Prevent clients from bypassing it through private networking, load balancers, alternate hostnames, or direct service exposure. Authenticate the gateway workload to the application with an appropriate mechanism, and encrypt the hop when the threat model requires it.
Before injecting identity context, remove the corresponding inbound headers. Use a documented namespace and include provenance such as issuer, subject, authentication method, gateway policy version, and decision ID. The application should reject requests that lack the expected authenticated handoff rather than accepting the same header from any reachable client.
Minimize propagated claims. Email addresses, group lists, and complete user-info documents create privacy exposure and stale authorization state. Send only the attributes the downstream policy actually needs.
Plan Failure and Freshness Paths
For each dependency, decide what happens when it is slow, unavailable, or stale:
| Dependency | Safe questions to answer before production |
|---|---|
| OIDC discovery or key set | How long are keys cached, how does rotation work, and when is a token rejected? |
| Token introspection | Is there a bounded cache, what is its revocation delay, and does timeout deny access? |
| Policy service | Which routes fail closed, is any cached permit reusable, and how is policy version recorded? |
| Device or risk signal | How fresh must it be, and can absence reduce privilege instead of granting access? |
| Audit pipeline | Can enforcement continue with bounded buffering, and how is evidence loss detected? |
Do not use a cached permit beyond the identity, resource, action, policy version, and maximum age for which it was issued. A generic "policy service unavailable" fallback can silently broaden access.
Test Both the Intended and Bypass Paths
Verify at least:
- missing, malformed, expired, wrong-issuer, wrong-audience, and insufficient-scope tokens;
- valid identity with denied tenant, object, or workflow action;
- forged identity, forwarding, and correlation headers;
- direct backend access around the gateway;
- identity-provider, policy-service, DNS, and TLS failure behavior;
- key and certificate rotation while traffic continues;
- clock skew at token time boundaries;
- logs that show the enforcement point, decision, reason, and policy version without recording credentials.
Measure false permits, false denies, dependency latency, cache age, policy version skew, bypass attempts, and unexplained authorization differences between the gateway and application.
Zero Trust Gateway Checklist
- Is every API resource and action assigned to an authorization owner?
- Are issuer, audience, time, signature, and privilege checks explicit?
- Are human, client, workload, device, network, and resource identities distinct?
- Are inbound identity headers removed before verified context is added?
- Is the backend unreachable except through authenticated approved paths?
- Are Boolean modes documented with defaults and both paths?
- Are dependency timeout, cache, revocation, and fail-open or fail-closed choices tested?
- Does the application still enforce tenant, object, and workflow authorization?
- Can telemetry explain who decided what without treating correlation as identity?
Frequently Asked Questions
Does mTLS make an API zero trust?
No. mTLS can authenticate a client or workload certificate at one connection boundary. The system still needs least privilege, resource authorization, identity lifecycle, policy evaluation, telemetry, and protection against alternate paths.
Should every authorization decision run at the gateway?
No. Put a decision where authoritative inputs and enforcement are available. The gateway is effective for route admission and shared coarse policy; the application usually has the domain state needed for object and workflow decisions.
Is an internal API allowed to skip authentication?
Network location alone should not grant implicit trust. Choose an appropriate workload or client identity and restrict reachability, while recognizing that identity verification and authorization are separate controls.
Next Steps
Combine this architecture with API gateway mTLS, fine-grained gateway authorization, and API access log auditing.