API security depends on enforcing rules on the server, not on hiding a button in the client. Authentication identifies a caller; authorization decides whether that caller may act on a specific resource.
Validate and shape data deliberately
Accept only expected fields, validate types and limits, and return clear error responses. Resource representations should expose only the fields intended for that API. Do not accept ownership or permission decisions from client-controlled values.
Authorize individual records
A route-level check may confirm that a user is signed in, but each record still needs an ownership or policy decision. Test that one user cannot read or update another user's record by changing an identifier in the request.
Make the contract predictable
Use suitable status codes, consistent pagination, and stable validation responses. Apply rate limiting to resource-sensitive endpoints and avoid leaking stack traces or secrets.
Test the boundaries
- Valid authenticated requests succeed.
- Malformed and oversized values are rejected.
- Unauthenticated callers are denied.
- A user cannot access another user's records.