REST API Design and Security: Architecture-Level Best Practices and Standards
Designing a robust, platform-neutral REST API requires mastery of two interlocking disciplines: standards-based HTTP semantics (when, why, and where to use each HTTP method) and a comprehensive security architecture covering both user-facing and machine-to-machine access. This report consolidates guidance from IETF RFCs, the OWASP API Security project, and official documentation from Microsoft Azure, AWS, and Google Cloud.
Adhere to HTTP Semantics & Idempotency
GET is safe and cacheable — use it exclusively for read-only retrieval. POST creates resources or triggers processing — it is neither safe nor idempotent. PUT performs idempotent full-resource updates; PATCH applies partial updates (not guaranteed idempotent); DELETE removes resources idempotently.
Secure by Design — Zero Trust & Least Privilege
Mandate TLS for all API traffic, authenticate every request, and enforce token scopes/claims at the endpoint level. Design against the OWASP API Security Top 10 (2023 edition) threat categories, and implement rate limiting to counter unrestricted resource consumption.
Modern Auth: OAuth 2.0 / OIDC over SAML
OAuth 2.0 handles authorization via lightweight JSON tokens; OpenID Connect adds authentication on top. SAML 2.0 remains relevant for legacy enterprise SSO but is XML-heavy and browser-bound. The Microsoft identity platform uses OAuth for authorization and OIDC for authentication, while SAML is commonly used with identity providers such as AD FS federated to Microsoft Entra ID.
1. RESTful API Design Principles and HTTP Methods
1.1 Resource-Oriented Design and the Uniform Interface
A RESTful web API is built around resources — any object, data, or service the client can access — each uniquely identified by a URI. Two foundational principles govern design:
- Platform independence: clients call the API regardless of internal implementation, using HTTP as the standard protocol and a familiar format such as JSON or XML.
- Loose coupling: client and service evolve independently; only standard protocols and agreed-upon data formats bind them.
The uniform interface is realized through standard HTTP verbs — GET, POST, PUT, PATCH, and DELETE — applied to resources. Resource URIs should be modelled as nouns (e.g. /orders, /customers/1) rather than verbs (e.g. /createOrder). The HTTP method already implies the action. For example, creating a new order for customer 1 is expressed as POST /customers/1/orders with the order data in the body; retrieving all orders for that customer uses GET /customers/1/orders.
The Google Cloud API design guide, used internally at Google since 2014, reinforces resource-oriented design and recommends choosing methods in this priority order: (1) standard methods on collections/resources, (2) standard batch or aggregate methods, (3) custom methods, (4) streaming methods. Standard methods offer the greatest uniformity: they are automatable across declarative clients, CLIs, UIs, and SDKs.
RESTful APIs also use a stateless request model: each HTTP request is independent and self-contained, meaning the server retains no session state between requests. This supports high scalability because it removes any affinity between a client and a specific server.
1.2 GET vs POST — Safety, Idempotency, and Caching
The distinction between GET and POST is rooted in three formal properties defined in RFC 7231 (now obsoleted by RFC 9110, published in 2022):
| roperty | Definition | GET | POST | PUT | PATCH | DELETE | HEAD | OPTIONS |
|---|---|---|---|---|---|---|---|---|
| Safe | Read-only; no state change requested by the client | ? | ? | ? | ? | ? | ? | ? |
| Idempotent | Repeating N times ? doing it once (same state change) | ? | ? | ? | ? | ? | ? | ? |
| Cacheable | Responses may be stored and reused by intermediaries | ? | ? | ? | ? | ? | ? | ? |
Safe methods (GET, HEAD, OPTIONS, TRACE) are essentially read-only — the client does not request or expect any state change on the server, though incidental side effects such as logging may occur. Safety matters because browsers can prefetch safe requests, web crawlers can follow safe links automatically, users can bookmark and re-request safe URLs, and caches can serve responses without forwarding to the origin server.
Idempotent methods guarantee that executing the same request N times produces the same state change as executing it once (though the response body may differ between calls, e.g. different timestamps). All safe methods are idempotent, but not all idempotent methods are safe — DELETE and PUT change state but are idempotent.
GET should be used exclusively for retrieving a representation of a resource. A successful GET returns 200 OK with the resource in the body, 204 No Content when a search returns no matches, or 404 Not Found when the resource does not exist.
POST should be used to create a new resource or to submit data for processing to an existing resource without necessarily creating anything new. The server assigns the URI for a newly created resource and returns it in the Locationheader with a 201 Created status. Other valid POST responses include 200 OK (processing done, no new resource), 204 No Content, 400 Bad Request, and 405 Method Not Allowed. POST is neither safe nor idempotent — repeating a POST may create duplicate resources or repeat an action (e.g. charging a payment twice).
Anti-pattern alert: Using GET for operations that modify state — such as
GET /blog/1234/delete— violates HTTP semantics. Because GET is safe and cacheable, middleware proxies may cache the response, meaning a subsequent client requesting the same URL could receive the cached response without the server ever being contacted again, and a web crawler could inadvertently trigger the destructive action.
1.3 PUT, PATCH, and DELETE
PUT replaces or creates a resource at a client-specified URI. The client must supply a complete representation of the resource in the request body. PUT is idempotent: submitting the same request multiple times always results in the same resource state. Use PUT when the client can meaningfully assign the resource URI before it exists; otherwise, use POST for creation and PUT (or PATCH) for updates. Valid responses: 200 OK, 201 Created, 204 No Content, 409 Conflict.
PATCH performs a partial update to an existing resource, sending only the changed fields. Two common formats are JSON merge patch (RFC 7396, media type application/merge-patch+json) and JSON patch (RFC 6902, media type application/json-patch+json), the latter specifying changes as a sequence of operations (add, remove, replace, copy, test). PATCH is not guaranteed idempotent. Valid responses: 200 OK, 400 Bad Request, 409 Conflict, 415 Unsupported Media Type.
DELETE removes the resource at the specified URI and is idempotent: deleting the same resource twice yields the same end state (resource gone). Responses: 204 No Content (success) or 404 Not Found (resource already absent).
1.4 Pagination, Filtering, Sorting, and Field Selection
For large collections, the Azure Architecture Center recommends implementing pagination using limit and offset query parameters with meaningful defaults such as limit=25 and offset=0. Example: GET /orders?limit=25&offset=50.
To help prevent denial-of-service attacks, impose an upper bound on the number of items returned. If a service sets max-limit=25 and a client requests limit=1000, the service can either return 25 items or an HTTP Bad Request error, depending on documented policy.
Filtering allows clients to refine results by applying conditions via query parameters: GET /orders?minCost=100&status=shipped.
Sorting can be supported via a sort parameter (e.g. sort=price), with the caveat that different sort values alter the cache key and can negatively affect caching effectiveness.
Field selection (client-defined projections) lets clients request only needed fields using a parameter like fields=id,name, reducing payload size. The API must validate that the client is allowed to access the requested fields and must not expose fields that are not normally available.
The Google Cloud blog additionally cautions against “chatty” APIs that force many sequential calls: consider providing coarser-grained “experience APIs” that compose multiple domains into a single endpoint for common use cases, reducing network overhead. Observation studies cited by Google suggest that developers spend more than 51% of their time in editor and client environments versus approximately 18% on reference documentation, underscoring the importance of self-explanatory payload design.
1.5 Asynchronous Operations
When a POST, PUT, PATCH, or DELETE requires lengthy processing, return HTTP 202 (Accepted) with a Locationheader pointing to a status-polling endpoint. The status endpoint returns 200 OK with current progress and, optionally, a cancel link. When the asynchronous operation creates a new resource, the status endpoint returns 303 (See Other) with a Location header pointing to the new resource URI (e.g. /api/orders/12345).
1.6 Content Negotiation and Partial Responses
Clients indicate acceptable response formats via the Accept header (e.g. Accept: application/json, application/xml). If the server cannot match any listed media type, it returns 406 (Not Acceptable). When sending data, the Content-Type header specifies the format; if the server does not support it, it returns 415 (Unsupported Media Type).
For large binary resources (files, images), support partial retrieval via the Accept-Ranges header on GET responses and Range requests from clients. A HEAD request lets the client inspect the Content-Length and Accept-Ranges headers before deciding whether to fetch the resource in chunks.
1.7 Common Design Anti-Patterns
| Anti-Pattern | Why It Fails | Correct Approach |
Verbs in URIs (/createUser) | HTTP method already implies the action | Use nouns: POST /users to create, GET /users to list |
GET with side effects (GET /blog/1234/delete) | Violates safety; caches and crawlers may trigger it | Use DELETE /blogs/1234 |
| Tunneling everything through POST | Clients and caches cannot infer intent; no caching benefit | Use the semantically correct verb for each operation |
| Designing “inside-out” instead of “outside-in” | Exposes internal structure rather than consumer needs | Start from consumer use cases and work inward |
| Chatty APIs (many sequential calls) | Multiple network calls increase latency and operational cost | Offer experience APIs or batch endpoints |
| Missing pagination/filtering | Overwhelming payloads; potential DoS vector | Implement limit/offset with enforced upper bounds |
1.8 HATEOAS and Hypermedia
REST APIs can be driven by hypermedia links embedded in resource representations, a principle known as HATEOAS(Hypertext as the Engine of Application State). Each response contains links describing valid next actions, making the API self-documenting and enabling clients to discover capabilities dynamically. While not all APIs implement HATEOAS fully, embedding navigation links in responses (e.g. links to related resources, pagination cursors) improves discoverability and reduces hard-coded assumptions in client code.
2. API Security Architecture
2.1 Transport Security — HTTPS Is Non-Negotiable
Secure REST services must only provide HTTPS endpoints. TLS protects authentication credentials in transit (passwords, API keys, JWTs), allows clients to authenticate the service, and guarantees data integrity. For highly privileged web services, consider mutually authenticated client-side certificates (mutual TLS) to provide additional protection.
2.2 Authentication vs Authorization
Authentication (AuthN) is the process of proving that a caller is who they claim to be. The Microsoft identity platform uses the OpenID Connect protocol for handling authentication.
Authorization (AuthZ) is the act of granting an authenticated party permission to perform specific actions or access specific data. The Microsoft identity platform uses the OAuth 2.0 protocol for handling authorization.
Both must be enforced on every API endpoint. Without authentication, the API cannot identify the caller; without authorization, even a valid caller may exceed permitted access. Non-public REST services must perform access control at each API endpoint; user authentication should be centralized in an Identity Provider (IdP) that issues access tokens.
2.3 Token-Based Security — JWTs, Access Tokens, and Refresh Tokens
There is a convergence toward using JSON Web Tokens (JWT) as the format for security tokens in REST APIs. JWTs are JSON data structures containing a set of claims that can be used for access control decisions. A cryptographic signature or message authentication code (MAC) protects integrity.
The Microsoft identity platform defines three primary token types:
| Token Type | Purpose | Issued Via |
| Access token | Grants access to a protected resource; contains user/resource info | OAuth 2.0 flow |
| Refresh token | Exchanged for a new access token when the current one expires | Issued alongside access token (short-lived access tokens paired with longer-lived refresh tokens) |
| ID token | Authenticates the user; conveys identity claims | OpenID Connect flow |
Access tokens are passed as the bearer token in the Authorization header. The resource server validates the token by verifying the signature using the authorization server’s published public key.
Critical JWT validation rules from the OWASP REST Security Cheat Sheet:
- Never allow unsecured JWTs (
{"alg":"none"}). - Prefer signatures over MACs for integrity protection; with MACs, all services sharing the same key can forge new tokens, meaning a compromise of any one service compromises all others using that key.
- The relying party must verify integrity based on its own configuration, not the JWT header’s algorithm claim, to prevent algorithm-substitution attacks.
- At minimum, validate the following standard claims:
iss(issuer — is this a trusted issuer?),aud(audience — is this token intended for this service?),exp(expiration time — has the token expired?), andnbf(not-before time — is the token valid yet?).
2.4 Scopes and Claims for Least Privilege
Claims are name-value pairs that relay facts about the token subject: the security token server that generated it, generation date, subject identity, audience (the app the token was generated for), and the requesting client app. Applications use claims to validate the token, identify the subject’s tenant, display user information, and determine authorization.
Scopes define the permitted access for a service within an OAuth 2.0 flow. They are a way for the resource server to group permissions related to actions and resources, and they specify the coarse-grained operations OAuth 2.0 clients can request. Scopes are defined per section 3.3 of OAuth 2.0 (RFC 6749). AWS IAM Identity Center enforces a maximum of 25 scopes per access token request.
Design your token issuance to grant only the minimum scopes and claims necessary for the client’s function — this is the principle of least privilege, aligned with the Zero Trust tenet of “use least privilege access”.
2.5 API Keys — Supplementary, Not Sole Protection
Public REST services without access control risk excessive bandwidth or compute costs. API keys can mitigate this risk and are often used to monetize APIs via purchased access plans. However:
- Require API keys for every request to protected endpoints.
- Return 429 Too Many Requests if requests arrive too quickly.
- Revoke the API key if the client violates the usage agreement.
- Do not rely exclusively on API keys to protect sensitive, critical, or high-value resources — they are relatively easy to compromise when issued to third-party clients.
2.6 OWASP API Security Top 10 (2023 Edition)
The following table captures the ten most critical API security risks identified by OWASP in 2023:
| # | Risk | Description |
| API1 | Broken Object Level Authorization | APIs expose endpoints handling object identifiers, creating a wide attack surface; object-level authorization checks should occur in every function accessing a data source using a user-supplied ID |
| API2 | Broken Authentication | Incorrectly implemented auth mechanisms allow attackers to compromise tokens or assume other users’ identities, compromising API security overall |
| API3 | Broken Object Property Level Authorization | Combines excessive data exposure and mass assignment — improper validation at the object property level leads to information exposure or manipulation |
| API4 | Unrestricted Resource Consumption | API requests consume network bandwidth, CPU, memory, and storage; successful attacks cause denial of service or cost escalation |
| API5 | Broken Function Level Authorization | Complex access policies with unclear separation between admin and regular functions lead to authorization flaws, allowing access to others’ resources or admin functions |
| API6 | Unrestricted Access to Sensitive Business Flows | Business flows (buying a ticket, posting a comment) exposed without compensating for automated excessive use |
| API7 | Server-Side Request Forgery (SSRF) | API fetches a remote resource without validating the user-supplied URI, enabling crafted requests to unexpected destinations even behind firewalls |
| API8 | Security Misconfiguration | Complex configurations are missed or don’t follow security best practices, opening the door for attacks |
| API9 | Improper Inventory Management | APIs expose more endpoints than traditional web apps; proper inventory of hosts and deployed API versions is critical to mitigate issues like deprecated API versions and exposed debug endpoints |
| API10 | Unsafe Consumption of APIs | Developers trust third-party API data more than user input and adopt weaker standards; attackers target integrated third-party services instead of the API directly |
2.7 Zero Trust Considerations for APIs
The Zero Trust security model assumes breach and verifies each request as though it originated from an uncontrolled network, regardless of where it actually originates or what resource it accesses. Microsoft’s developer guidance distills this into three guiding principles:
- Verify explicitly — authenticate and authorize based on all available data points on every request.
- Use least privilege access — limit user and service access with just-in-time and just-enough-access policies.
- Assume breach — minimize blast radius by segmenting access, verifying end-to-end encryption, and using analytics to detect and respond to threats.
For API developers, this means: do not bypass security checks for internal calls. Instead of believing everything behind the corporate firewall is safe, verify identity and permissions on every request — “never trust, always verify”. Compromised applications can affect the entire organization; the work-from-anywhere workforce and hybrid cloud environments have redefined the security perimeter such that data is accessed outside the corporate network and shared with external collaborators.
Microsoft’s guidance recommends using Zero Trust identity and access management best practices throughout the application development lifecycle, protecting APIs through registration, defining permissions and consent, and enforcing access to achieve Zero Trust goals.
3. OAuth 2.0 / OpenID Connect vs SAML 2.0
3.1 OAuth 2.0 — Delegated Authorization
OAuth 2.0 is a protocol that allows applications to access and share user data securely without sharing passwords. It provides a secure and standardized way for users to allow applications access to their resources, facilitated by different grant flows.
Key architectural roles:
- Resource Owner — the user who owns the data.
- Client — the application requesting access.
- Authorization Server — the identity provider that authenticates the user and issues tokens.
- Resource Server — the API that validates tokens and serves protected resources.
Standardized grant flows supported by modern identity services (per AWS IAM Identity Center):
| Grant Flow | RFC | Use Case |
| Authorization Code Grant with PKCE | RFC 6749 + RFC 7636 | Web and mobile apps running on devices with a browser |
| Device Authorization Grant | RFC 8628 | Devices with or without a browser (e.g. CLI tools, IoT) |
| Client Credentials | RFC 6749 | Machine-to-machine (M2M) / server-to-server, no human user involved |
The Microsoft identity platform lists six supported authorization flows, each producing different token combinations:
| Flow | ID Token | Access Token | Refresh Token | Authorization Code |
| Authorization code flow | ? | ? | ? | ? |
| Implicit flow | ? | ? | — | — |
| Hybrid OIDC flow | ? | — | — | ? |
| Refresh token redemption | ? | ? | ? | — |
| On-behalf-of flow | ? | ? | ? | — |
| Client credentials | — | ?(App only) | — | — |
Source: [learn.microsoft.com]
The Authorization Code flow with PKCE proceeds as follows: a browser opens, the user authenticates (if not already), a consent screen displays the application name and the access scopes being requested, and after consent is granted the application proceeds with access based on the user’s permissions.
3.2 OpenID Connect (OIDC) — Authentication Layer over OAuth
OIDC is an authentication protocol built on top of the OAuth 2.0 framework. While OAuth alone provides authorization(granting token-based access to APIs), OIDC adds authentication — confirming the user’s identity — by introducing the ID token, a JWT containing identity claims (subject, name, email, etc.).
The Microsoft identity platform clarifies the relationship: “The platform uses OAuth for authorization and OpenID Connect (OIDC) for authentication. OpenID Connect is built on top of OAuth 2.0, so the terminology and flow are similar between the two. You can even both authenticate a user (through OpenID Connect) and get authorization to access a protected resource that the user owns (through OAuth 2.0) in one request”.
OIDC is commonly used for apps that are purely in the cloud, such as mobile apps, websites, and web APIs.
3.3 SAML 2.0 — XML-Based Enterprise SSO
SAML 2.0 is an industry standard used for securely exchanging SAML assertions that pass information about a user between a SAML authority (called an Identity Provider or IdP) and a SAML consumer (called a Service Provider or SP). This information is used to provide federated single sign-on access for authorized users.
SAML operates via browser redirects and XML-based signed assertions: the user attempts to access an SP, is redirected to the IdP for authentication, and upon success the IdP posts a signed XML assertion back to the SP through the user’s browser. The SP validates the assertion and establishes a session.
Enterprise applications that use SAML authentication are commonly integrated with identity providers such as Active Directory Federation Services (AD FS) federated to Microsoft Entra ID. Many enterprise apps also use SAML assertions, as referenced by the Microsoft Tokens and Claims documentation.
3.4 Comparative Analysis — When to Use Which
| Dimension | OAuth 2.0 / OIDC | SAML 2.0 |
| Primary purpose | OAuth: authorization; OIDC: authentication + authorization | Authentication and SSO |
| Token/assertion format | JSON (JWT) — compact, web-friendly | XML — verbose, requires signature validation |
| Transport | HTTP/REST, JSON payloads | Browser POST of XML assertions |
| Client types | Mobile, SPA, web, server, IoT, CLI | Browser-based web applications primarily |
| Enterprise SSO | Supported (especially OIDC); preferred for cloud-native apps | Widely deployed; commonly used with ADFS + Microsoft Entra ID |
| API authorization | Native capability (access tokens with scopes) | Not designed for API authorization; requires translation layer |
| Token validation | Fast local validation via JWT signature + public key | Requires XML signature validation and certificate trust chain |
| Specification lineage | IETF RFC 6749 (OAuth 2.0), OpenID Foundation (OIDC) | OASIS standard (2005) |
When to prefer OAuth 2.0 / OIDC:
- Any new REST API — user-facing or M2M.
- Mobile or single-page applications where lightweight JSON tokens and HTTP-based flows are essential.
- Scenarios requiring fine-grained API access control through scopes and claims.
- Multi-platform environments (Azure, AWS, GCP all standardize on OAuth2/OIDC).
When SAML remains relevant:
- Legacy enterprise applications that only support SAML-based SSO.
- B2B federation with partners whose identity infrastructure is SAML-based.
- Environments where AD FS is the primary federation service and OIDC migration is not yet complete.
Tradeoff: SAML’s maturity and XML extensibility allow it to carry rich attribute statements, which can be useful for complex enterprise authorization decisions in legacy systems. However, this comes at the cost of complexity, payload size, and incompatibility with non-browser clients (mobile, CLI, IoT). OAuth 2.0/OIDC trades some of that extensibility for simplicity, speed, and broad client support — which is why the industry has converged on it for modern API architectures.
3.5 Hybrid Environments
In practice, organizations frequently combine both protocols. The Microsoft identity platform explicitly supports this: “The platform uses OAuth 2.0 for authorization and SAML for authentication” and documents a SAML bearer assertion flow where SAML-based authentication can be exchanged for OAuth tokens to call protected APIs. This allows an enterprise user to authenticate via SAML with a corporate IdP and then receive OAuth-based access tokens for API consumption — bridging legacy SSO infrastructure with modern API security.
3.6 Implementation Guidance
For OAuth 2.0 / OIDC:
- Use the Authorization Code Grant with PKCE for public clients (mobile, SPA); the implicit flow is deprecated in favor of this approach.
- Use Client Credentials for M2M communication where no user is present.
- Validate tokens rigorously: check
iss,aud,exp,nbfclaims; verify the cryptographic signature using the authorization server’s public key; never rely on the JWT header’salgclaim to select the verification algorithm. - Each Microsoft Entra tenant publishes a standards-compliant well-known metadata document containing information about the issuer name, authentication and authorization endpoints, supported scopes, and claims.
- Use established libraries such as the Microsoft Authentication Libraries (MSAL), which implement token acquisition, refresh, and validation, and support standards-compliant discovery of tenant settings and keys using the OpenID well-known discovery document.
For SAML 2.0:
- Rely on vetted SAML libraries for XML parsing, signature validation, and assertion handling — avoid custom implementations.
- Note that AWS IAM Identity Center does not support validating signatures of incoming SAML authentication requests from SAML applications; the assertion from the IdP is validated, but the SP-initiated AuthN request signature is not checked at the AWS end.
- If you need to translate SAML-authenticated sessions into API access tokens, use an intermediary (identity broker) that can exchange SAML assertions for OAuth tokens.
Key Authoritative References
All guidance in this report is grounded in the following official and standards-body sources:
- Azure Architecture Center — Best practices for RESTful web API design
- Google Cloud — API design guide (used inside Google since 2014); 6 common mistakes in RESTful API design
- Google AIP-130 — Standard methods and method categories
- IETF — RFC 7231 (HTTP/1.1 Semantics and Content, June 2014; obsoleted by RFC 9110); RFC 6749 (OAuth 2.0 Authorization Framework); RFC 7636 (PKCE); RFC 8628 (Device Authorization Grant); RFC 5789 (PATCH); RFC 7396 (JSON Merge Patch); RFC 6902 (JSON Patch)
- OWASP — API Security Top 10 (2023); REST Security Cheat Sheet
- Microsoft Identity Platform — Authentication vs. authorization; Tokens and claims overview
- Microsoft Zero Trust — Develop using Zero Trust principles
- AWS — Single sign-on access to SAML 2.0 and OAuth 2.0 applications; Best practices for API Gateway private APIs
- NIST — SP 800-207, Zero Trust Architecture (August 2020)