{"id":2761,"date":"2026-05-03T12:35:36","date_gmt":"2026-05-03T16:35:36","guid":{"rendered":"https:\/\/shirishranjit.com\/blog1\/?page_id=2761"},"modified":"2026-05-03T13:04:36","modified_gmt":"2026-05-03T17:04:36","slug":"rest-api-design-and-security-architecture-level-best-practices-and-standards","status":"publish","type":"page","link":"https:\/\/shirishranjit.com\/blog1\/architect-principles\/rest-api-design-and-security-architecture-level-best-practices-and-standards","title":{"rendered":"REST API Design and Security: Architecture-Level Best Practices and Standards"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\"><br \/>REST API Design and Security: Architecture-Level Best Practices and Standards<\/h1>\n\n\n\n<p>Designing a robust, platform-neutral REST API requires mastery of two interlocking disciplines:&nbsp;standards-based HTTP semantics&nbsp;(when, why, and where to use each HTTP method) and a&nbsp;comprehensive security architecture&nbsp;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.<\/p>\n\n\n\n<style>\n        :root {\n        --accent: #464feb;\n        --timeline-ln: linear-gradient(to bottom, transparent 0%, #b0beff 15%, #b0beff 85%, transparent 100%);\n        --timeline-border: #ffffff;\n        --bg-card: #f5f7fa;\n        --bg-hover: #ebefff;\n        --text-title: #424242;\n        --text-accent: var(--accent);\n        --text-sub: #424242;\n        --radius: 12px;\n        --border: #e0e0e0;\n        --shadow: 0 2px 10px rgba(0, 0, 0, 0.06);\n        --hover-shadow: 0 4px 14px rgba(39, 16, 16, 0.1);\n        --font: \"Segoe Sans\", \"Segoe UI\", \"Segoe UI Web (West European)\", -apple-system, \"system-ui\", Roboto, \"Helvetica Neue\", sans-serif;\n        --overflow-wrap: break-word;\n    }\n\n    @media (prefers-color-scheme: dark) {\n        :root {\n            --accent: #7385ff;\n            --timeline-ln: linear-gradient(to bottom, transparent 0%, transparent 3%, #6264a7 30%, #6264a7 50%, transparent 97%, transparent 100%);\n            --timeline-border: #424242;\n            --bg-card: #1a1a1a;\n            --bg-hover: #2a2a2a;\n            --text-title: #ffffff;\n            --text-sub: #ffffff;\n            --shadow: 0 2px 10px rgba(0, 0, 0, 0.3);\n            --hover-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);\n            --border: #3d3d3d;\n        }\n    }\n\n    @media (prefers-contrast: more),\n    (forced-colors: active) {\n        :root {\n            --accent: ActiveText;\n            --timeline-ln: ActiveText;\n            --timeline-border: Canvas;\n            --bg-card: Canvas;\n            --bg-hover: Canvas;\n            --text-title: CanvasText;\n            --text-sub: CanvasText;\n            --shadow: 0 2px 10px Canvas;\n            --hover-shadow: 0 4px 14px Canvas;\n            --border: ButtonBorder;\n        }\n    }\n\n    .insights-container {\n        display: grid;\n        grid-template-columns: repeat(2,minmax(240px,1fr));\n        padding: 0px 16px 0px 16px;\n        gap: 16px;\n        margin: 0 0;\n        font-family: var(--font);\n    }\n\n    .insight-card:last-child:nth-child(odd){\n        grid-column: 1 \/ -1;\n    }\n\n    .insight-card {\n        background-color: var(--bg-card);\n        border-radius: var(--radius);\n        border: 1px solid var(--border);\n        box-shadow: var(--shadow);\n        min-width: 220px;\n        padding: 16px 20px 16px 20px;\n    }\n\n    .insight-card:hover {\n        background-color: var(--bg-hover);\n    }\n\n    .insight-card h4 {\n        margin: 0px 0px 8px 0px;\n        font-size: 1.1rem;\n        color: var(--text-accent);\n        font-weight: 600;\n        display: flex;\n        align-items: center;\n        gap: 8px;\n    }\n\n    .insight-card .icon {\n        display: inline-flex;\n        align-items: center;\n        justify-content: center;\n        width: 20px;\n        height: 20px;\n        font-size: 1.1rem;\n        color: var(--text-accent);\n    }\n\n    .insight-card p {\n        font-size: 0.92rem;\n        color: var(--text-sub);\n        line-height: 1.5;\n        margin: 0px;\n        overflow-wrap: var(--overflow-wrap);\n    }\n\n    .insight-card p b, .insight-card p strong {\n        font-weight: 600;\n    }\n\n    .metrics-container {\n        display:grid;\n        grid-template-columns:repeat(2,minmax(210px,1fr));\n        font-family: var(--font);\n        padding: 0px 16px 0px 16px;\n        gap: 16px;\n    }\n\n    .metric-card:last-child:nth-child(odd){\n        grid-column:1 \/ -1; \n    }\n\n    .metric-card {\n        flex: 1 1 210px;\n        padding: 16px;\n        background-color: var(--bg-card);\n        border-radius: var(--radius);\n        border: 1px solid var(--border);\n        text-align: center;\n        display: flex;\n        flex-direction: column;\n        gap: 8px;\n    }\n\n    .metric-card:hover {\n        background-color: var(--bg-hover);\n    }\n\n    .metric-card h4 {\n        margin: 0px;\n        font-size: 1rem;\n        color: var(--text-title);\n        font-weight: 600;\n    }\n\n    .metric-card .metric-card-value {\n        margin: 0px;\n        font-size: 1.4rem;\n        font-weight: 600;\n        color: var(--text-accent);\n    }\n\n    .metric-card p {\n        font-size: 0.85rem;\n        color: var(--text-sub);\n        line-height: 1.45;\n        margin: 0;\n        overflow-wrap: var(--overflow-wrap);\n    }\n\n    .timeline-container {\n        position: relative;\n        margin: 0 0 0 0;\n        padding: 0px 16px 0px 56px;\n        list-style: none;\n        font-family: var(--font);\n        font-size: 0.9rem;\n        color: var(--text-sub);\n        line-height: 1.4;\n    }\n\n    .timeline-container::before {\n        content: \"\";\n        position: absolute;\n        top: 0;\n        left: calc(-40px + 56px);\n        width: 2px;\n        height: 100%;\n        background: var(--timeline-ln);\n    }\n\n    .timeline-container > li {\n        position: relative;\n        margin-bottom: 16px;\n        padding: 16px 20px 16px 20px;\n        border-radius: var(--radius);\n        background: var(--bg-card);\n        border: 1px solid var(--border);\n    }\n\n    .timeline-container > li:last-child {\n        margin-bottom: 0px;\n    }\n\n    .timeline-container > li:hover {\n        background-color: var(--bg-hover);\n    }\n\n    .timeline-container > li::before {\n        content: \"\";\n        position: absolute;\n        top: 18px;\n        left: -40px;\n        width: 14px;\n        height: 14px;\n        background: var(--accent);\n        border: var(--timeline-border) 2px solid;\n        border-radius: 50%;\n        transform: translateX(-50%);\n        box-shadow: 0px 0px 2px 0px #00000012, 0px 4px 8px 0px #00000014;\n    }\n\n    .timeline-container > li h4 {\n        margin: 0 0 5px;\n        font-size: 1rem;\n        font-weight: 600;\n        color: var(--accent);\n    }\n\n    .timeline-container > li h4 em {\n        margin: 0 0 5px;\n        font-size: 1rem;\n        font-weight: 600;\n        color: var(--accent);\n        font-style: normal;\n    }\n\n    .timeline-container > li * {\n        margin: 0;\n        font-size: 0.9rem;\n        color: var(--text-sub);\n        line-height: 1.4;\n    }\n\n    .timeline-container > li * b, .timeline-container > li * strong {\n        font-weight: 600;\n    }\n        @media (max-width:600px){\n        .metrics-container,\n        .insights-container{\n            grid-template-columns:1fr;\n      }\n    }\n<\/style>\n<div class=\"insights-container\">\n  <div class=\"insight-card\">\n    <h4>Adhere to HTTP Semantics &#038; Idempotency<\/h4>\n    <p><strong>GET<\/strong> is safe and cacheable \u2014 use it exclusively for read-only retrieval. <strong>POST<\/strong> creates resources or triggers processing \u2014 it is neither safe nor idempotent. <strong>PUT<\/strong> performs idempotent full-resource updates; <strong>PATCH<\/strong> applies partial updates (not guaranteed idempotent); <strong>DELETE<\/strong> removes resources idempotently.<\/p>\n  <\/div>\n  <div class=\"insight-card\">\n    <h4>Secure by Design \u2014 Zero Trust &#038; Least Privilege<\/h4>\n    <p>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.<\/p>\n  <\/div>\n  <div class=\"insight-card\">\n    <h4>Modern Auth: OAuth 2.0 \/ OIDC over SAML<\/h4>\n    <p>OAuth 2.0 handles <em>authorization<\/em> via lightweight JSON tokens; OpenID Connect adds <em>authentication<\/em> 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.<\/p>\n  <\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. RESTful API Design Principles and HTTP Methods<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1.1 Resource-Oriented Design and the Uniform Interface<\/h3>\n\n\n\n<p>A RESTful web API is built around&nbsp;resources&nbsp;\u2014 any object, data, or service the client can access \u2014 each uniquely identified by a&nbsp;URI. Two foundational principles govern design:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>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.<\/li>\n\n\n\n<li>Loose coupling: client and service evolve independently; only standard protocols and agreed-upon data formats bind them.<\/li>\n<\/ul>\n\n\n\n<p>The&nbsp;uniform interface&nbsp;is realized through standard HTTP verbs \u2014&nbsp;<code>GET<\/code>,&nbsp;<code>POST<\/code>,&nbsp;<code>PUT<\/code>,&nbsp;<code>PATCH<\/code>, and&nbsp;<code>DELETE<\/code>&nbsp;\u2014 applied to resources. Resource URIs should be modelled as&nbsp;nouns&nbsp;(e.g.&nbsp;<code>\/orders<\/code>,&nbsp;<code>\/customers\/1<\/code>) rather than verbs (e.g.&nbsp;<code>\/createOrder<\/code>). The HTTP method already implies the action. For example, creating a new order for customer 1 is expressed as&nbsp;<code>POST \/customers\/1\/orders<\/code>&nbsp;with the order data in the body; retrieving all orders for that customer uses&nbsp;<code>GET \/customers\/1\/orders<\/code>.<\/p>\n\n\n\n<p>The Google Cloud API design guide, used internally at Google since 2014, reinforces resource-oriented design and recommends choosing methods in this priority order:&nbsp;(1)&nbsp;standard methods on collections\/resources,&nbsp;(2)&nbsp;standard batch or aggregate methods,&nbsp;(3)&nbsp;custom methods,&nbsp;(4)&nbsp;streaming methods. Standard methods offer the greatest uniformity: they are automatable across declarative clients, CLIs, UIs, and SDKs.<\/p>\n\n\n\n<p>RESTful APIs also use a&nbsp;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.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.2 GET vs POST \u2014 Safety, Idempotency, and Caching<\/h3>\n\n\n\n<p>The distinction between GET and POST is rooted in three formal properties defined in RFC 7231 (now obsoleted by RFC 9110, published in 2022):<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-1 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:100%\">\n<figure class=\"wp-block-table is-style-stripes\"><table class=\"has-fixed-layout\"><tbody><tr><th>roperty<\/th><th>Definition<\/th><th>GET<\/th><th>POST<\/th><th>PUT<\/th><th>PATCH<\/th><th>DELETE<\/th><th>HEAD<\/th><th>OPTIONS<\/th><\/tr><tr><th><strong>Safe<\/strong><\/th><td>Read-only; no state change requested by the client<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><\/tr><tr><th><strong>Idempotent<\/strong><\/th><td>Repeating N times ? doing it once (same state change)<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><\/tr><tr><th><strong>Cacheable<\/strong><\/th><td>Responses may be stored and reused by intermediaries<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">REST CRUD Operations<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p>Safe methods&nbsp;(GET, HEAD, OPTIONS, TRACE) are essentially read-only \u2014 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&nbsp;prefetch&nbsp;safe requests, web crawlers can follow safe links automatically, users can&nbsp;bookmark&nbsp;and re-request safe URLs, and caches can serve responses without forwarding to the origin server.<\/p>\n\n\n\n<p>Idempotent methods&nbsp;guarantee that executing the same request N times produces the&nbsp;same state change&nbsp;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 \u2014 DELETE and PUT change state but are idempotent.<\/p>\n\n\n\n<p>GET&nbsp;should be used exclusively for&nbsp;retrieving&nbsp;a representation of a resource. A successful GET returns&nbsp;200 OK&nbsp;with the resource in the body,&nbsp;204 No Content&nbsp;when a search returns no matches, or&nbsp;404 Not Found&nbsp;when the resource does not exist.<\/p>\n\n\n\n<p>POST&nbsp;should be used to&nbsp;create a new resource&nbsp;or to&nbsp;submit data for processing&nbsp;to an existing resource without necessarily creating anything new. The server assigns the URI for a newly created resource and returns it in the&nbsp;<code>Location<\/code>header with a&nbsp;201 Created&nbsp;status. Other valid POST responses include&nbsp;200 OK&nbsp;(processing done, no new resource),&nbsp;204 No Content,&nbsp;400 Bad Request, and&nbsp;405 Method Not Allowed. POST is&nbsp;neither safe nor idempotent&nbsp;\u2014 repeating a POST may create duplicate resources or repeat an action (e.g. charging a payment twice).<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Anti-pattern alert:&nbsp;Using GET for operations that modify state \u2014 such as&nbsp;<code>GET \/blog\/1234\/delete<\/code>&nbsp;\u2014 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.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">1.3 PUT, PATCH, and DELETE<\/h3>\n\n\n\n<p>PUT&nbsp;replaces or creates a resource at a client-specified URI. The client must supply a&nbsp;complete representation&nbsp;of the resource in the request body. PUT is&nbsp;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:&nbsp;200 OK,&nbsp;201 Created,&nbsp;204 No Content,&nbsp;409 Conflict.<\/p>\n\n\n\n<p>PATCH&nbsp;performs a&nbsp;partial update&nbsp;to an existing resource, sending only the changed fields. Two common formats are&nbsp;JSON merge patch&nbsp;(RFC 7396, media type&nbsp;<code>application\/merge-patch+json<\/code>) and&nbsp;JSON patch&nbsp;(RFC 6902, media type&nbsp;<code>application\/json-patch+json<\/code>), the latter specifying changes as a sequence of operations (add, remove, replace, copy, test). PATCH is&nbsp;not guaranteed idempotent. Valid responses:&nbsp;200 OK,&nbsp;400 Bad Request,&nbsp;409 Conflict,&nbsp;415 Unsupported Media Type.<\/p>\n\n\n\n<p>DELETE&nbsp;removes the resource at the specified URI and is&nbsp;idempotent: deleting the same resource twice yields the same end state (resource gone). Responses:&nbsp;204 No Content&nbsp;(success) or&nbsp;404 Not Found&nbsp;(resource already absent).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.4 Pagination, Filtering, Sorting, and Field Selection<\/h3>\n\n\n\n<p>For large collections, the Azure Architecture Center recommends implementing&nbsp;pagination&nbsp;using&nbsp;<code>limit<\/code>&nbsp;and&nbsp;<code>offset<\/code>&nbsp;query parameters with meaningful defaults such as&nbsp;<code>limit=25<\/code>&nbsp;and&nbsp;<code>offset=0<\/code>. Example:&nbsp;<code>GET \/orders?limit=25&amp;offset=50<\/code>.<\/p>\n\n\n\n<p>To help prevent&nbsp;denial-of-service attacks, impose an upper bound on the number of items returned. If a service sets&nbsp;<code>max-limit=25<\/code>&nbsp;and a client requests&nbsp;<code>limit=1000<\/code>, the service can either return 25 items or an HTTP Bad Request error, depending on documented policy.<\/p>\n\n\n\n<p>Filtering&nbsp;allows clients to refine results by applying conditions via query parameters:&nbsp;<code>GET \/orders?minCost=100&amp;status=shipped<\/code>.<\/p>\n\n\n\n<p>Sorting&nbsp;can be supported via a&nbsp;<code>sort<\/code>&nbsp;parameter (e.g.&nbsp;<code>sort=price<\/code>), with the caveat that different sort values alter the cache key and can negatively affect caching effectiveness.<\/p>\n\n\n\n<p>Field selection&nbsp;(client-defined projections) lets clients request only needed fields using a parameter like&nbsp;<code>fields=id,name<\/code>, 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.<\/p>\n\n\n\n<p>The Google Cloud blog additionally cautions against &#8220;chatty&#8221; APIs that force many sequential calls: consider providing coarser-grained &#8220;experience APIs&#8221; 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.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.5 Asynchronous Operations<\/h3>\n\n\n\n<p>When a POST, PUT, PATCH, or DELETE requires lengthy processing, return&nbsp;HTTP 202 (Accepted)&nbsp;with a&nbsp;<code>Location<\/code>header pointing to a status-polling endpoint. The status endpoint returns&nbsp;200 OK&nbsp;with current progress and, optionally, a cancel link. When the asynchronous operation creates a new resource, the status endpoint returns&nbsp;303 (See Other)&nbsp;with a&nbsp;<code>Location<\/code>&nbsp;header pointing to the new resource URI (e.g.&nbsp;<code>\/api\/orders\/12345<\/code>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.6 Content Negotiation and Partial Responses<\/h3>\n\n\n\n<p>Clients indicate acceptable response formats via the&nbsp;<code>Accept<\/code>&nbsp;header (e.g.&nbsp;<code>Accept: application\/json, application\/xml<\/code>). If the server cannot match any listed media type, it returns&nbsp;406 (Not Acceptable). When sending data, the&nbsp;<code>Content-Type<\/code>&nbsp;header specifies the format; if the server does not support it, it returns&nbsp;415 (Unsupported Media Type).<\/p>\n\n\n\n<p>For large binary resources (files, images), support&nbsp;partial retrieval&nbsp;via the&nbsp;<code>Accept-Ranges<\/code>&nbsp;header on GET responses and&nbsp;<code>Range<\/code>&nbsp;requests from clients. A&nbsp;HEAD&nbsp;request lets the client inspect the&nbsp;<code>Content-Length<\/code>&nbsp;and&nbsp;<code>Accept-Ranges<\/code>&nbsp;headers before deciding whether to fetch the resource in chunks.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.7 Common Design Anti-Patterns<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td>Anti-Pattern<\/td><td>Why It Fails<\/td><td>Correct Approach<\/td><\/tr><\/thead><tbody><tr><td>Verbs in URIs (<code>\/createUser<\/code>)<\/td><td>HTTP method already implies the action<\/td><td>Use nouns:&nbsp;<code>POST \/users<\/code>&nbsp;to create,&nbsp;<code>GET \/users<\/code>&nbsp;to list<\/td><\/tr><tr><td>GET with side effects (<code>GET \/blog\/1234\/delete<\/code>)<\/td><td>Violates safety; caches and crawlers may trigger it<\/td><td>Use&nbsp;<code>DELETE \/blogs\/1234<\/code><\/td><\/tr><tr><td>Tunneling everything through POST<\/td><td>Clients and caches cannot infer intent; no caching benefit<\/td><td>Use the semantically correct verb for each operation<\/td><\/tr><tr><td>Designing &#8220;inside-out&#8221; instead of &#8220;outside-in&#8221;<\/td><td>Exposes internal structure rather than consumer needs<\/td><td>Start from consumer use cases and work inward<\/td><\/tr><tr><td>Chatty APIs (many sequential calls)<\/td><td>Multiple network calls increase latency and operational cost<\/td><td>Offer experience APIs or batch endpoints<\/td><\/tr><tr><td>Missing pagination\/filtering<\/td><td>Overwhelming payloads; potential DoS vector<\/td><td>Implement&nbsp;<code>limit<\/code>\/<code>offset<\/code>&nbsp;with enforced upper bounds<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.8 HATEOAS and Hypermedia<\/h3>\n\n\n\n<p>REST APIs can be driven by&nbsp;hypermedia links&nbsp;embedded in resource representations, a principle known as&nbsp;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.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. API Security Architecture<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">2.1 Transport Security \u2014 HTTPS Is Non-Negotiable<\/h3>\n\n\n\n<p>Secure REST services&nbsp;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&nbsp;mutually authenticated client-side certificates&nbsp;(mutual TLS) to provide additional protection.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.2 Authentication vs Authorization<\/h3>\n\n\n\n<p>Authentication (AuthN)&nbsp;is the process of proving that a caller is who they claim to be. The Microsoft identity platform uses the&nbsp;OpenID Connect&nbsp;protocol for handling authentication.<\/p>\n\n\n\n<p>Authorization (AuthZ)&nbsp;is the act of granting an authenticated party permission to perform specific actions or access specific data. The Microsoft identity platform uses the&nbsp;OAuth 2.0&nbsp;protocol for handling authorization.<\/p>\n\n\n\n<p>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&nbsp;access control at each API endpoint; user authentication should be centralized in an Identity Provider (IdP) that issues access tokens.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.3 Token-Based Security \u2014 JWTs, Access Tokens, and Refresh Tokens<\/h3>\n\n\n\n<p>There is a convergence toward using&nbsp;JSON Web Tokens (JWT)&nbsp;as the format for security tokens in REST APIs. JWTs are JSON data structures containing a set of&nbsp;claims&nbsp;that can be used for access control decisions. A cryptographic signature or message authentication code (MAC) protects integrity.<\/p>\n\n\n\n<p>The Microsoft identity platform defines three primary token types:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td>Token Type<\/td><td>Purpose<\/td><td>Issued Via<\/td><\/tr><\/thead><tbody><tr><td>Access token<\/td><td>Grants access to a protected resource; contains user\/resource info<\/td><td>OAuth 2.0 flow<\/td><\/tr><tr><td>Refresh token<\/td><td>Exchanged for a new access token when the current one expires<\/td><td>Issued alongside access token (short-lived access tokens paired with longer-lived refresh tokens)<\/td><\/tr><tr><td>ID token<\/td><td>Authenticates the user; conveys identity claims<\/td><td>OpenID Connect flow<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Access tokens are passed as the&nbsp;bearer token&nbsp;in the&nbsp;<code>Authorization<\/code>&nbsp;header. The resource server validates the token by verifying the signature using the authorization server&#8217;s published public key.<\/p>\n\n\n\n<p>Critical JWT validation rules&nbsp;from the OWASP REST Security Cheat Sheet:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Never allow unsecured JWTs&nbsp;(<code>{\"alg\":\"none\"}<\/code>).<\/li>\n\n\n\n<li>Prefer signatures over MACs&nbsp;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.<\/li>\n\n\n\n<li>The relying party must verify integrity based on&nbsp;its own configuration, not the JWT header&#8217;s algorithm claim, to prevent algorithm-substitution attacks.<\/li>\n\n\n\n<li>At minimum, validate the following&nbsp;standard claims:&nbsp;<code>iss<\/code>&nbsp;(issuer \u2014 is this a trusted issuer?),&nbsp;<code>aud<\/code>&nbsp;(audience \u2014 is this token intended for this service?),&nbsp;<code>exp<\/code>&nbsp;(expiration time \u2014 has the token expired?), and&nbsp;<code>nbf<\/code>&nbsp;(not-before time \u2014 is the token valid yet?).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2.4 Scopes and Claims for Least Privilege<\/h3>\n\n\n\n<p>Claims&nbsp;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&#8217;s tenant, display user information, and determine authorization.<\/p>\n\n\n\n<p>Scopes&nbsp;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&nbsp;25 scopes&nbsp;per access token request.<\/p>\n\n\n\n<p>Design your token issuance to grant&nbsp;only the minimum scopes and claims necessary&nbsp;for the client&#8217;s function \u2014 this is the principle of least privilege, aligned with the Zero Trust tenet of &#8220;use least privilege access&#8221;.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.5 API Keys \u2014 Supplementary, Not Sole Protection<\/h3>\n\n\n\n<p>Public REST services without access control risk excessive bandwidth or compute costs.&nbsp;API keys&nbsp;can mitigate this risk and are often used to monetize APIs via purchased access plans. However:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Require API keys for&nbsp;every request&nbsp;to protected endpoints.<\/li>\n\n\n\n<li>Return&nbsp;429 Too Many Requests&nbsp;if requests arrive too quickly.<\/li>\n\n\n\n<li>Revoke&nbsp;the API key if the client violates the usage agreement.<\/li>\n\n\n\n<li>Do not rely exclusively on API keys&nbsp;to protect sensitive, critical, or high-value resources \u2014 they are relatively easy to compromise when issued to third-party clients.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2.6 OWASP API Security Top 10 (2023 Edition)<\/h3>\n\n\n\n<p>The following table captures the ten most critical API security risks identified by OWASP in 2023:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td>#<\/td><td>Risk<\/td><td>Description<\/td><\/tr><\/thead><tbody><tr><td>API1<\/td><td>Broken Object Level Authorization<\/td><td>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<\/td><\/tr><tr><td>API2<\/td><td>Broken Authentication<\/td><td>Incorrectly implemented auth mechanisms allow attackers to compromise tokens or assume other users&#8217; identities, compromising API security overall<\/td><\/tr><tr><td>API3<\/td><td>Broken Object Property Level Authorization<\/td><td>Combines excessive data exposure and mass assignment \u2014 improper validation at the object&nbsp;<em>property<\/em>&nbsp;level leads to information exposure or manipulation<\/td><\/tr><tr><td>API4<\/td><td>Unrestricted Resource Consumption<\/td><td>API requests consume network bandwidth, CPU, memory, and storage; successful attacks cause denial of service or cost escalation<\/td><\/tr><tr><td>API5<\/td><td>Broken Function Level Authorization<\/td><td>Complex access policies with unclear separation between admin and regular functions lead to authorization flaws, allowing access to others&#8217; resources or admin functions<\/td><\/tr><tr><td>API6<\/td><td>Unrestricted Access to Sensitive Business Flows<\/td><td>Business flows (buying a ticket, posting a comment) exposed without compensating for automated excessive use<\/td><\/tr><tr><td>API7<\/td><td>Server-Side Request Forgery (SSRF)<\/td><td>API fetches a remote resource without validating the user-supplied URI, enabling crafted requests to unexpected destinations even behind firewalls<\/td><\/tr><tr><td>API8<\/td><td>Security Misconfiguration<\/td><td>Complex configurations are missed or don&#8217;t follow security best practices, opening the door for attacks<\/td><\/tr><tr><td>API9<\/td><td>Improper Inventory Management<\/td><td>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<\/td><\/tr><tr><td>API10<\/td><td>Unsafe Consumption of APIs<\/td><td>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<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">2.7 Zero Trust Considerations for APIs<\/h3>\n\n\n\n<p>The&nbsp;Zero Trust&nbsp;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&#8217;s developer guidance distills this into three guiding principles:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Verify explicitly&nbsp;\u2014 authenticate and authorize based on all available data points on every request.<\/li>\n\n\n\n<li>Use least privilege access&nbsp;\u2014 limit user and service access with just-in-time and just-enough-access policies.<\/li>\n\n\n\n<li>Assume breach&nbsp;\u2014 minimize blast radius by segmenting access, verifying end-to-end encryption, and using analytics to detect and respond to threats.<\/li>\n<\/ol>\n\n\n\n<p>For API developers, this means:&nbsp;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 \u2014 &#8220;never trust, always verify&#8221;. 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.<\/p>\n\n\n\n<p>Microsoft&#8217;s guidance recommends using&nbsp;Zero Trust identity and access management best practices&nbsp;throughout the application development lifecycle, protecting APIs through registration, defining permissions and consent, and enforcing access to achieve Zero Trust goals.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. OAuth 2.0 \/ OpenID Connect vs SAML 2.0<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">3.1 OAuth 2.0 \u2014 Delegated Authorization<\/h3>\n\n\n\n<p>OAuth 2.0&nbsp;is a protocol that allows applications to access and share user data securely&nbsp;without sharing passwords. It provides a secure and standardized way for users to allow applications access to their resources, facilitated by different grant flows.<\/p>\n\n\n\n<p>Key architectural roles:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Resource Owner&nbsp;\u2014 the user who owns the data.<\/li>\n\n\n\n<li>Client&nbsp;\u2014 the application requesting access.<\/li>\n\n\n\n<li>Authorization Server&nbsp;\u2014 the identity provider that authenticates the user and issues tokens.<\/li>\n\n\n\n<li>Resource Server&nbsp;\u2014 the API that validates tokens and serves protected resources.<\/li>\n<\/ul>\n\n\n\n<p>Standardized grant flows&nbsp;supported by modern identity services (per AWS IAM Identity Center):<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td>Grant Flow<\/td><td>RFC<\/td><td>Use Case<\/td><\/tr><\/thead><tbody><tr><td>Authorization Code Grant with PKCE<\/td><td>RFC 6749 + RFC 7636<\/td><td>Web and mobile apps running on devices with a browser<\/td><\/tr><tr><td>Device Authorization Grant<\/td><td>RFC 8628<\/td><td>Devices with or without a browser (e.g. CLI tools, IoT)<\/td><\/tr><tr><td>Client Credentials<\/td><td>RFC 6749<\/td><td>Machine-to-machine (M2M) \/ server-to-server, no human user involved<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The Microsoft identity platform lists six supported authorization flows, each producing different token combinations:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td>Flow<\/td><td>ID Token<\/td><td>Access Token<\/td><td>Refresh Token<\/td><td>Authorization Code<\/td><\/tr><\/thead><tbody><tr><td>Authorization code flow<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>?<\/td><\/tr><tr><td>Implicit flow<\/td><td>?<\/td><td>?<\/td><td>\u2014<\/td><td>\u2014<\/td><\/tr><tr><td>Hybrid OIDC flow<\/td><td>?<\/td><td>\u2014<\/td><td>\u2014<\/td><td>?<\/td><\/tr><tr><td>Refresh token redemption<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>\u2014<\/td><\/tr><tr><td>On-behalf-of flow<\/td><td>?<\/td><td>?<\/td><td>?<\/td><td>\u2014<\/td><\/tr><tr><td>Client credentials<\/td><td>\u2014<\/td><td>?(App only)<\/td><td>\u2014<\/td><td>\u2014<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><em>Source:<\/em> <a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity-platform\/security-tokens\">[learn.microsoft.com]<\/a><\/p>\n\n\n\n<p>The Authorization Code flow with PKCE proceeds as follows: a browser opens, the user authenticates (if not already), a consent screen displays the&nbsp;application name&nbsp;and the&nbsp;access scopes&nbsp;being requested, and after consent is granted the application proceeds with access based on the user&#8217;s permissions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3.2 OpenID Connect (OIDC) \u2014 Authentication Layer over OAuth<\/h3>\n\n\n\n<p>OIDC&nbsp;is an authentication protocol built on top of the OAuth 2.0 framework. While OAuth alone provides&nbsp;<em>authorization<\/em>(granting token-based access to APIs), OIDC adds&nbsp;<em>authentication<\/em>&nbsp;\u2014 confirming the user&#8217;s identity \u2014 by introducing the&nbsp;ID token, a JWT containing identity claims (subject, name, email, etc.).<\/p>\n\n\n\n<p>The Microsoft identity platform clarifies the relationship: &#8220;The platform uses&nbsp;OAuth for authorization&nbsp;and&nbsp;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&#8221;.<\/p>\n\n\n\n<p>OIDC is commonly used for&nbsp;apps that are purely in the cloud, such as mobile apps, websites, and web APIs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3.3 SAML 2.0 \u2014 XML-Based Enterprise SSO<\/h3>\n\n\n\n<p>SAML 2.0&nbsp;is an industry standard used for securely exchanging&nbsp;SAML assertions&nbsp;that pass information about a user between a SAML authority (called an&nbsp;Identity Provider&nbsp;or IdP) and a SAML consumer (called a&nbsp;Service Provider&nbsp;or SP). This information is used to provide&nbsp;federated single sign-on access&nbsp;for authorized users.<\/p>\n\n\n\n<p>SAML operates via browser redirects and&nbsp;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&#8217;s browser. The SP validates the assertion and establishes a session.<\/p>\n\n\n\n<p>Enterprise applications that use SAML authentication are commonly integrated with identity providers such as&nbsp;Active Directory Federation Services (AD FS)&nbsp;federated to&nbsp;Microsoft Entra ID. Many enterprise apps also use SAML assertions, as referenced by the Microsoft Tokens and Claims documentation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3.4 Comparative Analysis \u2014 When to Use Which<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td>Dimension<\/td><td>OAuth 2.0 \/ OIDC<\/td><td>SAML 2.0<\/td><\/tr><\/thead><tbody><tr><td>Primary purpose<\/td><td>OAuth: authorization; OIDC: authentication + authorization<\/td><td>Authentication and SSO<\/td><\/tr><tr><td>Token\/assertion format<\/td><td>JSON (JWT) \u2014 compact, web-friendly<\/td><td>XML \u2014 verbose, requires signature validation<\/td><\/tr><tr><td>Transport<\/td><td>HTTP\/REST, JSON payloads<\/td><td>Browser POST of XML assertions<\/td><\/tr><tr><td>Client types<\/td><td>Mobile, SPA, web, server, IoT, CLI<\/td><td>Browser-based web applications primarily<\/td><\/tr><tr><td>Enterprise SSO<\/td><td>Supported (especially OIDC); preferred for cloud-native apps<\/td><td>Widely deployed; commonly used with ADFS + Microsoft Entra ID<\/td><\/tr><tr><td>API authorization<\/td><td>Native capability (access tokens with scopes)<\/td><td>Not designed for API authorization; requires translation layer<\/td><\/tr><tr><td>Token validation<\/td><td>Fast local validation via JWT signature + public key<\/td><td>Requires XML signature validation and certificate trust chain<\/td><\/tr><tr><td>Specification lineage<\/td><td>IETF RFC 6749 (OAuth 2.0), OpenID Foundation (OIDC)<\/td><td>OASIS standard (2005)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>When to prefer OAuth 2.0 \/ OIDC:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Any new REST API \u2014 user-facing or M2M.<\/li>\n\n\n\n<li>Mobile or single-page applications where lightweight JSON tokens and HTTP-based flows are essential.<\/li>\n\n\n\n<li>Scenarios requiring fine-grained API access control through&nbsp;scopes&nbsp;and&nbsp;claims.<\/li>\n\n\n\n<li>Multi-platform environments (Azure, AWS, GCP all standardize on OAuth2\/OIDC).<\/li>\n<\/ul>\n\n\n\n<p>When SAML remains relevant:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Legacy enterprise applications that only support SAML-based SSO.<\/li>\n\n\n\n<li>B2B federation with partners whose identity infrastructure is SAML-based.<\/li>\n\n\n\n<li>Environments where AD FS is the primary federation service and OIDC migration is not yet complete.<\/li>\n<\/ul>\n\n\n\n<p>Tradeoff:&nbsp;SAML&#8217;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 \u2014 which is why the industry has converged on it for modern API architectures.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3.5 Hybrid Environments<\/h3>\n\n\n\n<p>In practice, organizations frequently combine both protocols. The Microsoft identity platform explicitly supports this: &#8220;The platform uses&nbsp;OAuth 2.0 for authorization and SAML for authentication&#8221; and documents a&nbsp;SAML bearer assertion flow&nbsp;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 \u2014 bridging legacy SSO infrastructure with modern API security.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3.6 Implementation Guidance<\/h3>\n\n\n\n<p>For OAuth 2.0 \/ OIDC:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use the&nbsp;Authorization Code Grant with PKCE&nbsp;for public clients (mobile, SPA); the implicit flow is deprecated in favor of this approach.<\/li>\n\n\n\n<li>Use&nbsp;Client Credentials&nbsp;for M2M communication where no user is present.<\/li>\n\n\n\n<li>Validate tokens rigorously: check&nbsp;<code>iss<\/code>,&nbsp;<code>aud<\/code>,&nbsp;<code>exp<\/code>,&nbsp;<code>nbf<\/code>&nbsp;claims; verify the cryptographic signature using the authorization server&#8217;s public key; never rely on the JWT header&#8217;s&nbsp;<code>alg<\/code>&nbsp;claim to select the verification algorithm.<\/li>\n\n\n\n<li>Each Microsoft Entra tenant publishes a&nbsp;standards-compliant well-known metadata&nbsp;document containing information about the issuer name, authentication and authorization endpoints, supported scopes, and claims.<\/li>\n\n\n\n<li>Use established libraries such as the&nbsp;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.<\/li>\n<\/ul>\n\n\n\n<p>For SAML 2.0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rely on vetted SAML libraries for XML parsing, signature validation, and assertion handling \u2014 avoid custom implementations.<\/li>\n\n\n\n<li>Note that&nbsp;AWS IAM Identity Center does not support validating signatures of incoming SAML authentication requests&nbsp;from SAML applications; the assertion from the IdP is validated, but the SP-initiated AuthN request signature is not checked at the AWS end.<\/li>\n\n\n\n<li>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.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Key Authoritative References<\/h2>\n\n\n\n<p>All guidance in this report is grounded in the following official and standards-body sources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure Architecture Center&nbsp;\u2014&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/architecture\/best-practices\/api-design\">Best practices for RESTful web API design<\/a><\/li>\n\n\n\n<li>Google Cloud&nbsp;\u2014&nbsp;<a href=\"https:\/\/docs.cloud.google.com\/apis\/design\">API design guide<\/a>&nbsp;(used inside Google since 2014);&nbsp;<a href=\"https:\/\/cloud.google.com\/blog\/products\/api-management\/restful-web-api-design-best-practices\">6 common mistakes in RESTful API design<\/a><\/li>\n\n\n\n<li>Google AIP-130&nbsp;\u2014&nbsp;<a href=\"https:\/\/google.aip.dev\/130\">Standard methods and method categories<\/a><\/li>\n\n\n\n<li>IETF&nbsp;\u2014 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)<\/li>\n\n\n\n<li>OWASP&nbsp;\u2014&nbsp;<a href=\"https:\/\/owasp.org\/API-Security\/editions\/2023\/en\/0x11-t10\/\">API Security Top 10 (2023)<\/a>;&nbsp;<a href=\"https:\/\/cheatsheetseries.owasp.org\/cheatsheets\/REST_Security_Cheat_Sheet.html\">REST Security Cheat Sheet<\/a><\/li>\n\n\n\n<li>Microsoft Identity Platform&nbsp;\u2014&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity-platform\/authentication-vs-authorization\">Authentication vs. authorization<\/a>;&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity-platform\/security-tokens\">Tokens and claims overview<\/a><\/li>\n\n\n\n<li>Microsoft Zero Trust&nbsp;\u2014&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/security\/zero-trust\/develop\/overview\">Develop using Zero Trust principles<\/a><\/li>\n\n\n\n<li>AWS&nbsp;\u2014&nbsp;<a href=\"https:\/\/docs.aws.amazon.com\/singlesignon\/latest\/userguide\/customermanagedapps-saml2-oauth2.html\">Single sign-on access to SAML 2.0 and OAuth 2.0 applications<\/a>;&nbsp;<a href=\"https:\/\/docs.aws.amazon.com\/whitepapers\/latest\/best-practices-api-gateway-private-apis-integration\/rest-api.html\">Best practices for API Gateway private APIs<\/a><\/li>\n\n\n\n<li>NIST&nbsp;\u2014 SP 800-207, Zero Trust Architecture (August 2020)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n<div class=\"twttr_buttons\"><div class=\"twttr_twitter\">\n\t\t\t\t\t<a href=\"http:\/\/twitter.com\/share?text=REST+API+Design+and+Security%3A+Architecture-Level+Best+Practices+and+Standards\" class=\"twitter-share-button\" data-via=\"\" data-hashtags=\"\"  data-size=\"default\" data-url=\"https:\/\/shirishranjit.com\/blog1\/architect-principles\/rest-api-design-and-security-architecture-level-best-practices-and-standards\"  data-related=\"\" target=\"_blank\">Tweet<\/a>\n\t\t\t\t<\/div><div class=\"twttr_followme\">\n\t\t\t\t\t\t<a href=\"https:\/\/twitter.com\/shiranjit\" class=\"twitter-follow-button\" data-size=\"default\"  data-show-screen-name=\"false\"  target=\"_blank\">Follow me<\/a>\n\t\t\t\t\t<\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>REST API Design and Security: Architecture-Level Best Practices and Standards Designing a robust, platform-neutral REST API requires mastery of two interlocking disciplines:&nbsp;standards-based HTTP semantics&nbsp;(when, why, and where to use each HTTP method) and a&nbsp;comprehensive security architecture&nbsp;covering both user-facing and machine-to-machine &hellip; <a href=\"https:\/\/shirishranjit.com\/blog1\/architect-principles\/rest-api-design-and-security-architecture-level-best-practices-and-standards\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"parent":2688,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2761","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/shirishranjit.com\/blog1\/wp-json\/wp\/v2\/pages\/2761"}],"collection":[{"href":"https:\/\/shirishranjit.com\/blog1\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/shirishranjit.com\/blog1\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/shirishranjit.com\/blog1\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/shirishranjit.com\/blog1\/wp-json\/wp\/v2\/comments?post=2761"}],"version-history":[{"count":4,"href":"https:\/\/shirishranjit.com\/blog1\/wp-json\/wp\/v2\/pages\/2761\/revisions"}],"predecessor-version":[{"id":2768,"href":"https:\/\/shirishranjit.com\/blog1\/wp-json\/wp\/v2\/pages\/2761\/revisions\/2768"}],"up":[{"embeddable":true,"href":"https:\/\/shirishranjit.com\/blog1\/wp-json\/wp\/v2\/pages\/2688"}],"wp:attachment":[{"href":"https:\/\/shirishranjit.com\/blog1\/wp-json\/wp\/v2\/media?parent=2761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}