Gateway-Only Identity and the Header Trust Boundary
A retailer is splitting a 12-year-old JSP monolith into 40 microservices behind a Kubernetes ingress and a centralized API gateway. Customer JWTs are issued by an external identity provider with a 15-minute lifetime and a scope claim; the monolith currently calls downstream services with a shared service account. A partner bank will call three order APIs directly and requires static IP allowlisting plus mTLS, but its legacy client cannot perform OAuth token exchange. The security team proposes validating JWTs only at the gateway, stripping the Authorization header, and injecting an X-User-Id header for downstream services. A penetration test found that one internal service trusts X-User-Id from any caller when reached through the cluster network. The platform team wants a decision before the partner onboarding in six weeks; downtime is limited to a two-hour window.
1. Assess the proposal to validate JWTs only at the gateway, strip Authorization, and inject X-User-Id. What would you implement for internal service-to-service calls and for the partner bank, and why?
Read the worked answer
The proposal turns the API gateway into the only policy enforcement point and converts a strong token into a spoofable header. Once a request is inside the cluster, any workload, compromised pod, or misconfigured job can set X-User-Id and be trusted. The penetration test already demonstrates the consequence: horizontal impersonation. Stripping Authorization also removes the audience and scope claims that downstream services need for authorization, so the gateway cannot enforce fine-grained order-level access on behalf of every service.
Recommended model:
- Keep the gateway as an external PEP, but do not make it the only one. Forward a signed, short-lived token, or a token-exchange result, with audience bound to the target service, not a raw user ID.
- Enforce mTLS between services with workload identity, such as SPIFFE or a service mesh, and add authorization policy at each service for the specific operation. Default-deny network policy prevents direct pod-to-pod calls that bypass the mesh.
- If a header is needed for a legacy service, sign it with HMAC and strip any inbound copy at the ingress and sidecar. Prefer a token over a header.
- Replace the shared service account with per-service identities and token exchange that carries the actor (user) and subject (service), so the downstream sees both.
For the partner, IP allowlisting is only a coarse network control and fails behind NAT or shared egress. Terminate mTLS with a partner-specific client certificate, then have the gateway obtain a downstream token using OAuth client credentials or token exchange. If the partner truly cannot do token exchange, the gateway can act as the OAuth client while the partner authenticates with mTLS plus a signed request. The residual risk is a static partner secret; mitigate with certificate rotation, per-partner quotas, anomaly detection, and a narrow API product. Record this as an exception with an expiry date, not as the target architecture.
2. The partner's legacy client cannot perform OAuth token exchange. Compare two viable onboarding patterns and recommend one, including controls and residual risk.
Read the worked answer
Pattern A is mutual TLS plus HMAC-signed requests at the gateway, with the gateway performing token exchange to an internal token. The partner keeps its legacy client but must implement request signing and certificate rotation. Controls: per-partner client certificate in a trust store, CA validation, timestamp plus nonce to prevent replay, body hash, key in an HSM or protected keystore, IP allowlist as an additional signal, rate limiting, and schema validation. The gateway maps the partner identity to a service account with only the three order scopes. Residual risk: shared-secret compromise and replay if nonce storage is weak. Require short timestamp windows and idempotency keys.
Pattern B is OAuth client credentials with a client secret, plus mTLS. This is simpler if the partner can do OAuth, because the prompt only rules out token exchange, not client credentials. The gateway validates the partner token, checks audience and scope, and exchanges it for an internal token. The partner secret is still a bearer credential, so mTLS binding and IP allowlisting reduce but do not remove theft risk. Rotate secrets automatically.
Recommendation: use Pattern B if the partner client supports client credentials; otherwise use Pattern A. In both cases, do not let the partner call internal services directly; expose only the three API routes. Do not accept a static API key alone. Add per-partner rate limits, request and response logging with PII redaction, alerts on abnormal volume or object access, and quarterly access review. The exception should expire at the ERP migration date, when token exchange becomes mandatory.
3. You have six weeks and one two-hour downtime window. Sequence the remediation and define the go/no-go evidence.
Read the worked answer
Weeks 1-2: inventory the three partner APIs and all internal callers, and build a service-level authorization test harness. Put mesh mTLS and default-deny network policy into audit mode and capture what would break. Build token validation in one service and run it in shadow mode. Week 3: enforce header stripping at ingress and sidecars; make the vulnerable internal service reject unsigned X-User-Id in test. Week 4: canary token validation and mesh policy on two low-risk services; replay the penetration test. Week 5: onboard the partner in staging with mTLS and either client credentials or signed requests; test rotation, replay, quota, and error paths. Week 6: production cutover in the two-hour window: enable the gateway route, partner certificate, token exchange, then remove the shared service account.
Go/no-go evidence: a forged X-User-Id request is rejected; an expired token or one with the wrong audience is rejected at the service, not only at the gateway; a partner request without a certificate or with a bad signature fails; a valid partner order succeeds; rollback is a single feature flag plus restoring the old route. Monitor 401/403 rates, partner error rate, p95 latency, and authentication failures for 24 hours. If the internal service cannot be fixed before the window, narrow the partner scope or delay that route; do not accept a spoofable header to hit a date.