Choose the service by the required credential
A fictional portal lets partners inspect positions and upload documents. First draw the path: browser, login, API, storage. A Cognito user pool authenticates users and issues application tokens; an identity pool can exchange federated identity for temporary AWS credentials constrained by IAM. A browser that only calls the API need not receive direct bucket access. Where direct upload is justified, define the allowed resource and operations in the temporary role. Record who administers users, who approves permissions, and who removes partner access. This division also identifies the team that must investigate a failed request.
Validate the token, then the operation
Reading a JWT payload does not verify its signature. Use a suitable library configured for the expected issuer, signing key, expiry, token use, and client. Check aud in an ID token; for a Cognito access token, check client_id and the required scopes, together with any audience restrictions in the design. A signed token for another client does not become acceptable merely because it came from the same pool. Here, positions.read permits retrieval, not order submission. A valid scope alone does not establish fund ownership: the API must enforce object access rules. Those business rules are decisions in this fictional design.
Design the browser sign-in path
An application running entirely in the browser cannot keep a client secret confidential. For this example’s public client, use authorization code with PKCE and S256, the method supported by Cognito. Retain the transaction’s verifier and present it during code exchange; do not treat it as a permanent client secret. The submitted callback must match the preregistered URI. Moving from /callback to /login/return therefore requires reviewing that configuration. Acceptance should cover an unregistered callback, a code without the correct verifier, and a wrong client. Operations needs to know the owner of each failure without copying tokens into its report.
Trace WAF order and scope
In a web ACL, start with the lowest numeric priority. Count records a match and continues evaluation; Allow and Block terminate it. An overly broad Allow before a blocking rule can therefore prevent that rule from being evaluated. Configure CloudFront’s global scope in us-east-1; for a regional ALB, use the ALB’s Region. Each resource associates with one web ACL, which can contain multiple rules and groups. Two teams should combine their protections within that design rather than attempt a second ACL association. Trace a request manually to its final action before changing priorities, and record which rules were never reached.
Understand inspection boundaries
An IP aggregation key groups users sharing that address, such as staff behind one NAT. WAF rate limiting is approximate and is unsuitable as an exact commercial quota counter. For a forwarded IP header, distinguish missing, invalid, and valid input: in a simple positive statement, a missing header does not match and does not invoke fallback; NOT would invert that result. Establish who writes the header because a client may forge it if the trust boundary permits this. Continue on an oversized body inspects only the available portion. Decide how to handle legitimate uploads and uninspected bytes before accepting the policy.
Hand usable protection to operations
Before blocking, test rules in staging and observe Count against representative traffic. Investigate a match on a legitimate upload; tune the specific rule and repeat acceptance instead of adding a broad Allow that skips other inspections. Attaching WAF to CloudFront does not automatically close direct ALB access. The public-origin example includes network restrictions and a secret header checked by the listener over HTTPS; test the direct path as well. Finally, redacting a header in WAF logs does not hide it in samples: configure sampling data protection or disable sampling. Hand owners, metrics, and a rollback condition to RUN.
Workshop: a token carries positions.read, but the request submits an order. The API must reject that operation. Next trace two WAF rules matching the same upload: priority 10 Allow and 30 Block. The result is Allow; Block is never reached. Redesign the exception so it does not allow all partner traffic early, then define one regression check for the legitimate upload and another for the malicious request. Values, rules, and partners are fictional.
Common pitfalls
Confusing JWTs with IAM credentials; trusting decode without signature verification; accepting another aud; hiding a secret in JavaScript; treating Count as blocking; equating an IP with one person; trusting client-supplied headers; assuming complete upload inspection; redacting logs while overlooking sampling.
Related topics: Identity, trust, and permissions · Data protection and recovery · CloudFront: caching, privacy, and origin
Decide separately who the user is, what they may do, and which requests pass the protection. Accept the solution with allowed and denied examples, explicit inspection boundaries, and a recovery procedure. This documentary workshop does not execute Cognito or WAF in AWS.
Reference: Amazon Cognito user pools · SAA-C03