Skip to main content
KAWINDU WIJEWARDHANE
JOURNAL / API SecurityKAWINDU WIJEWARDHANE

The API Boundary Is the Security Boundary

Authentication proves an identity. Secure APIs must still constrain what that identity can access, which state it can change, and how every object relationship is enforced.

ARTICLEPublished August 3, 2026

Authentication proves an identity. Secure APIs must still constrain what that identity can access, which state it can change, and how every object relationship is enforced.

Many API failures begin with a correct login and an incorrect assumption. The server knows who sent the request, so the request is treated as trusted. Authentication answers only one question: which identity presented the credential? It does not answer whether that identity may read this record, change this field, trigger this transition, or act for this tenant.

Authorization must be evaluated at the object boundary. If an endpoint accepts an invoice ID, project ID, message ID, file key, or user ID, the server must prove that the authenticated identity has the required relationship with that specific object. Filtering a list in the interface is not enforcement. Hiding an identifier is not enforcement. A UUID makes guessing harder; it does not create permission.

Multi-tenant systems make this especially important. Tenant context should be derived from trusted server-side identity and applied to every query. Accepting a tenant identifier from a request and assuming it is valid creates a direct path to cross-tenant access. Data-access functions should make the secure condition difficult to omit—for example, requiring both the object identifier and tenant scope instead of allowing a global lookup followed by an optional check.

Field-level control matters too. Mass assignment appears when request data is passed too directly into an update operation. A user who is permitted to edit a profile may not be permitted to change its role, approval state, balance, ownership, or internal flags. Explicit input schemas are security controls. They describe not only the expected data type but the exact fields available in this operation.

State transitions deserve separate endpoints or commands when they represent meaningful authority. Approving an account, publishing content, issuing a refund, or rotating a credential is not simply a generic update with a different status value. Treating it as a named action makes authorization, validation, auditing, rate limiting, and review much clearer.

Errors must avoid becoming an information channel. Different responses for a missing object and an unauthorized object can reveal which identifiers exist. Verbose validation, stack traces, database errors, and upstream responses may expose implementation details. Clients need actionable errors, but they do not need the internal path that produced them.

Rate limits should be attached to risk rather than applied as one global number. Login attempts, password recovery, search, file processing, message dispatch, exports, and administrative actions have different abuse patterns and different costs. Useful limits combine identity, endpoint, resource, and network signals while avoiding the collection of raw connection data when a derived value is sufficient.

Finally, security tests should exercise relationships, not only responses. Test one user against another user’s object. Test one tenant against another tenant. Test lower roles against administrative transitions. Remove optional fields, add forbidden fields, repeat requests, alter content types, and replay stale tokens. The API boundary is where the product makes its real promises. Those promises must be enforced on every request, independently of the interface that happens to call it.

Return to the journal