Who can access what

Access Control and Security Boundaries

Explains API keys, trusted source networks, scopes, replay protection, and log protection through an explicit deny-by-default model.

Explains API keys, trusted source networks, scopes, replay protection, and log protection through an explicit deny-by-default model.

5. Identity, API Key, and Authorization Model

5.1 API Key Credential Format

Clients pass credentials through the Authorization request header using the ApiKey authentication scheme. A credential consists of a public Key ID and a 256-bit random Secret. The public Key ID locates the record, and the Secret proves possession.

Security requirements:

  1. Generate Secrets with a cryptographically secure random source and entropy of at least 256 bits.
  2. Show a Secret only once, in the successful response for creation or rotation.
  3. The server must not store plaintext Secrets. Compute an HMAC-SHA-256 digest of the Secret with a KMS-protected Pepper and store the digest together with pepper_version.
  4. Digest comparison must use a constant-time algorithm.
  5. The gateway, WAF, APM, and application logs must consistently redact the Authorization request header.
  6. Production and non-production environments use different Keys. The request ingress, Key, route, and backend endpoint must belong to the same environment; any cross-environment combination is rejected.
  7. Pepper rotation applies only to newly issued Secret versions. An old Pepper remains available in read-only mode until every corresponding Secret version is invalid, and existing digests must not be recomputed or bulk-invalidated during rotation.

5.2 Permission Scopes

Permissions use three explicit identifiers: platform, resource, and operation. Initial examples are:

ScopeMeaning
webpay_inbox.payment.readRead WebPay Inbox payment information
webpay_inbox.payment.submitSubmit a payment operation to WebPay Inbox
bps.payment.readRead BPS payment information
bps.payment.submitSubmit a payment operation to BPS
zero_confirmation.payment.readRead Zero Confirmation payment information
zero_confirmation.payment.submitSubmit a payment operation to Zero Confirmation

The actual resource and operation catalog must be confirmed and published item by item by the owner of each platform. Authorization rules are:

  1. Every accessible route must declare one explicit required scope.
  2. An API Key must have that required scope; prefix matching and implicit wildcard permissions are prohibited.
  3. A new route must not be published without a bound required scope.
  4. A Scope change must create a new configuration version and an audit record.
  5. One API Key may explicitly hold Scopes across multiple platforms.

5.3 API Key and IP Binding

The binding granularity must be the API Key, not the merchant. A Key can bind to multiple explicit IPv4 addresses, IPv6 addresses, or CIDR ranges; an IP can be used with a Key only after it has been explicitly bound to that Key.

For a merchant with Key A, Key B, IP A, and IP B, the authorization matrix is:

API KeySource IPBinding existsResult
Key AIP AYesContinue with Scope validation
Key AIP BNoReject
Key BIP ANoReject
Key BIP BYesContinue with Scope validation

Detailed rules:

  1. A merchant-level IP list must not be automatically applied to all of that merchant's Keys.
  2. The same IP may be used by multiple Keys, but each binding must be created and audited independently.
  3. Normalize IPv4, IPv6, and CIDR values on write. Default self-service configuration permits only IPv4 /32 and IPv6 /128. IPv4 /29 through /31 and IPv6 /64 through /127 require a business reason and dual approval; IPv4 ranges smaller than /29 and IPv6 ranges smaller than /64 are always rejected.
  4. The data plane trusts only the client IP passed by the edge load balancer. Any X-Forwarded-For value supplied by a public-network request must not directly serve as an authorization input.
  5. The edge layer must overwrite client-supplied forwarding headers and pass the original IP to the gateway through a trusted network or PROXY Protocol.
  6. If the source IP cannot be determined reliably, deny by default; it must not degrade to API Key-only validation.
  7. When a merchant uses dynamic egress IPs or third-party NAT, it must first establish fixed egress or private-connectivity arrangements. Loosening the rule to an internet-scale CIDR is not allowed.
  8. Do not store duplicate or mutually inclusive ranges under the same Key. When a new binding overlaps an existing range, the control plane must reject it and require atomic replacement of the binding set first.

5.4 Key Lifecycle

API Key states are pending, active, suspended, revoked, and expired.

  1. Create: validate merchant, environment, Scope, and IP bindings, then generate the Key. The Secret is displayed only once.
  2. Activate: after approval, a high-privilege production Key moves from pending to active.
  3. Rotate: create a new Secret version for the same logical Key. By default, new and old versions coexist for 24 hours, after which the old version becomes invalid automatically.
  4. Suspend: used for short-term risk treatment and may be restored by an authorized administrator.
  5. Revoke: irreversible and must propagate rapidly to every region.
  6. Expire: automatically reject after the explicit expires_at time is reached.

The recommended maximum lifetime of a production Key is 180 days, with notifications to its owner 30 days, 14 days, 7 days, and 1 day before expiration. This schedule is a security recommendation and requires confirmation by the security and merchant-operations teams.

5.5 Request Replay Protection

A static API Key is inherently a Bearer credential. TLS and Key-level IP binding lower the risk of credential theft and remote replay, but they cannot prevent replay after a credential is stolen inside a trusted egress network, a TLS termination point, or a logging path.

The first read-only vertical slice may use TLS, API Key, and IP binding after the security team explicitly accepts the risk. Before any production payment.submit route is exposed, it must satisfy one of the following options:

  1. The merchant uses mTLS. The client certificate is explicitly bound to the API Key, and certificate-revocation checks are performed.
  2. The merchant uses a separate Ed25519 private key to sign the request method, canonicalized path, request-body SHA-256, UTC timestamp, random Nonce, Idempotency-Key, and API Key ID. The gateway stores the public key, allows five minutes of clock skew, and forbids reuse of a Nonce within 10 minutes.

The request-signing private key is held by the merchant and must never be received or stored by the gateway. Nonce state is stored in a secure cache synchronized between regions where write failover is permitted; if that state is unavailable and backend global-idempotency capability has not been verified, payment write requests fail closed. Whether TLS terminates at the WAF or passes through to the gateway is a deployment decision, but regardless of that choice, every termination point must redact credentials in logs and be governed by least privilege.

5.6 Access Control Center

The Access Control Center is the logical union of “API Key validation service plus API Gateway authorization-policy enforcement,” not a new monolithic service. The validation service verifies only the credential, state, environment, and Key-IP binding, and returns the identity and Scope set. Gateway policy then determines route visibility and the required scope. A route-match result may be held temporarily before authentication completes, but it must not produce a differentiated response.

%%{init: {"flowchart": {"curve": "linear", "nodeSpacing": 34, "rankSpacing": 38, "htmlLabels": true}}}%% flowchart TB REQUEST["Unified Ingress Layer output<br/>Key ID + Secret · Trusted source IP<br/>Ingress environment · Temporary route match"] --> PARSE["Parse public Key ID<br/>Malformed input goes directly to authentication denial"] SNAPSHOT["Local versioned snapshot<br/>Key · Secret digest · Status · Environment<br/>Key-IP · Scope · Routes"] --> LOOKUP["Read record and merge deny entries<br/>Validate epoch / sequence and validity period"] BREAKGLASS["Independent break-glass channel<br/>Signed local deny entries"] -.-> LOOKUP subgraph VERIFY["Component 1 · API Key validation service"] direction LR PARSE --> LOOKUP LOOKUP --> CREDENTIAL["Fixed-order validation<br/>Constant-time Secret comparison → Status and validity<br/>→ Environment → Key-IP binding"] CREDENTIAL --> AUTH{"Identity authentication passes?"} end AUTH -->|"No"| DENY401["Uniform 401<br/>Record the precise reason_code internally"] AUTH -->|"Yes"| IDENTITY["Verified identity<br/>merchant · Key · Scope set<br/>Configuration version"] subgraph POLICY["Component 2 · API Gateway authorization policy"] direction LR AUTHORIZE["Read temporary route match<br/>Route visibility · Required scope"] AUTHORIZE --> ALLOWED{"Route exists and Scope is sufficient?"} end IDENTITY --> AUTHORIZE ALLOWED -->|"No"| DENY404["Uniform 404<br/>Route absence and insufficient Scope share one semantic"] ALLOWED -->|"Yes"| OUTPUT["Output to Request Governance Layer<br/>Authorized request + trusted identity context"] classDef input fill:#F4F7FB,stroke:#72849A,color:#253954,stroke-width:1.5px classDef runtime fill:#FFFFFF,stroke:#4F79A7,color:#18212F,stroke-width:1.5px classDef policy fill:#EDF8F3,stroke:#16835E,color:#124D3B,stroke-width:1.5px classDef reject fill:#FFF2EC,stroke:#C7582B,color:#6B2812,stroke-width:1.5px class REQUEST,SNAPSHOT,BREAKGLASS input class PARSE,LOOKUP,CREDENTIAL,AUTH,IDENTITY runtime class AUTHORIZE,ALLOWED,OUTPUT policy class DENY401,DENY404 reject style VERIFY fill:#F8FBFF,stroke:#B8CDEA,stroke-width:2px style POLICY fill:#F5FBF8,stroke:#AAD8C7,stroke-width:2px

The local snapshot is not an independent authorization module. It is produced by the publishing path in Section 10.1 and read within each region by the validation service and gateway policy. An expired snapshot, an unconfirmable version, or an unknown Key fails closed. Break-glass deny entries are unioned with central configuration; they can only restrict access, never restore a Key or expand a Scope.

11. Security Design

  1. External connections use at least TLS 1.2 and preferably TLS 1.3; internal service-to-service communication uses mTLS.
  2. Peppers and internal signing keys in KMS are isolated by environment, region, and purpose. Pepper rotation retains the old version under Section 5.1 until every Secret that references it becomes invalid.
  3. Administrators use short-lived identity tokens and least-privilege roles. Merchant API Keys are not used to call administrative interfaces.
  4. Key creation, Scope privilege escalation, IP-range expansion, route publication, and cross-region-write switch changes are all audited.
  5. The gateway overwrites externally supplied merchant identity, permissions, source region, and internal tracing headers to prevent identity-header forgery.
  6. Request-body size, header count, path length, connection count, and concurrency all have explicit limits.
  7. Rate limiting includes at least four dimensions: source IP, API Key, merchant, and platform, and supports emergency blocking.
  8. Access logs do not record Authorization, Cookies, payment-card data, bank-account information, or complete request bodies.
  9. Source IP in logs is governed as sensitive data, with restricted query permission and a retention period.
  10. Perform Key-permission reviews every quarter, and both a cross-region failover exercise and an API Key leakage exercise every six months.

Complete STRIDE threat modeling in detailed design, focusing on forged forwarding headers, Key enumeration, Secret leakage, cache poisoning, configuration rollback, replay attacks, repeated cross-region writes, and internal identity-header forgery.