<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Identity &amp; Auth · Brennenstuhl on Security</title><link>https://www.janbrennenstuhl.eu/topics/identity-authentication/</link><description>OpenID Connect, OAuth, passkeys and step-up: who is acting, on whose behalf, and how strongly that was proven.</description><language>en-GB</language><copyright>Original writing CC BY 4.0, Jan Brennenstuhl</copyright><atom:link href="https://www.janbrennenstuhl.eu/topics/identity-authentication/index.xml" rel="self" type="application/rss+xml"/><item><title>How does authorization work for MCP servers?</title><link>https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/</guid><pubDate>Tue, 13 Oct 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; In the MCP authorization specification (revision 2026-07-28), a protected MCP server over HTTP is an OAuth 2.1 resource server: it publishes Protected Resource Metadata that points clients to its authorization server and accepts only tokens issued for itself. MCP clients discover that authorization server, run the authorization code flow with PKCE, and name the MCP server in a resource parameter on every authorization and token request.&lt;/p&gt;&lt;p&gt;This entry describes the Model Context Protocol (MCP) &lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization" class="ext"&gt;authorization specification&lt;/a&gt; as of revision 2026-07-28, which the MCP versioning page listed as the current revision on 13 October 2026. Later revisions may change these requirements.&lt;/p&gt;
&lt;h2 id="key-findings"&gt;Key findings &lt;a class="heading-anchor" href="#key-findings" aria-label="Link to section: Key findings"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class="finding" id="f-agent-mcp-protected-resource-metadata"&gt;
&lt;blockquote&gt;&lt;p&gt;As of MCP revision 2026-07-28, MCP servers must implement OAuth 2.0 Protected Resource Metadata (RFC 9728), and MCP clients must use it to discover the authorization server.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization" class="ext"&gt;&lt;cite&gt;Model Context Protocol, Authorization, revision 2026-07-28&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-mcp-protected-resource-metadata" title="#f-agent-mcp-protected-resource-metadata"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="As of MCP revision 2026-07-28, MCP servers must implement OAuth 2.0 Protected Resource Metadata (RFC 9728), and MCP clients must use it to discover the authorization server." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/#f-agent-mcp-protected-resource-metadata" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/f-agent-mcp-protected-resource-metadata.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-mcp-resource-parameter"&gt;
&lt;blockquote&gt;&lt;p&gt;MCP clients must send the RFC 8707 resource parameter with the MCP server&amp;rsquo;s canonical URI in both authorization and token requests, whether or not the authorization server supports it.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization" class="ext"&gt;&lt;cite&gt;Model Context Protocol, Authorization, revision 2026-07-28&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-mcp-resource-parameter" title="#f-agent-mcp-resource-parameter"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="MCP clients must send the RFC 8707 resource parameter with the MCP server&amp;rsquo;s canonical URI in both authorization and token requests, whether or not the authorization server supports it." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/#f-agent-mcp-resource-parameter" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/f-agent-mcp-resource-parameter.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-mcp-audience-validation"&gt;
&lt;blockquote&gt;&lt;p&gt;MCP servers must validate that an access token was issued specifically for them as the intended audience and must not accept or transit any other tokens.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization" class="ext"&gt;&lt;cite&gt;Model Context Protocol, Authorization, revision 2026-07-28&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-mcp-audience-validation" title="#f-agent-mcp-audience-validation"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="MCP servers must validate that an access token was issued specifically for them as the intended audience and must not accept or transit any other tokens." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/#f-agent-mcp-audience-validation" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/f-agent-mcp-audience-validation.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-mcp-no-token-passthrough"&gt;
&lt;blockquote&gt;&lt;p&gt;An MCP server that calls upstream APIs must use a separate token from the upstream authorization server and must not pass through the token it received from the MCP client.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization/security-considerations" class="ext"&gt;&lt;cite&gt;Model Context Protocol, Authorization Security Considerations, revision 2026-07-28&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-mcp-no-token-passthrough" title="#f-agent-mcp-no-token-passthrough"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="An MCP server that calls upstream APIs must use a separate token from the upstream authorization server and must not pass through the token it received from the MCP client." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/#f-agent-mcp-no-token-passthrough" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/f-agent-mcp-no-token-passthrough.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="evidence"&gt;Evidence &lt;a class="heading-anchor" href="#evidence" aria-label="Link to section: Evidence"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="table-scroll studies" tabindex="0" role="region" aria-label="Primary sources on MCP authorization"&gt;&lt;table&gt;
&lt;caption&gt;Primary sources on MCP authorization&lt;/caption&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th scope="col"&gt;Study&lt;/th&gt;&lt;th scope="col"&gt;Year&lt;/th&gt;&lt;th scope="col"&gt;Sample&lt;/th&gt;&lt;th scope="col"&gt;Method&lt;/th&gt;&lt;th scope="col"&gt;Finding&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization" class="ext"&gt;Model Context Protocol: Authorization (revision 2026-07-28)&lt;/a&gt;&lt;span class="org"&gt;Model Context Protocol&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Defines roles, discovery, the authorization flow, the resource parameter, token handling and step-up authorization for HTTP transports.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization/security-considerations" class="ext"&gt;Model Context Protocol: Authorization Security Considerations (revision 2026-07-28)&lt;/a&gt;&lt;span class="org"&gt;Model Context Protocol&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Requires audience binding, PKCE, exact redirect URI matching and a ban on token passthrough.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9728" class="ext"&gt;OAuth 2.0 Protected Resource Metadata (RFC 9728)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2025&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Defines the metadata document and the WWW-Authenticate parameter that point a client to a resource&amp;rsquo;s authorization servers.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc8707" class="ext"&gt;Resource Indicators for OAuth 2.0 (RFC 8707)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2020&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Defines the resource parameter and asks authorization servers to audience-restrict tokens to it.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.janbrennenstuhl.eu/talks/economies-of-scale-for-mcp/" class="ext"&gt;Economies of Scale for MCP and Agents&lt;/a&gt;&lt;span class="org"&gt;this site&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Talk&lt;/td&gt;&lt;td&gt;States that an agent should not hold a shared, long-lived provider credential and presents the broker&amp;rsquo;s delegation model.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id="what-to-do"&gt;What to do &lt;a class="heading-anchor" href="#what-to-do" aria-label="Link to section: What to do"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="for-engineers"&gt;For engineers &lt;a class="heading-anchor" href="#for-engineers" aria-label="Link to section: For engineers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For an MCP server over HTTP, publish Protected Resource Metadata, answer unauthenticated requests with a 401 that points to it, and check the audience of every token. Put the scopes an operation needs in the &lt;code&gt;WWW-Authenticate&lt;/code&gt; challenge, all at once. If the server calls other APIs, get its own token for each of them. The &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/"&gt;token exchange entry&lt;/a&gt; shows one way to do that.&lt;/p&gt;
&lt;p&gt;For an MCP client, implement both discovery mechanisms, PKCE with &lt;code&gt;S256&lt;/code&gt;, the &lt;code&gt;resource&lt;/code&gt; parameter, and the issuer check. Never put tokens in the query string.&lt;/p&gt;
&lt;p&gt;An MCP server on the STDIO transport is outside this specification, which says such servers should take credentials from the environment. Keep those credentials short-lived and task-scoped, as my &lt;a href="https://www.janbrennenstuhl.eu/appsec-agentic-engineering/"&gt;AppSec essay&lt;/a&gt; recommends for coding agents.&lt;/p&gt;
&lt;h3 id="for-product-and-ux"&gt;For product and UX &lt;a class="heading-anchor" href="#for-product-and-ux" aria-label="Link to section: For product and UX"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Start with the minimal scopes and ask for more only when an operation needs them. The specification warns that misconfigured scopes may require frequent user interaction, and that challenging one scope at a time forces several authorization round-trips for one operation.&lt;/p&gt;
&lt;h2 id="how-it-works"&gt;How it works &lt;a class="heading-anchor" href="#how-it-works" aria-label="Link to section: How it works"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The specification defines 3 roles. The MCP server is an OAuth 2.1 resource server, the MCP client is an OAuth 2.1 client acting for a resource owner, and the authorization server issues the tokens. Authorization is optional for MCP implementations. Implementations on HTTP-based transports should conform to the specification, and STDIO implementations should not.&lt;/p&gt;
&lt;p&gt;A first connection follows these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The client sends an MCP request without a token. The server answers with HTTP 401 and a &lt;code&gt;WWW-Authenticate&lt;/code&gt; header that carries the &lt;code&gt;resource_metadata&lt;/code&gt; URL from RFC 9728 and, as the specification recommends, the required &lt;code&gt;scope&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The client fetches the Protected Resource Metadata and picks an authorization server from it. It then reads that server&amp;rsquo;s metadata through OAuth 2.0 Authorization Server Metadata (RFC 8414) or OpenID Connect Discovery. Clients must support both, and if the metadata doesn&amp;rsquo;t list &lt;code&gt;code_challenge_methods_supported&lt;/code&gt;, the client must refuse to proceed.&lt;/li&gt;
&lt;li&gt;The client gets a client ID. It uses pre-registered client information if it has some, then Client ID Metadata Documents if the authorization server supports them. Dynamic Client Registration is deprecated and kept only as a fallback for backwards compatibility.&lt;/li&gt;
&lt;li&gt;The client starts the authorization code flow with PKCE, the &lt;code&gt;resource&lt;/code&gt; parameter and the selected scopes, and records the expected issuer. When the response comes back, it validates the &lt;code&gt;iss&lt;/code&gt; parameter (RFC 9207) before it redeems the code.&lt;/li&gt;
&lt;li&gt;The client redeems the code with the &lt;code&gt;code_verifier&lt;/code&gt; and the &lt;code&gt;resource&lt;/code&gt; parameter, then sends the access token in the &lt;code&gt;Authorization: Bearer&lt;/code&gt; header on every request.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When a token lacks a scope at runtime, the server answers with 403 and &lt;code&gt;error=&amp;quot;insufficient_scope&amp;quot;&lt;/code&gt;. The client then runs a step-up flow with the union of its previous scopes and the new ones.&lt;/p&gt;
&lt;p&gt;Revision 2026-07-28 doesn&amp;rsquo;t cover token exchange in its core authorization pages. Optional authorization extensions live in a separate repository. In the Agentic Identity Broker, which Magnus Jungsbluth and I built, an MCP gateway exchanges the agent&amp;rsquo;s token for the matching provider token through RFC 8693, so the provider token never reaches the agent. I describe that design in the &lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/"&gt;retrospective&lt;/a&gt;, and we presented it in our &lt;a href="https://www.janbrennenstuhl.eu/talks/economies-of-scale-for-mcp/"&gt;AGNTCon + MCPCon talk&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="related"&gt;Related &lt;a class="heading-anchor" href="#related" aria-label="Link to section: Related"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/"&gt;Should an agent use a robot account or delegated access?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/"&gt;How should people grant and revoke an agent&amp;rsquo;s access?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/projects/agentic-identity-broker/"&gt;Agentic Identity Broker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>How should people grant and revoke an agent's access?</title><link>https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/</guid><pubDate>Tue, 13 Oct 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; Let people grant each agent access per service, with a permission set they choose and an expiry, and let them revoke that grant at any time. Revoking the grant has to stop every token derived from it, so keep issued tokens short-lived and check the grant whenever a new token is issued.&lt;/p&gt;&lt;h2 id="key-findings"&gt;Key findings &lt;a class="heading-anchor" href="#key-findings" aria-label="Link to section: Key findings"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class="finding" id="f-agent-grant-scope-expiry-revoke"&gt;
&lt;blockquote&gt;&lt;p&gt;In the Agentic Identity Broker, a user grants an agent access to a service with a chosen permission set and an optional expiry, and can revoke that grant at any time.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/" class="ext"&gt;&lt;cite&gt;What I Learned Building an Identity Broker With Coding Agents (janbrennenstuhl.eu, 2026)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-grant-scope-expiry-revoke" title="#f-agent-grant-scope-expiry-revoke"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="In the Agentic Identity Broker, a user grants an agent access to a service with a chosen permission set and an optional expiry, and can revoke that grant at any time." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/#f-agent-grant-scope-expiry-revoke" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/f-agent-grant-scope-expiry-revoke.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-revocation-cascades-to-grant"&gt;
&lt;blockquote&gt;&lt;p&gt;Under RFC 7009, revoking a refresh token should also invalidate all access tokens based on the same authorization grant if the authorization server supports access token revocation.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc7009#section-2.1" class="ext"&gt;&lt;cite&gt;RFC 7009, OAuth 2.0 Token Revocation (IETF, 2013), Section 2.1&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-revocation-cascades-to-grant" title="#f-agent-revocation-cascades-to-grant"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Under RFC 7009, revoking a refresh token should also invalidate all access tokens based on the same authorization grant if the authorization server supports access token revocation." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/#f-agent-revocation-cascades-to-grant" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/f-agent-revocation-cascades-to-grant.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-self-contained-token-revocation"&gt;
&lt;blockquote&gt;&lt;p&gt;Immediate revocation of self-contained access tokens needs backend coordination that RFC 7009 calls non-standardized, and short-lived access tokens limit how long a revoked token stays in use.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc7009#section-3" class="ext"&gt;&lt;cite&gt;RFC 7009, OAuth 2.0 Token Revocation (IETF, 2013), Section 3&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-self-contained-token-revocation" title="#f-agent-self-contained-token-revocation"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Immediate revocation of self-contained access tokens needs backend coordination that RFC 7009 calls non-standardized, and short-lived access tokens limit how long a revoked token stays in use." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/#f-agent-self-contained-token-revocation" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/f-agent-self-contained-token-revocation.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-refresh-token-bound-to-consent"&gt;
&lt;blockquote&gt;&lt;p&gt;Refresh tokens must be bound to the scope and resource servers the resource owner consented to.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc9700#section-4.14.2" class="ext"&gt;&lt;cite&gt;RFC 9700, Best Current Practice for OAuth 2.0 Security (IETF, 2025), Section 4.14.2&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-refresh-token-bound-to-consent" title="#f-agent-refresh-token-bound-to-consent"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Refresh tokens must be bound to the scope and resource servers the resource owner consented to." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/#f-agent-refresh-token-bound-to-consent" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/f-agent-refresh-token-bound-to-consent.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="evidence"&gt;Evidence &lt;a class="heading-anchor" href="#evidence" aria-label="Link to section: Evidence"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="table-scroll studies" tabindex="0" role="region" aria-label="Primary sources on agent consent and revocation"&gt;&lt;table&gt;
&lt;caption&gt;Primary sources on agent consent and revocation&lt;/caption&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th scope="col"&gt;Study&lt;/th&gt;&lt;th scope="col"&gt;Year&lt;/th&gt;&lt;th scope="col"&gt;Sample&lt;/th&gt;&lt;th scope="col"&gt;Method&lt;/th&gt;&lt;th scope="col"&gt;Finding&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc7009" class="ext"&gt;OAuth 2.0 Token Revocation (RFC 7009)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2013&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Defines a revocation endpoint and how revoking one token can revoke related tokens and the grant.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9700" class="ext"&gt;Best Current Practice for OAuth 2.0 Security (RFC 9700)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2025&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Binds refresh tokens to the consented scope and resources and lets them expire after inactivity.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc8707" class="ext"&gt;Resource Indicators for OAuth 2.0 (RFC 8707)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2020&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Lets the authorization server tell the user which resources a client will access on their behalf.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc8693" class="ext"&gt;OAuth 2.0 Token Exchange (RFC 8693)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2020&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Leaves revocation of tokens issued by an exchange to the implementation.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization" class="ext"&gt;Model Context Protocol: Authorization (revision 2026-07-28)&lt;/a&gt;&lt;span class="org"&gt;Model Context Protocol&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Asks clients to request minimal scopes first and add scopes through step-up authorization.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/" class="ext"&gt;What I Learned Building an Identity Broker With Coding Agents&lt;/a&gt;&lt;span class="org"&gt;this site&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Field report&lt;/td&gt;&lt;td&gt;Describes per-agent grants with chosen permissions, optional expiry and revocation at any time.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id="what-to-do"&gt;What to do &lt;a class="heading-anchor" href="#what-to-do" aria-label="Link to section: What to do"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="for-engineers"&gt;For engineers &lt;a class="heading-anchor" href="#for-engineers" aria-label="Link to section: For engineers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Model the grant as a record of its own that names the person, the agent, the service, the permissions and the expiry, and issue every token from it. Check that record whenever you issue or exchange a token, so a revocation takes effect at the next tool call. Expiring tokens are the fallback for tokens you can&amp;rsquo;t recall.&lt;/p&gt;
&lt;p&gt;Wire revocation through every layer you control. Call the &lt;a href="https://www.rfc-editor.org/rfc/rfc7009" class="ext"&gt;RFC 7009&lt;/a&gt; revocation endpoint where the provider offers one, and don&amp;rsquo;t stop at the first token. RFC 8693 says tokens issued by a &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/"&gt;token exchange&lt;/a&gt; aren&amp;rsquo;t linked to their input token, so revoking one doesn&amp;rsquo;t reach the other unless you build that.&lt;/p&gt;
&lt;p&gt;Ask for the least access first. The &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/"&gt;MCP authorization specification&lt;/a&gt; describes this as step-up authorization: request minimal scopes and add more when a server asks for them.&lt;/p&gt;
&lt;h3 id="for-product-and-ux"&gt;For product and UX &lt;a class="heading-anchor" href="#for-product-and-ux" aria-label="Link to section: For product and UX"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Show each grant with the agent, the service, the permissions and the expiry in plain words, and put the revoke action next to it. Default to an expiry instead of open-ended access. When an agent needs more access, ask at that moment for that specific permission.&lt;/p&gt;
&lt;h2 id="how-it-works"&gt;How it works &lt;a class="heading-anchor" href="#how-it-works" aria-label="Link to section: How it works"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Granting access in OAuth starts with an authorization request. The client names the access it wants in &lt;code&gt;scope&lt;/code&gt; and, with &lt;a href="https://www.rfc-editor.org/rfc/rfc8707#section-2.1" class="ext"&gt;RFC 8707&lt;/a&gt;, the resources in &lt;code&gt;resource&lt;/code&gt;. RFC 8707 notes that the authorization server can use those resource values to inform the user about the resources the client will access on their behalf. The consent screen can then name the service, not only a list of scopes.&lt;/p&gt;
&lt;p&gt;In the Agentic Identity Broker, which Magnus Jungsbluth and I built, a user grants an agent access to a service with a chosen permission set and an optional expiry. The broker keeps both the user and the agent in every authorization decision. I describe the design in the &lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/"&gt;retrospective&lt;/a&gt;, and my &lt;a href="https://www.janbrennenstuhl.eu/appsec-agentic-engineering/"&gt;AppSec essay&lt;/a&gt; argues for narrow, time-limited permissions that the user can revoke at any moment.&lt;/p&gt;
&lt;p&gt;Revoking access in OAuth uses the revocation endpoint from RFC 7009. A client sends the token it wants revoked, and the server invalidates it and, depending on policy, related tokens and the grant itself. RFC 7009 gives 2 reasons this matters for people: it stops a grant from staying valid without the user&amp;rsquo;s knowledge, and revoked grants disappear from any list of grants the authorization server shows the user. The server answers with HTTP 200 even for an invalid token. A 503 means the client must assume the token still exists.&lt;/p&gt;
&lt;p&gt;Self-contained tokens make revocation harder. A resource server can check a self-contained token, such as a JSON Web Token (JWT), without asking the authorization server, so it won&amp;rsquo;t learn about a revocation on its own. RFC 7009 names short-lived access tokens with refresh tokens as one alternative. RFC 9700 adds that refresh tokens must stay bound to the consented scope and resources, should expire after a period of inactivity, and may be revoked on security events such as a password change or logout.&lt;/p&gt;
&lt;h2 id="related"&gt;Related &lt;a class="heading-anchor" href="#related" aria-label="Link to section: Related"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/"&gt;Should an agent use a robot account or delegated access?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/"&gt;How does OAuth 2.0 Token Exchange keep provider tokens away from agents?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/talks/economies-of-scale-for-mcp/"&gt;Economies of Scale for MCP and Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/projects/agentic-identity-broker/"&gt;Agentic Identity Broker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>How does OAuth 2.0 Token Exchange keep provider tokens away from agents?</title><link>https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/</guid><pubDate>Tue, 13 Oct 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; OAuth 2.0 Token Exchange (RFC 8693) lets a client trade one token for another token meant for a specific target service. When a gateway runs that exchange on each tool call, as in the Agentic Identity Broker, the provider token stays between the broker, the gateway and the provider and never reaches the agent.&lt;/p&gt;&lt;h2 id="key-findings"&gt;Key findings &lt;a class="heading-anchor" href="#key-findings" aria-label="Link to section: Key findings"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class="finding" id="f-agent-rfc8693-security-token-service"&gt;
&lt;blockquote&gt;&lt;p&gt;RFC 8693 lets a client present a security token to an OAuth 2.0 authorization server acting as a Security Token Service and receive a new token, for example one scoped more narrowly for a downstream service.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc8693#section-1" class="ext"&gt;&lt;cite&gt;RFC 8693, OAuth 2.0 Token Exchange (IETF, 2020), Section 1&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-rfc8693-security-token-service" title="#f-agent-rfc8693-security-token-service"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="RFC 8693 lets a client present a security token to an OAuth 2.0 authorization server acting as a Security Token Service and receive a new token, for example one scoped more narrowly for a downstream service." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/#f-agent-rfc8693-security-token-service" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/f-agent-rfc8693-security-token-service.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-broker-provider-token-stays-out"&gt;
&lt;blockquote&gt;&lt;p&gt;In the Agentic Identity Broker, an MCP gateway exchanges the agent&amp;rsquo;s token for the matching provider token through RFC 8693 on each tool call, so the provider token never reaches the agent.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/" class="ext"&gt;&lt;cite&gt;What I Learned Building an Identity Broker With Coding Agents (janbrennenstuhl.eu, 2026)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-broker-provider-token-stays-out" title="#f-agent-broker-provider-token-stays-out"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="In the Agentic Identity Broker, an MCP gateway exchanges the agent&amp;rsquo;s token for the matching provider token through RFC 8693 on each tool call, so the provider token never reaches the agent." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/#f-agent-broker-provider-token-stays-out" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/f-agent-broker-provider-token-stays-out.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-exchange-client-authentication"&gt;
&lt;blockquote&gt;&lt;p&gt;RFC 8693 warns that without client authentication at the token endpoint, anyone holding a compromised token can trade it for other tokens.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc8693#section-2.1" class="ext"&gt;&lt;cite&gt;RFC 8693, OAuth 2.0 Token Exchange (IETF, 2020), Section 2.1&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-exchange-client-authentication" title="#f-agent-exchange-client-authentication"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="RFC 8693 warns that without client authentication at the token endpoint, anyone holding a compromised token can trade it for other tokens." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/#f-agent-exchange-client-authentication" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/f-agent-exchange-client-authentication.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-act-claim-current-actor"&gt;
&lt;blockquote&gt;&lt;p&gt;In a JWT issued through token exchange, access control decisions must consider only the top-level claims and the current actor named in the act claim, while nested prior actors are informational.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc8693#section-4.1" class="ext"&gt;&lt;cite&gt;RFC 8693, OAuth 2.0 Token Exchange (IETF, 2020), Section 4.1&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-act-claim-current-actor" title="#f-agent-act-claim-current-actor"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="In a JWT issued through token exchange, access control decisions must consider only the top-level claims and the current actor named in the act claim, while nested prior actors are informational." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/#f-agent-act-claim-current-actor" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/f-agent-act-claim-current-actor.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-exchange-no-revocation-link"&gt;
&lt;blockquote&gt;&lt;p&gt;A token exchange creates no tight link between the input and output tokens, so passing revocation from one to the other depends on the implementation and isn&amp;rsquo;t a property of the protocol.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc8693#section-2.1" class="ext"&gt;&lt;cite&gt;RFC 8693, OAuth 2.0 Token Exchange (IETF, 2020), Section 2.1&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-exchange-no-revocation-link" title="#f-agent-exchange-no-revocation-link"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="A token exchange creates no tight link between the input and output tokens, so passing revocation from one to the other depends on the implementation and isn&amp;rsquo;t a property of the protocol." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/#f-agent-exchange-no-revocation-link" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/f-agent-exchange-no-revocation-link.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="evidence"&gt;Evidence &lt;a class="heading-anchor" href="#evidence" aria-label="Link to section: Evidence"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="table-scroll studies" tabindex="0" role="region" aria-label="Primary sources on token exchange for agents"&gt;&lt;table&gt;
&lt;caption&gt;Primary sources on token exchange for agents&lt;/caption&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th scope="col"&gt;Study&lt;/th&gt;&lt;th scope="col"&gt;Year&lt;/th&gt;&lt;th scope="col"&gt;Sample&lt;/th&gt;&lt;th scope="col"&gt;Method&lt;/th&gt;&lt;th scope="col"&gt;Finding&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc8693" class="ext"&gt;OAuth 2.0 Token Exchange (RFC 8693)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2020&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Defines the token exchange grant, its request and response parameters, and the act and may_act claims.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc8707" class="ext"&gt;Resource Indicators for OAuth 2.0 (RFC 8707)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2020&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Defines the resource parameter that tells the authorization server where a token will be used.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/" class="ext"&gt;What I Learned Building an Identity Broker With Coding Agents&lt;/a&gt;&lt;span class="org"&gt;this site&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Field report&lt;/td&gt;&lt;td&gt;Describes how a gateway exchanges the agent&amp;rsquo;s token for the matching provider token on each tool call.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.janbrennenstuhl.eu/talks/economies-of-scale-for-mcp/" class="ext"&gt;Economies of Scale for MCP and Agents&lt;/a&gt;&lt;span class="org"&gt;this site&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Talk&lt;/td&gt;&lt;td&gt;Presents the broker&amp;rsquo;s delegation model at AGNTCon + MCPCon Europe 2026.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id="what-to-do"&gt;What to do &lt;a class="heading-anchor" href="#what-to-do" aria-label="Link to section: What to do"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="for-engineers"&gt;For engineers &lt;a class="heading-anchor" href="#for-engineers" aria-label="Link to section: For engineers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Put the exchange in a component the agent can&amp;rsquo;t control, such as a gateway, and authenticate that component at the token endpoint. Name the target with &lt;code&gt;resource&lt;/code&gt; or &lt;code&gt;audience&lt;/code&gt; and ask for the smallest &lt;code&gt;scope&lt;/code&gt; the tool call needs. RFC 8693 points out that broad requests across many target services are more likely to be refused.&lt;/p&gt;
&lt;p&gt;Treat revocation as your own job. The RFC leaves it to the implementation whether revoking a grant or an input token affects tokens already issued, so keep issued tokens short-lived and check the grant at exchange time. &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/"&gt;Consent and revocation&lt;/a&gt; covers the rest.&lt;/p&gt;
&lt;p&gt;If an agent&amp;rsquo;s token can travel further, use the &lt;code&gt;act&lt;/code&gt; claim to record the agent as the actor and the &lt;code&gt;may_act&lt;/code&gt; claim to state who may act for the subject.&lt;/p&gt;
&lt;h3 id="for-product-and-ux"&gt;For product and UX &lt;a class="heading-anchor" href="#for-product-and-ux" aria-label="Link to section: For product and UX"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Users don&amp;rsquo;t see the exchange, but they see its effects. When a tool call fails because a grant expired or was revoked, tell the user which service and which agent were affected and how to grant access again.&lt;/p&gt;
&lt;h2 id="how-it-works"&gt;How it works &lt;a class="heading-anchor" href="#how-it-works" aria-label="Link to section: How it works"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;RFC 8693 defines the exchange as 1 request and 1 response at an authorization server&amp;rsquo;s token endpoint. With a gateway between an agent and its tools, the exchange runs like this:&lt;/p&gt;
&lt;section class="explainer" data-explainer="delegation" aria-labelledby="ex-delegation"&gt;
&lt;h3 id="ex-delegation"&gt;Step through the exchange&lt;/h3&gt;
&lt;div class="explainer-static"&gt;&lt;ol&gt;
&lt;li&gt;The agent calls a tool through the gateway and presents its own token.&lt;/li&gt;
&lt;li&gt;The gateway acts as the RFC 8693 client. It sends a &lt;code&gt;POST&lt;/code&gt; to the token endpoint with &lt;code&gt;grant_type=urn:ietf:params:oauth:grant-type:token-exchange&lt;/code&gt;, a &lt;code&gt;subject_token&lt;/code&gt; that represents the person on whose behalf the request is made, and its &lt;code&gt;subject_token_type&lt;/code&gt;. Optional parameters name the target (&lt;code&gt;resource&lt;/code&gt;, &lt;code&gt;audience&lt;/code&gt;), the access wanted (&lt;code&gt;scope&lt;/code&gt;), and the token type wanted (&lt;code&gt;requested_token_type&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The gateway authenticates with the normal OAuth 2.0 client authentication methods.&lt;/li&gt;
&lt;li&gt;The authorization server validates the presented tokens and decides by policy whether to issue a token for the named target. If it refuses, it answers with &lt;code&gt;invalid_request&lt;/code&gt;, or with &lt;code&gt;invalid_target&lt;/code&gt; when it won&amp;rsquo;t issue a token for the requested target.&lt;/li&gt;
&lt;li&gt;A successful response is a normal OAuth token response: &lt;code&gt;access_token&lt;/code&gt; carries the issued token, together with &lt;code&gt;issued_token_type&lt;/code&gt;, &lt;code&gt;token_type&lt;/code&gt;, and, as recommended, &lt;code&gt;expires_in&lt;/code&gt;. The issued token doesn&amp;rsquo;t have to be an OAuth access token.&lt;/li&gt;
&lt;li&gt;The gateway calls the target service with the issued token and returns only the result to the agent.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="explainer-app" hidden&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;p&gt;The following request shows step 2 with placeholder hosts and tokens. It illustrates the RFC parameters and isn&amp;rsquo;t the broker&amp;rsquo;s API. I&amp;rsquo;ve left the values unencoded and added line breaks for readability; a real request URL-encodes the form body.&lt;/p&gt;
&lt;figure class="code" data-lang="http"&gt;&lt;figcaption class="code-file"&gt;&lt;span class="sr-only"&gt;File: &lt;/span&gt;token-exchange.http&lt;/figcaption&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" aria-label="token-exchange.http" class="chroma"&gt;&lt;code data-lang="http"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/token&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;broker.example.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;Basic &amp;lt;gateway client credentials&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Content-Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;application/x-www-form-urlencoded&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;amp;subject_token=&amp;lt;token the agent presented&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;amp;subject_token_type=urn:ietf:params:oauth:token-type:access_token
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;amp;resource=https://api.provider.example/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;amp;scope=&amp;lt;permissions the tool call needs&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;The Agentic Identity Broker that Magnus Jungsbluth and I built uses this pattern, as I describe in the &lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/"&gt;retrospective&lt;/a&gt;. A user grants an agent access to a service, such as GitHub, with a chosen permission set and an optional expiry, and the broker stores the provider tokens encrypted. On each tool call, an MCP gateway such as agentgateway exchanges the agent&amp;rsquo;s token for the matching provider token, so the provider token never reaches the agent.&lt;/p&gt;
&lt;p&gt;RFC 8693 also defines an optional &lt;code&gt;actor_token&lt;/code&gt; for the party that will act on behalf of the subject. In the issued JWT, the &lt;code&gt;act&lt;/code&gt; claim can record that actor, and nested &lt;code&gt;act&lt;/code&gt; claims record a chain of earlier actors. The &lt;a href="https://github.com/zalando-incubator/agentic-identity-broker#roadmap" title="Agentic Identity Broker roadmap" class="ext"&gt;broker roadmap&lt;/a&gt; lists token exchange for agent-to-agent calls as planned work.&lt;/p&gt;
&lt;h2 id="related"&gt;Related &lt;a class="heading-anchor" href="#related" aria-label="Link to section: Related"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/"&gt;Should an agent use a robot account or delegated access?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/"&gt;How does authorization work for MCP servers?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/talks/economies-of-scale-for-mcp/"&gt;Economies of Scale for MCP and Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/projects/agentic-identity-broker/"&gt;Agentic Identity Broker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>What is inside a JWT?</title><link>https://www.janbrennenstuhl.eu/knowledge-base/oidc/jwt-anatomy/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/knowledge-base/oidc/jwt-anatomy/</guid><pubDate>Tue, 13 Oct 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; A signed JWT is 3 base64url-encoded parts joined by dots: a header that names the algorithm, a payload of claims, and a signature over both. The payload is encoded, not encrypted, so anyone holding the token can read it; only a signature check with a key you trust tells you whether to believe it.&lt;/p&gt;&lt;h2 id="key-findings"&gt;Key findings &lt;a class="heading-anchor" href="#key-findings" aria-label="Link to section: Key findings"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class="finding" id="f-jwt-claims-in-jws-or-jwe"&gt;
&lt;blockquote&gt;&lt;p&gt;A JWT is a set of claims encoded as a JSON object inside a JWS or a JWE, so the same token format can be signed, encrypted, or both.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc7519#section-2" class="ext"&gt;&lt;cite&gt;RFC 7519, JSON Web Token (JWT), Section 2&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-jwt-claims-in-jws-or-jwe" title="#f-jwt-claims-in-jws-or-jwe"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="A JWT is a set of claims encoded as a JSON object inside a JWS or a JWE, so the same token format can be signed, encrypted, or both." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/oidc/jwt-anatomy/#f-jwt-claims-in-jws-or-jwe" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/oidc/jwt-anatomy/f-jwt-claims-in-jws-or-jwe.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-jwt-payload-is-readable"&gt;
&lt;blockquote&gt;&lt;p&gt;The payload of a signed JWT is only base64url-encoded, so a token that carries privacy-sensitive claims needs encryption or must not reach parties who should not read it.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc7519#section-12" class="ext"&gt;&lt;cite&gt;RFC 7519, Section 12, Privacy Considerations&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-jwt-payload-is-readable" title="#f-jwt-payload-is-readable"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="The payload of a signed JWT is only base64url-encoded, so a token that carries privacy-sensitive claims needs encryption or must not reach parties who should not read it." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/oidc/jwt-anatomy/#f-jwt-payload-is-readable" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/oidc/jwt-anatomy/f-jwt-payload-is-readable.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-jwt-registered-claims-optional"&gt;
&lt;blockquote&gt;&lt;p&gt;RFC 7519 registers 7 claim names, iss, sub, aud, exp, nbf, iat and jti, and none of them is mandatory in every case; each application profile decides which it requires.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc7519#section-4.1" class="ext"&gt;&lt;cite&gt;RFC 7519, Section 4.1&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-jwt-registered-claims-optional" title="#f-jwt-registered-claims-optional"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="RFC 7519 registers 7 claim names, iss, sub, aud, exp, nbf, iat and jti, and none of them is mandatory in every case; each application profile decides which it requires." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/oidc/jwt-anatomy/#f-jwt-registered-claims-optional" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/oidc/jwt-anatomy/f-jwt-registered-claims-optional.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-jwt-allowlist-algorithms"&gt;
&lt;blockquote&gt;&lt;p&gt;JWT libraries must let the caller specify the supported algorithms and must not use any other algorithm, which closes the door on tokens whose header was changed to &amp;ldquo;none&amp;rdquo;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc8725#section-3.1" class="ext"&gt;&lt;cite&gt;RFC 8725, JSON Web Token Best Current Practices, Section 3.1&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-jwt-allowlist-algorithms" title="#f-jwt-allowlist-algorithms"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="JWT libraries must let the caller specify the supported algorithms and must not use any other algorithm, which closes the door on tokens whose header was changed to &amp;ldquo;none&amp;rdquo;." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/oidc/jwt-anatomy/#f-jwt-allowlist-algorithms" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/oidc/jwt-anatomy/f-jwt-allowlist-algorithms.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="evidence"&gt;Evidence &lt;a class="heading-anchor" href="#evidence" aria-label="Link to section: Evidence"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="table-scroll studies" tabindex="0" role="region" aria-label="Specifications"&gt;&lt;table&gt;
&lt;caption&gt;Specifications&lt;/caption&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th scope="col"&gt;Study&lt;/th&gt;&lt;th scope="col"&gt;Year&lt;/th&gt;&lt;th scope="col"&gt;Sample&lt;/th&gt;&lt;th scope="col"&gt;Method&lt;/th&gt;&lt;th scope="col"&gt;Finding&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc7519" class="ext"&gt;RFC 7519: JSON Web Token (JWT)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2015&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Defines the JWT format, the registered claim names and the privacy considerations for claims.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc7515" class="ext"&gt;RFC 7515: JSON Web Signature (JWS)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2015&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Defines the compact serialization: base64url header, payload and signature joined by dots.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc8725" class="ext"&gt;RFC 8725: JSON Web Token Best Current Practices&lt;/a&gt;&lt;span class="org"&gt;IETF (BCP 225)&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2020&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Best current practice&lt;/td&gt;&lt;td&gt;Requires algorithm allowlists in libraries and audience, issuer and key validation in applications.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id="what-to-do"&gt;What to do &lt;a class="heading-anchor" href="#what-to-do" aria-label="Link to section: What to do"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="for-engineers"&gt;For engineers &lt;a class="heading-anchor" href="#for-engineers" aria-label="Link to section: For engineers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Treat a decoded payload as untrusted input until the signature verifies. Pin the algorithms you accept instead of reading &lt;code&gt;alg&lt;/code&gt; from the token, and resolve the key by &lt;code&gt;kid&lt;/code&gt; only from a key set you trust, such as the issuer&amp;rsquo;s &lt;a href="https://www.janbrennenstuhl.eu/jwks/"&gt;JWKS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;After the signature, check &lt;code&gt;exp&lt;/code&gt;, &lt;code&gt;nbf&lt;/code&gt;, &lt;code&gt;iss&lt;/code&gt; and &lt;code&gt;aud&lt;/code&gt;. RFC 8725 makes audience validation a must whenever one issuer serves several relying parties.&lt;/li&gt;
&lt;li&gt;Keep secrets and personal data out of signed tokens. If a token has to carry them, use &lt;a href="https://www.janbrennenstuhl.eu/jwe/"&gt;JWE&lt;/a&gt; or keep the data on the server and put a reference in the token.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="for-product-and-ux"&gt;For product and UX &lt;a class="heading-anchor" href="#for-product-and-ux" aria-label="Link to section: For product and UX"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tokens end up in logs, browser storage and support tickets. Anything in the payload should be safe to show to whoever might see it there.&lt;/li&gt;
&lt;li&gt;Short token lifetimes are a product decision as much as a security one: they decide how often a session has to be refreshed.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="try-it"&gt;Try it &lt;a class="heading-anchor" href="#try-it" aria-label="Link to section: Try it"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;section class="explainer" data-explainer="jwt" aria-labelledby="ex-jwt"&gt;
&lt;h3 id="ex-jwt"&gt;Decode a token in your browser&lt;/h3&gt;
&lt;div class="explainer-static"&gt;&lt;p&gt;The example token below has 3 parts. Paste your own token into the decoder to split and decode it. Decoding happens only in your browser; nothing is sent anywhere, and the signature is not verified.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjIwMjYtMTAifQ.eyJpc3MiOiJodHRwczovL2lkLmV4YW1wbGUuY29tIiwic3ViIjoidXNlci0xMjMiLCJhdWQiOiJodHRwczovL2FwaS5leGFtcGxlLmNvbSIsImV4cCI6MTc5MTkwMDAwMCwiaWF0IjoxNzkxODk2NDAwLCJqdGkiOiI3ZjNjOWEifQ.cGxhY2Vob2xkZXIgc2lnbmF0dXJlLCBub3QgdmFsaWQ&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Header&lt;/strong&gt; decodes to &lt;code&gt;{&amp;quot;alg&amp;quot;:&amp;quot;ES256&amp;quot;,&amp;quot;typ&amp;quot;:&amp;quot;JWT&amp;quot;,&amp;quot;kid&amp;quot;:&amp;quot;2026-10&amp;quot;}&lt;/code&gt;: an ECDSA P-256 signature, and the ID of the key that made it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Payload&lt;/strong&gt; decodes to &lt;code&gt;{&amp;quot;iss&amp;quot;:&amp;quot;https://id.example.com&amp;quot;,&amp;quot;sub&amp;quot;:&amp;quot;user-123&amp;quot;,&amp;quot;aud&amp;quot;:&amp;quot;https://api.example.com&amp;quot;,&amp;quot;exp&amp;quot;:1791900000,&amp;quot;iat&amp;quot;:1791896400,&amp;quot;jti&amp;quot;:&amp;quot;7f3c9a&amp;quot;}&lt;/code&gt;: issued at 13:00 UTC on 13 October 2026, expiring 1 hour later.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Signature&lt;/strong&gt; is a placeholder in this example. In a real token it is the ES256 signature over the encoded header and payload, checked with the issuer&amp;rsquo;s public key from its JWKS.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="explainer-app" hidden&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;h2 id="how-the-parts-fit-together"&gt;How the parts fit together &lt;a class="heading-anchor" href="#how-the-parts-fit-together" aria-label="Link to section: How the parts fit together"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The header and payload are JSON objects. Each is encoded with base64url, a URL-safe variant of base64 without padding, and the two results are joined with a dot. The signer signs that string with the algorithm named in the header and appends the base64url-encoded signature after a second dot. That is the JWS compact serialization from RFC 7515.&lt;/p&gt;
&lt;p&gt;A verifier reverses the steps: split at the dots, decode the header, pick the key and algorithm it allows, and verify the signature over the first 2 parts exactly as received. Only then does it decode the payload and evaluate the claims. The essays on &lt;a href="https://www.janbrennenstuhl.eu/jwt-stateless-authentication/"&gt;the purpose of JWT&lt;/a&gt;, &lt;a href="https://www.janbrennenstuhl.eu/jwa/"&gt;JSON Web Algorithms&lt;/a&gt; and &lt;a href="https://www.janbrennenstuhl.eu/jwt-vs-oauth/"&gt;JWT versus OAuth 2.0&lt;/a&gt; go deeper.&lt;/p&gt;
&lt;h2 id="related"&gt;Related &lt;a class="heading-anchor" href="#related" aria-label="Link to section: Related"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/"&gt;How does OAuth 2.0 Token Exchange keep provider tokens away from agents?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/oidc/openid-connect-security/"&gt;Where do OpenID Connect implementations break?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Should an agent use a robot account or delegated access?</title><link>https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/</guid><pubDate>Tue, 13 Oct 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; When an agent acts for a person, give it delegated access that names both the person and the agent, with narrow scopes, an expiry, and a way to revoke it. A robot account shared by several people gives the agent their combined permissions and hides whose request was whose.&lt;/p&gt;&lt;h2 id="key-findings"&gt;Key findings &lt;a class="heading-anchor" href="#key-findings" aria-label="Link to section: Key findings"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class="finding" id="f-agent-robot-account-combined-permissions"&gt;
&lt;blockquote&gt;&lt;p&gt;When several people share an agent that holds a robot account, the agent acts with the combined permissions of all its users, and nobody can tell whose request was whose.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/" class="ext"&gt;&lt;cite&gt;What I Learned Building an Identity Broker With Coding Agents (janbrennenstuhl.eu, 2026)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-robot-account-combined-permissions" title="#f-agent-robot-account-combined-permissions"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="When several people share an agent that holds a robot account, the agent acts with the combined permissions of all its users, and nobody can tell whose request was whose." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/#f-agent-robot-account-combined-permissions" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/f-agent-robot-account-combined-permissions.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-delegation-keeps-actor-identity"&gt;
&lt;blockquote&gt;&lt;p&gt;Under the delegation semantics of OAuth 2.0 Token Exchange, the acting party keeps its own identity, separate from the person whose rights it uses.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc8693#section-1.1" class="ext"&gt;&lt;cite&gt;RFC 8693, OAuth 2.0 Token Exchange (IETF, 2020), Section 1.1&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-delegation-keeps-actor-identity" title="#f-agent-delegation-keeps-actor-identity"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Under the delegation semantics of OAuth 2.0 Token Exchange, the acting party keeps its own identity, separate from the person whose rights it uses." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/#f-agent-delegation-keeps-actor-identity" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/f-agent-delegation-keeps-actor-identity.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-token-least-privilege"&gt;
&lt;blockquote&gt;&lt;p&gt;The OAuth 2.0 security best current practice says an access token&amp;rsquo;s privileges should be restricted to the minimum the use case requires, and the token should be audience-restricted to a specific resource server.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.rfc-editor.org/rfc/rfc9700#section-2.3" class="ext"&gt;&lt;cite&gt;RFC 9700, Best Current Practice for OAuth 2.0 Security (IETF, 2025), Section 2.3&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-token-least-privilege" title="#f-agent-token-least-privilege"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="The OAuth 2.0 security best current practice says an access token&amp;rsquo;s privileges should be restricted to the minimum the use case requires, and the token should be audience-restricted to a specific resource server." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/#f-agent-token-least-privilege" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/f-agent-token-least-privilege.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-agent-no-long-lived-keys"&gt;
&lt;blockquote&gt;&lt;p&gt;Coding agents should not hold persistent identity and access management (IAM) roles or long-lived API keys; an identity broker can issue short-lived, task-scoped credentials on demand instead.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.janbrennenstuhl.eu/appsec-agentic-engineering/" class="ext"&gt;&lt;cite&gt;AppSec in the Age of Agentic Engineering (janbrennenstuhl.eu, 2026)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-agent-no-long-lived-keys" title="#f-agent-no-long-lived-keys"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Coding agents should not hold persistent identity and access management (IAM) roles or long-lived API keys; an identity broker can issue short-lived, task-scoped credentials on demand instead." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/#f-agent-no-long-lived-keys" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/delegation-vs-robot-accounts/f-agent-no-long-lived-keys.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="evidence"&gt;Evidence &lt;a class="heading-anchor" href="#evidence" aria-label="Link to section: Evidence"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="table-scroll studies" tabindex="0" role="region" aria-label="Primary sources on robot accounts and delegated agent access"&gt;&lt;table&gt;
&lt;caption&gt;Primary sources on robot accounts and delegated agent access&lt;/caption&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th scope="col"&gt;Study&lt;/th&gt;&lt;th scope="col"&gt;Year&lt;/th&gt;&lt;th scope="col"&gt;Sample&lt;/th&gt;&lt;th scope="col"&gt;Method&lt;/th&gt;&lt;th scope="col"&gt;Finding&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc8693" class="ext"&gt;OAuth 2.0 Token Exchange (RFC 8693)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2020&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Defines delegation and impersonation semantics and the act claim that names the acting party.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9700" class="ext"&gt;Best Current Practice for OAuth 2.0 Security (RFC 9700)&lt;/a&gt;&lt;span class="org"&gt;IETF&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2025&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Asks for least-privilege, audience-restricted tokens and warns when resource servers can&amp;rsquo;t tell client tokens from user tokens.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization" class="ext"&gt;Model Context Protocol: Authorization (revision 2026-07-28)&lt;/a&gt;&lt;span class="org"&gt;Model Context Protocol&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Specification&lt;/td&gt;&lt;td&gt;Treats clients acting for a user differently from clients acting on their own behalf.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/" class="ext"&gt;What I Learned Building an Identity Broker With Coding Agents&lt;/a&gt;&lt;span class="org"&gt;this site&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Field report&lt;/td&gt;&lt;td&gt;Explains why the Agentic Identity Broker keeps both the user and the agent in every authorization decision.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.janbrennenstuhl.eu/appsec-agentic-engineering/" class="ext"&gt;AppSec in the Age of Agentic Engineering&lt;/a&gt;&lt;span class="org"&gt;this site&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Essay&lt;/td&gt;&lt;td&gt;Argues for short-lived, task-scoped credentials and user-revocable delegation for agents.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id="what-to-do"&gt;What to do &lt;a class="heading-anchor" href="#what-to-do" aria-label="Link to section: What to do"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="for-engineers"&gt;For engineers &lt;a class="heading-anchor" href="#for-engineers" aria-label="Link to section: For engineers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Ask first whom the agent acts for. If it runs a job on its own behalf, a dedicated client with its own narrow permissions is a reasonable fit. The &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/"&gt;MCP authorization specification&lt;/a&gt; explicitly mentions such &lt;code&gt;client_credentials&lt;/code&gt; clients. If it acts for a person, use a grant that names that person and that agent, and keep it narrow and short-lived as &lt;a href="https://www.rfc-editor.org/rfc/rfc9700#section-2.3" class="ext"&gt;RFC 9700&lt;/a&gt; asks.&lt;/p&gt;
&lt;p&gt;Prefer delegation over impersonation. A delegated token can carry the agent as the actor next to the person as the subject, so a resource server and your logs can tell them apart. RFC 9700 also warns that a resource server that can&amp;rsquo;t distinguish tokens obtained with a person&amp;rsquo;s involvement from tokens a client obtained on its own may let that client reach the person&amp;rsquo;s resources.&lt;/p&gt;
&lt;p&gt;Keep provider credentials out of the agent&amp;rsquo;s context. &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/"&gt;Token exchange&lt;/a&gt; shows how a gateway can do this on each tool call.&lt;/p&gt;
&lt;h3 id="for-product-and-ux"&gt;For product and UX &lt;a class="heading-anchor" href="#for-product-and-ux" aria-label="Link to section: For product and UX"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Show people which agent holds access to which service, with what permissions and until when. Give them one place to &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/"&gt;revoke that access&lt;/a&gt;. If several people use the same agent, show each of them only the grants they made.&lt;/p&gt;
&lt;h2 id="how-it-works"&gt;How it works &lt;a class="heading-anchor" href="#how-it-works" aria-label="Link to section: How it works"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With a robot account, the agent holds a long-lived credential for each MCP server or API it calls. In OAuth terms, that is closest to a client that gets tokens for itself, without a person in the flow. RFC 9700 quotes the JSON Web Token (JWT) profile for access tokens (RFC 9068): the &lt;code&gt;sub&lt;/code&gt; claim of such a token should identify the client application, while a token obtained with a person&amp;rsquo;s involvement should identify that person. A robot account therefore can&amp;rsquo;t express who asked for an action. In &lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/"&gt;my retrospective&lt;/a&gt;, I describe the consequences once several people share the agent: combined permissions, no attribution, and credentials within reach of anything that tricks the agent.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc8693#section-1.1" class="ext"&gt;RFC 8693&lt;/a&gt; describes 2 ways one party can use another&amp;rsquo;s rights. With impersonation, party A gets B&amp;rsquo;s rights and is indistinguishable from B in that context. With delegation, A keeps its own identity, and it&amp;rsquo;s explicitly understood that A acts for B. The RFC uses this exact phrase: &amp;ldquo;In a sense, A is an agent for B.&amp;rdquo; A token that carries both identities is a composite token. In a JWT, the &lt;code&gt;act&lt;/code&gt; claim names the acting party.&lt;/p&gt;
&lt;p&gt;The Agentic Identity Broker that Magnus Jungsbluth and I built applies delegation. A user grants an agent access to a service with a chosen permission set and an optional expiry and can revoke the grant at any time. The broker keeps both the user and the agent in every authorization decision. The essay and our &lt;a href="https://www.janbrennenstuhl.eu/talks/economies-of-scale-for-mcp/"&gt;AGNTCon + MCPCon talk&lt;/a&gt; explain the design, and the &lt;a href="https://www.janbrennenstuhl.eu/projects/agentic-identity-broker/"&gt;project page&lt;/a&gt; links the code.&lt;/p&gt;
&lt;p&gt;This model covers agents that act for a person. For autonomous agents with no human in the loop, I wrote in the retrospective that every approach I know of is still brittle.&lt;/p&gt;
&lt;h2 id="related"&gt;Related &lt;a class="heading-anchor" href="#related" aria-label="Link to section: Related"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/token-exchange/"&gt;How does OAuth 2.0 Token Exchange keep provider tokens away from agents?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/consent-and-revocation/"&gt;How should people grant and revoke an agent&amp;rsquo;s access?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/agent-identity/mcp-authorization/"&gt;How does authorization work for MCP servers?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/appsec-agentic-engineering/"&gt;AppSec in the Age of Agentic Engineering&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Economies of Scale for MCP and Agents</title><link>https://www.janbrennenstuhl.eu/talks/economies-of-scale-for-mcp/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/talks/economies-of-scale-for-mcp/</guid><pubDate>Fri, 18 Sep 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;Presented by Magnus Jungsbluth and Jan Brennenstuhl at AGNTCon + MCPCon Europe in Amsterdam on 18 September 2026.&lt;/p&gt;
&lt;h2 id="materials"&gt;Materials &lt;a class="heading-anchor" href="#materials" aria-label="Link to section: Materials"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://agenticidentitybroker.dev/docs/presentations/2026-09-18_agntcon-mcpcon-agentic-identity-broker.pdf" class="ext"&gt;Presentation slides (PDF)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://agntconmcpconeu26.sched.com/event/2RBAI" class="ext"&gt;Session information&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/"&gt;Supporting article: What I Learned Building an Identity Broker With Coding Agents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reading-companion"&gt;Reading companion &lt;a class="heading-anchor" href="#reading-companion" aria-label="Link to section: Reading companion"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An agent should not hold a shared, long-lived provider credential. The broker ties delegated access to both the person and the agent, with chosen permissions and optional expiry. On a tool call, a gateway exchanges the agent&amp;rsquo;s token for a provider token; the provider token does not enter the agent&amp;rsquo;s context.&lt;/p&gt;
&lt;p&gt;This is a short reading companion, not a transcript. The supporting article explains the identity model and the engineering lessons in accessible HTML.&lt;/p&gt;</description></item><item><title>Agentic Identity Broker</title><link>https://www.janbrennenstuhl.eu/projects/agentic-identity-broker/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/projects/agentic-identity-broker/</guid><pubDate>Tue, 15 Sep 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;Magnus Jungsbluth and I built the open-source Agentic Identity Broker. It keeps the user and the agent in authorization decisions and stores provider tokens outside the agent&amp;rsquo;s context.&lt;/p&gt;
&lt;h2 id="explore-the-project"&gt;Explore the project &lt;a class="heading-anchor" href="#explore-the-project" aria-label="Link to section: Explore the project"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://agenticidentitybroker.dev/" class="ext"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zalando-incubator/agentic-identity-broker" class="ext"&gt;Source code and current project status&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/agentic-identity-broker/"&gt;What I learned building it&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The project is licensed under MIT. This page reflects the September 2026 release; consult the project documentation for current capabilities.&lt;/p&gt;</description></item><item><title>Mastering JWKS: JSON Web Key Sets Explained</title><link>https://www.janbrennenstuhl.eu/jwks/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/jwks/</guid><pubDate>Fri, 02 Jun 2023 00:00:00 +0200</pubDate><description>&lt;h2 id="tldr"&gt;TL;DR &lt;a class="heading-anchor" href="#tldr" aria-label="Link to section: TL;DR"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JWKS (JSON Web Key Set) is a tool for standardizing the representation and management of cryptographic keys via a JSON object.&lt;/li&gt;
&lt;li&gt;The technology, defined in RFC 7517, enables client-local &lt;a href="https://www.janbrennenstuhl.eu/topics/tokens-jwt/" title="JWT Security: Best practices and when to use JSON Web Token"&gt;JWT (JSON Web Tokens)&lt;/a&gt; verification and is integral for decentralized authentication protocols such as OpenID Connect and &lt;a href="https://www.janbrennenstuhl.eu/topics/identity-authentication/" title="OAuth 2.0 in Action"&gt;OAuth2&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Implementing JWKS simplifies key management, eases key rotation, and secures key distribution across multiple servers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="technical-specifications-of-jwk-and-jwks"&gt;Technical Specifications of JWK and JWKS &lt;a class="heading-anchor" href="#technical-specifications-of-jwk-and-jwks" aria-label="Link to section: Technical Specifications of JWK and JWKS"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;JWKS is an acronym for JSON Web Key Set. It is a collection of JSON Web Keys (JWKs) used to verify JSON Web Tokens (JWTs). Both constructs are defined in &lt;a href="https://datatracker.ietf.org/doc/html/rfc7517" title="RFC 7517: JSON Web Key (JWK)" class="ext"&gt;RFC 7517&lt;/a&gt;, yet another integral member of the famous JOSE standards family. JWK Sets provide a standardized way and format for servers to obtain the public keys required to verify asymmetrically signed JWTs locally.&lt;/p&gt;
&lt;h3 id="what-is-json-web-key-jwk"&gt;What is JSON Web Key (JWK)? &lt;a class="heading-anchor" href="#what-is-json-web-key-jwk" aria-label="Link to section: What is JSON Web Key (JWK)?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A JWK is a JSON object data structure that represents a cryptographic key. It contains the key type, key operations, algorithm, and all relevant material to reconstruct the signature verification key. All officially supported &lt;a href="https://www.janbrennenstuhl.eu/jwa/" title="What is JWA?"&gt;JSON Web Algorithms (JWA)&lt;/a&gt; are defined in &lt;a href="https://datatracker.ietf.org/doc/html/rfc7518" title="RFC 7518: JSON Web Algorithms (JWA)" class="ext"&gt;RFC 7518&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The JSON data structure of the JWK format allows for easy, web-native exchange of public keys. The representation of an Elliptic Curve signature key of curve P-256 could look like this:&lt;/p&gt;
&lt;figure class="code" data-lang="json"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" aria-label="Code (json)" class="chroma"&gt;&lt;code data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;kty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;EC&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;use&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;sig&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;crv&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;P-256&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;kid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;01H1SG7BX197N040C0MHTDV1HR&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SEfcECpwqQg-vZ6Lv99RyV0Qkatngz1RV25nI5SOrPg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;YU2PRA6pXZ62OW_XuzjJqplqmBUtBwT2pKUZUVxUYfc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;alg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ES256&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;h3 id="what-is-json-web-key-set-jwks"&gt;What is JSON Web Key Set (JWKS)? &lt;a class="heading-anchor" href="#what-is-json-web-key-set-jwks" aria-label="Link to section: What is JSON Web Key Set (JWKS)?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A JWKS is a JSON object that represents a set of JWKs. It must contain a &amp;ldquo;keys&amp;rdquo; member and an array of JWKs. JSON Web Key Sets enable identity providers to support and expose more than one public key under a well-known resource. The following example JWK Set format contains two public cryptographic keys – one using an Elliptic Curve (EC) algorithm and a second one using an RSA algorithm:&lt;/p&gt;
&lt;figure class="code" data-lang="text"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" aria-label="Code" class="chroma"&gt;&lt;code data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{&amp;#34;keys&amp;#34;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;kty&amp;#34;: &amp;#34;EC&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;use&amp;#34;: &amp;#34;sig&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;crv&amp;#34;: &amp;#34;P-256&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;kid&amp;#34;: &amp;#34;01H1SG7BX197N040C0MHTDV1HR&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;x&amp;#34;: &amp;#34;SEfcECpwqQg-vZ6Lv99RyV0Qkatngz1RV25nI5SOrPg&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;y&amp;#34;: &amp;#34;YU2PRA6pXZ62OW_XuzjJqplqmBUtBwT2pKUZUVxUYfc&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;alg&amp;#34;: &amp;#34;ES256&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }, {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;kty&amp;#34;:&amp;#34;RSA&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;n&amp;#34;: &amp;#34;1qrQCTst3RF04aMC9Ye_kGbsE0sftL4FOtB_WrzBDOFdrfVwLfflQuPX5kJ-0iYv9r2mjD5YIDy8b-iJKwevb69ISeoOrmL3tj6MStJesbbRRLVyFIm_6L7alHhZVyqHQtMKX7IaNndrfebnLReGntuNk76XCFxBBnRaIzAWnzr3WN4UPBt84A0KF74pei17dlqHZJ2HB2CsYbE9Ort8m7Vf6hwxYzFtCvMCnZil0fCtk2OQ73l6egcvYO65DkAJibFsC9xAgZaF-9GYRlSjMPd0SMQ8yU9i3W7beT00Xw6C0FYA9JAYaGaOvbT87l_6ZkAksOMuvIPD_jNVfTCPLQ&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;e&amp;#34;:&amp;#34;AQAB&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;alg&amp;#34;:&amp;#34;RS256&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;kid&amp;#34;:&amp;#34;01H1SGVCX7GKBGE2J2QMQREAGN&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;h3 id="locate-json-web-key-sets"&gt;Locate JSON Web Key Sets &lt;a class="heading-anchor" href="#locate-json-web-key-sets" aria-label="Link to section: Locate JSON Web Key Sets"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Many modern identity providers like Google expose their JWK Sets via the &lt;code&gt;jwks_uri&lt;/code&gt; attribute within the &lt;a href="https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig" title="OpenID Connect Discovery Spec" class="ext"&gt;well-known discovery endpoint&lt;/a&gt; of OpenID Connect (OIDC) located at &lt;code&gt;https://{identity-provider}/.well-known/openid-configuration&lt;/code&gt; which often points to &lt;code&gt;https://{identity-provider}/.well-known/jwks.json&lt;/code&gt; or a similar resource.&lt;/p&gt;
&lt;h2 id="benefits-of-using-jwks"&gt;Benefits of Using JWKS &lt;a class="heading-anchor" href="#benefits-of-using-jwks" aria-label="Link to section: Benefits of Using JWKS"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="easy-management-of-keys-with-jwk-sets"&gt;Easy Management of Keys with JWK Sets &lt;a class="heading-anchor" href="#easy-management-of-keys-with-jwk-sets" aria-label="Link to section: Easy Management of Keys with JWK Sets"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One of the main benefits of using JWKs is that they provide an easy way to manage and distribute keys across multiple servers or locations. Instead of hardcoding public keys into application code, token issuers (authorization servers) only need to provide their clients with an URL for their JSON Web Key Set.&lt;/p&gt;
&lt;p&gt;Any application that needs access to the keys can retrieve them from that remote location. This eliminates the need for manual key distribution, resolves, and ensures all applications use the same set of keys. This makes it easier to manage multiple keys and rotate them when necessary.&lt;/p&gt;
&lt;h3 id="simplified-key-rotation-process-using-jwks"&gt;Simplified Key Rotation Process Using JWKs &lt;a class="heading-anchor" href="#simplified-key-rotation-process-using-jwks" aria-label="Link to section: Simplified Key Rotation Process Using JWKs"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Rotating keys is essential for maintaining security in any system that uses cryptography. However, manually replacing these keys can take time and effort. JWKS can simplify this process by automating key rotation.&lt;/p&gt;
&lt;p&gt;As JWKs decouple the authorization server from relying party applications, token issuers can generate new asymmetric key pairs whenever necessary. Setting up regular intervals for key rotation, publishing the new public key material, and using the latest private key automatically after some grace period, can ensure that the amount of keys signed with a particular key has a natural upper limit.&lt;/p&gt;
&lt;h3 id="compatibility-with-various-protocols-and-applications"&gt;Compatibility with Various Protocols and Applications &lt;a class="heading-anchor" href="#compatibility-with-various-protocols-and-applications" aria-label="Link to section: Compatibility with Various Protocols and Applications"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Finally, the JSON Web Key Set standard is compatible with various protocols and applications. This means it can enable local token validation in the context of web applications, APIs, mobile apps, and more. Popular authentication protocols such as OAuth 2.0 and OpenID Connect support JSON Web Key Set.&lt;/p&gt;
&lt;h2 id="best-practices--security-considerations"&gt;Best Practices &amp;amp; Security Considerations &lt;a class="heading-anchor" href="#best-practices--security-considerations" aria-label="Link to section: Best Practices &amp;amp; Security Considerations"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Dealing with cryptographic and primarily private keys is a highly sensitive undertaking. The security issues relevant to any cryptographic application must also be considered when dealing with JSON Web Token (JWT) and JSON Web Signature (JWS). It is essential to implement JSON Web Key Set (JWKS) correctly to ensure the security and integrity of the entire infrastructure. Here are some best practices for implementing JWKS.&lt;/p&gt;
&lt;h3 id="use-transport-layer-security"&gt;Use Transport Layer Security &lt;a class="heading-anchor" href="#use-transport-layer-security" aria-label="Link to section: Use Transport Layer Security"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Serving a JSON Web Key over HTTP poses significant security risks as it can be intercepted or modified in transit. Therefore, it is crucial to use HTTPS also when serving JWKS. HTTPS ensures that all communication between the client and server is encrypted, preventing unauthorized access or in-transit modification.&lt;/p&gt;
&lt;h3 id="make-sure-jwks-is-correct-and-current"&gt;Make sure JWKS is correct and current &lt;a class="heading-anchor" href="#make-sure-jwks-is-correct-and-current" aria-label="Link to section: Make sure JWKS is correct and current"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The entire system&amp;rsquo;s security relies on having up-to-date and accurate JWKS. If any cryptographic keys in the set expire or become invalid, it could result in rejected tokens or, worse yet, accepted but fraudulent tokens being used throughout the system. It&amp;rsquo;s essential to have processes in place to monitor and update JSON Web Keys regularly. This includes rotating keys, removing EOL keys, and adding new keys as necessary. Cryptographic key management should be automated to ensure that all cryptographic keys are always up-to-date. Symmetric keys must not be exposed!&lt;/p&gt;
&lt;h3 id="validate-the-signatures-of-incoming-jwts-using-jwks"&gt;Validate the signatures of incoming JWTs using JWKs &lt;a class="heading-anchor" href="#validate-the-signatures-of-incoming-jwts-using-jwks" aria-label="Link to section: Validate the signatures of incoming JWTs using JWKs"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One of the primary purposes of implementing JWKS is to verify the authenticity of incoming JWTs – be it access token or ID token. To do this, all applications that perform authorization decisions based on JSON &lt;a href="https://www.janbrennenstuhl.eu/single-use-jwt/" title="Single-Use JWT: The Power of Stateless One Time Token"&gt;Web Token&lt;/a&gt;, should fetch the entire JSON Web Key Set per the corresponding cache-control headers.&lt;/p&gt;
&lt;p&gt;Validating a JWT starts with fetching the &lt;code&gt;kid&lt;/code&gt; (key ID) parameter from its header. This key identifier specifies which cryptographic key in the JWKS was used by the authorization server to sign the token. The identified key can then be used to verify the signature by comparing it against the one included in the token&amp;rsquo;s signature.&lt;/p&gt;
&lt;p&gt;If the signature is valid, the token was issued by a trusted party and can be processed accordingly. An invalid token must be rejected immediately.&lt;/p&gt;
&lt;h3 id="consider-rotating-your-jwks-keys-periodically"&gt;Consider rotating your JWKS keys periodically &lt;a class="heading-anchor" href="#consider-rotating-your-jwks-keys-periodically" aria-label="Link to section: Consider rotating your JWKS keys periodically"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Rotating JSON Web Keys periodically is an essential best practice for maintaining a proper security posture. Doing so reduces the risk of compromised keys being used maliciously throughout the system. Rotating keys effectively requires creating a new set before retiring any old ones. This will ensure no gaps in coverage during the transition period.&lt;/p&gt;
&lt;h2 id="conclusion-the-importance-of-using-json-web-key-sets"&gt;Conclusion: The Importance of Using JSON Web Key Sets &lt;a class="heading-anchor" href="#conclusion-the-importance-of-using-json-web-key-sets" aria-label="Link to section: Conclusion: The Importance of Using JSON Web Key Sets"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Implementing JSON Web Key Sets (JWKS) is crucial for organizations that leverage decentralized authentication protocols like OpenID Connect or authorization delegation protocols like plain OAuth2. Truly benefiting from public-key cryptography requires client applications to verify issued tokens locally, without indispensable synchronous HTTP requests.&lt;/p&gt;
&lt;p&gt;Using a data interchange format like JSON Web Key (JWK), which is based on JavaScript Object Notation (JSON), and hosting the cryptographic keys on publicly accessible, standardized discovery endpoints allows maintaining decoupled service architectures while shifting effort to the client-side following a pull principle.&lt;/p&gt;</description></item><item><title>JSON Web Encryption: Exploring JWE Token</title><link>https://www.janbrennenstuhl.eu/jwe/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/jwe/</guid><pubDate>Mon, 29 May 2023 00:00:00 +0200</pubDate><description>&lt;h2 id="tldr"&gt;TL;DR &lt;a class="heading-anchor" href="#tldr" aria-label="Link to section: TL;DR"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JSON Web Encryption (JWE) is a standard for securing data transmission between parties, providing confidentiality, integrity, and authentication. It uses encryption to protect the payload of a &lt;a href="https://www.janbrennenstuhl.eu/topics/tokens-jwt/" title="JWT Security: Best practices and when to use JSON Web Token"&gt;JSON Web Token (JWT)&lt;/a&gt; and supports both symmetric and asymmetric encryption techniques. It also allows creating nested JWTs, combining the advantages of JWE and JSON Web Signature (JWS).&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;JWE token&lt;/strong&gt; consists of five parts: the Protected Header, the Content Encryption Key, the Initialization Vector, the Ciphertext, and the Authentication Tag. It supports various encryption algorithms like RSA-OAEP, AES-GCM, and ECDH-ES and requires using authenticated encryption to ensure the token&amp;rsquo;s integrity and confidentiality.&lt;/li&gt;
&lt;li&gt;Modern authentication and authorization frameworks like OAuth2 and &lt;a href="https://www.janbrennenstuhl.eu/topics/identity-authentication/" title="OpenID Connect: User Authentication &amp;amp; Identity"&gt;OpenID Connect (OIDC)&lt;/a&gt; use &lt;strong&gt;JWE tokens&lt;/strong&gt; as bearer tokens. Proper key management is crucial to maintain the security guarantees of JWE.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="json-web-encryption-jwe-token-a-comprehensive-guide"&gt;JSON Web Encryption (JWE) Token: A Comprehensive Guide &lt;a class="heading-anchor" href="#json-web-encryption-jwe-token-a-comprehensive-guide" aria-label="Link to section: JSON Web Encryption (JWE) Token: A Comprehensive Guide"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;JWE is a widely-used standard for &lt;strong&gt;securing data transmission&lt;/strong&gt; between parties. The industry standard describes a JSON Web Token (JWT) type that uses encryption to protect its &lt;strong&gt;payload&lt;/strong&gt;. It provides &lt;strong&gt;confidentiality&lt;/strong&gt; by encrypting the transmitted data, ensuring only &lt;strong&gt;authorized parties&lt;/strong&gt; can access and read it.&lt;/p&gt;
&lt;p&gt;In addition to providing confidentiality, &lt;strong&gt;JWE tokens&lt;/strong&gt; offer &lt;strong&gt;integrity&lt;/strong&gt; protection through message authentication codes (MACs). These codes ensure the receiver can detect tampering with the &lt;strong&gt;encrypted payload&lt;/strong&gt;. Depending on the key management mode, it can also provide authentication.&lt;/p&gt;
&lt;p&gt;JWE is relevant for modern AAA concepts in distributed, stateless environments as it enables an exchange of &lt;strong&gt;sensitive information&lt;/strong&gt; statelessly.&lt;/p&gt;
&lt;h3 id="the-structure-of-an-encrypted-jwt"&gt;The Structure of an Encrypted JWT &lt;a class="heading-anchor" href="#the-structure-of-an-encrypted-jwt" aria-label="Link to section: The Structure of an Encrypted JWT"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The JWE standard (&lt;a href="https://datatracker.ietf.org/doc/html/rfc7516" title="JSON Web Encryption (JWE)" class="ext"&gt;RFC 7516&lt;/a&gt;) is the go-to solution for developers who need to transmit JSON objects over the internet securely. JWE is a standard that defines how to encrypt and decrypt data in &lt;strong&gt;JSON format&lt;/strong&gt; using various algorithms. In this section, I will discuss some of the core concepts of JWE tokens.&lt;/p&gt;
&lt;p&gt;A typical, compact serialized, &lt;strong&gt;encrypted JWT&lt;/strong&gt; is a dot (.) separated string that contains five parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The JWE Protected Header is a base64url-encoded string representing the token metadata. It describes the JWE, how it was encrypted, and the media type of the encrypted payload. Protected JWE headers can’t be encrypted as they carry all information necessary for decryption.&lt;/li&gt;
&lt;li&gt;The JWE Encrypted Key (CEK) is another base64url-encoded string representing the encrypted, symmetric key used to encrypt the payload.&lt;/li&gt;
&lt;li&gt;The JWE Initialization Vector (IV) is a base64-encoded unique, random value string used when encrypting the plaintext and helps prevent attackers from exploiting patterns in plaintext or ciphertext.&lt;/li&gt;
&lt;li&gt;The JWE Ciphertext, the actual encrypted payload, also base64url-encoded, which was encrypted using the CEK, along with the IV and the additional authenticated data (AAD).&lt;/li&gt;
&lt;li&gt;The JWE Authentication Tag (MAC) results from performing &lt;strong&gt;authenticated encryption&lt;/strong&gt; and allows a verifier to prove the integrity of the ciphertext and the AAD (the encoded protected header when using compact serialization). It ensures integrity during decryption.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="support-for-symmetric-and-asymmetric-encryption-algorithms"&gt;Support for Symmetric and Asymmetric Encryption Algorithms &lt;a class="heading-anchor" href="#support-for-symmetric-and-asymmetric-encryption-algorithms" aria-label="Link to section: Support for Symmetric and Asymmetric Encryption Algorithms"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Encrypted JWTs support asymmetric and &lt;strong&gt;symmetric encryption&lt;/strong&gt; techniques to provide &lt;strong&gt;end-to-end security&lt;/strong&gt; for the transmitted data. Symmetric &lt;strong&gt;encryption algorithms&lt;/strong&gt; use the same key for encryption and decryption, while asymmetric algorithms use a pair of keys.&lt;/p&gt;
&lt;p&gt;The sender encrypts the plaintext payload using a randomly generated symmetric CEK, then encrypts the key using the recipient&amp;rsquo;s public key or a shared secret key (a long-lived key encryption key). The recipient can then decrypt the encrypted key using their private secret key and use it to decrypt the payload.&lt;/p&gt;
&lt;p&gt;As they are self-contained and carry their corresponding symmetric key (CEK), encrypted JWTs also support hybrid encryption, which allows combining the performance of symmetric encryption with the assurances of public-key cryptography. This flexibility lets developers choose between different encryption algorithms based on their needs.&lt;/p&gt;
&lt;h3 id="nested-jwts"&gt;Nested JWTs &lt;a class="heading-anchor" href="#nested-jwts" aria-label="Link to section: Nested JWTs"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Another exciting feature of JWE is the ability to create nested JWTs. As the JWE standard allows arbitrary data to be packaged into the payload, it also allows nesting a signed JWT (JWS) inside an encrypted JWT (JWE). Wrapping a JWS into a JWE can be helpful when dealing with asymmetrically encrypted JWE, as these alone do not allow to verify that the JWT was produced by a specific token issuer, merely that someone who possessed the issuer&amp;rsquo;s public key forged the token. Nested JWTs combine the advantages of JWE and JWS. Symmetrically encrypted JWEs provide all the above security properties without creating nested tokens.&lt;/p&gt;
&lt;h2 id="working-with-different-jwe-algorithms"&gt;Working with Different JWE Algorithms &lt;a class="heading-anchor" href="#working-with-different-jwe-algorithms" aria-label="Link to section: Working with Different JWE Algorithms"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://www.janbrennenstuhl.eu/jwa/" title="What is JWA?"&gt;JSON Web Algorithms (JWA)&lt;/a&gt; standard registers all cryptographic algorithms supported by the JWT ecosystem in &lt;a href="https://datatracker.ietf.org/doc/html/rfc7518" title="JSON Web Algorithms (JWA)" class="ext"&gt;RFC 7518&lt;/a&gt;. The most commonly recommended option for asymmetric key encryption is ECDH-ES, while AES-GCM (with key wrapping) is the recommended alternative for symmetric encryption setups.&lt;/p&gt;
&lt;h3 id="jwe-with-aes-algorithms"&gt;JWE with AES Algorithms &lt;a class="heading-anchor" href="#jwe-with-aes-algorithms" aria-label="Link to section: JWE with AES Algorithms"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;AES (Advanced Encryption Standard) algorithm is still the de-facto standard of a symmetric algorithm that can be used with JWE. It involves using the same secret key to encrypt and decrypt data. The &lt;strong&gt;JWE token can be encrypted using&lt;/strong&gt; AES-GCM (Galois/Counter Mode), which provides authenticated encryption with associated data (AEAD). AES128 should be fine for &amp;ldquo;short-lived&amp;rdquo; tokens (&lt;a href="https://crypto.stackexchange.com/questions/76738/has-aes-128-been-fully-broken/76746#76746" title="Has AES-128 been fully broken?" class="ext"&gt;&amp;lt;34 million years&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id="jwe-with-rsa-algorithms"&gt;JWE with RSA Algorithms &lt;a class="heading-anchor" href="#jwe-with-rsa-algorithms" aria-label="Link to section: JWE with RSA Algorithms"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;RSA (Rivest-Shamir-Adleman) is an example of an asymmetric encryption algorithm supported by JWE. It involves generating a key pair where the public key encrypts data while the private key allows to decrypt it. Commonly used in JWE token contexts is RSA-OAEP (Optimal Asymmetric Encryption Padding).&lt;/p&gt;
&lt;h3 id="jwe-with-elliptic-curve-algorithms"&gt;JWE with Elliptic Curve Algorithms &lt;a class="heading-anchor" href="#jwe-with-elliptic-curve-algorithms" aria-label="Link to section: JWE with Elliptic Curve Algorithms"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Elliptic Curve Cryptography (ECC) is another example of an asymmetric cryptography system supported by JWE. It involves generating a key pair based on elliptic curves rather than prime numbers. The JWE token can be encrypted using ECDH-ES (Elliptic Curve Diffie-Hellman Key Agreement with Elliptic Curve Cryptography) or ECDH-ES+A128KW (ECDH-ES with AES key wrap).&lt;/p&gt;
&lt;h3 id="authenticated-encryption-algorithms"&gt;Authenticated Encryption Algorithms &lt;a class="heading-anchor" href="#authenticated-encryption-algorithms" aria-label="Link to section: Authenticated Encryption Algorithms"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;JWE requires using authenticated encryption (AE) to ensure that the token is encrypted and integrity protected, supporting multiple AE algorithms. Two distinct classes exist, authenticated encryption with AES/CBC/HMAC/SHA and AES/GCM. The latter also supports Authenticated Encryption with Associated Data (AEAD), which provides confidentiality, integrity, and &lt;strong&gt;authenticity&lt;/strong&gt; of the encrypted message and additional authenticated data. It ensures that the message has not been tampered with during transmission.&lt;/p&gt;
&lt;h2 id="jwe-token-generation-process"&gt;JWE Token Generation Process &lt;a class="heading-anchor" href="#jwe-token-generation-process" aria-label="Link to section: JWE Token Generation Process"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="encryption-algorithm-choosing-the-right-one-for-your-needs"&gt;Encryption Algorithm: Choosing the Right One for Your Needs &lt;a class="heading-anchor" href="#encryption-algorithm-choosing-the-right-one-for-your-needs" aria-label="Link to section: Encryption Algorithm: Choosing the Right One for Your Needs"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Choosing a suitable algorithm is crucial when generating a JWE token. There are several options available, including AES-GCM, AES-CBC-HMAC-SHA2, and RSA-OAEP. Each algorithm has strengths and weaknesses, so choosing one that aligns with specific needs and requirements is essential.&lt;/p&gt;
&lt;h3 id="generating-keys-private-key-vs-secret-key"&gt;Generating Keys: Private Key vs Secret Key &lt;a class="heading-anchor" href="#generating-keys-private-key-vs-secret-key" aria-label="Link to section: Generating Keys: Private Key vs Secret Key"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The process of generating keys for JWE tokens differs depending on the form of encryption. Applying symmetric encryption requires generating a random secret key that both the sender and receiver can use to encrypt and decrypt data. Asymmetric encryption involves creating a public-private key pair.&lt;/p&gt;
&lt;h3 id="complete-jose-header"&gt;Complete JOSE Header &lt;a class="heading-anchor" href="#complete-jose-header" aria-label="Link to section: Complete JOSE Header"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The process of generating a JWE token is complex and involves several steps. The first step is the creation of a complete JOSE header that contains information about the encryption algorithm, &lt;strong&gt;key management&lt;/strong&gt; algorithm, key ID (kid), and other critical details. This header is essential because it provides the foundation for creating a secure and valid JWE token.&lt;/p&gt;
&lt;h3 id="encryption--serialization-creating-valid-jwe-tokens"&gt;Encryption &amp;amp; Serialization: Creating Valid JWE Tokens &lt;a class="heading-anchor" href="#encryption--serialization-creating-valid-jwe-tokens" aria-label="Link to section: Encryption &amp;amp; Serialization: Creating Valid JWE Tokens"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Once a suitable encryption algorithm is chosen and keys generated, it&amp;rsquo;s time to encrypt the payload involving an appropriate initialization vector (IV). After successfully calculating the ciphertext and the corresponding authentication tag, all individual parts are appropriately encoded and joined into their compact serialization format. As JWE deals with various cryptographic algorithms, is somewhat complex, and can become confusing, I recommend leveraging standard libraries to create encrypted and properly serialized JWT.&lt;/p&gt;
&lt;h2 id="jwe-token-decryption-process"&gt;JWE Token Decryption Process &lt;a class="heading-anchor" href="#jwe-token-decryption-process" aria-label="Link to section: JWE Token Decryption Process"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="decoding-the-jwe-compact-serialization"&gt;Decoding the JWE Compact Serialization &lt;a class="heading-anchor" href="#decoding-the-jwe-compact-serialization" aria-label="Link to section: Decoding the JWE Compact Serialization"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Decrypting a JWE token starts with decoding the JWE compact serialization. The JWE compact serialization is a string comprising five parts separated by dots: the JWE header, the encrypted key, the initialization vector, the JWE ciphertext, and the authentication tag. It is the most commonly used type compared to the less popular JWE JSON serialization.&lt;/p&gt;
&lt;p&gt;The protected header contains information about the encryption and key management algorithms used to encrypt the payload. This information is required to decrypt the token. Once being (base64url) decoded, these claims are accessible for introspection.&lt;/p&gt;
&lt;h3 id="key-decryption"&gt;Key Decryption &lt;a class="heading-anchor" href="#key-decryption" aria-label="Link to section: Key Decryption"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Access to the private secret key initially used to encrypt is required to decrypt the JWE token. The &lt;strong&gt;decryption algorithm&lt;/strong&gt; referenced in the JOSE header defines the cryptographic procedure for the CEK. Only after decryption can it unlock the actual payload. In the case of public key cryptography, the associated private key must be available. Single-key encryption requires the corresponding secret shared between both parties to be present.&lt;/p&gt;
&lt;h3 id="payload-decryption"&gt;Payload Decryption &lt;a class="heading-anchor" href="#payload-decryption" aria-label="Link to section: Payload Decryption"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The IV value initializes the cipher instance with an appropriate mode like CBC, GCM, etc. The previously obtained JWE encrypted key (CEK) can decrypt the JWE ciphertext value, yielding a plain text (often a JSON object) after successful decryption. The integrity of the ciphertext and its additional authenticated data (AAD), in this case, the JWE header elements, is verified using the authentication tag value provided in the last part of the serialized JWE object.&lt;/p&gt;
&lt;h2 id="security-considerations"&gt;Security Considerations &lt;a class="heading-anchor" href="#security-considerations" aria-label="Link to section: Security Considerations"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="authentication-tag-and-additional-authenticated-data"&gt;Authentication Tag and Additional Authenticated Data &lt;a class="heading-anchor" href="#authentication-tag-and-additional-authenticated-data" aria-label="Link to section: Authentication Tag and Additional Authenticated Data"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One key feature that makes JWE tokens secure is using an authentication tag and additional authenticated data (AAD). The authentication tag is a small piece of data at the end of the encrypted JWT, which allows recipients to verify that the message has not been tampered with during transmission. AAD provides an extra layer of security by enabling the sender to include additional data in the encryption process that the recipient will verify.&lt;/p&gt;
&lt;p&gt;However, not all JWE tokens have an authentication tag or AAD. There are JWA encryption algorithms that do not use an authentication tag, in which case the value is supposed to be an empty octet sequence.&lt;/p&gt;
&lt;h3 id="leaky-headers"&gt;Leaky Headers &lt;a class="heading-anchor" href="#leaky-headers" aria-label="Link to section: Leaky Headers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Another potential security concern when using JWE tokens is custom header elements. JWT headers include public claims by design that are integrity protected at max. Using customer header claims means they can potentially leak sensitive information if mismanaged. It&amp;rsquo;s crucial to handle custom header claims carefully and only include necessary information. If confidentiality is needed, custom fields belong in the payload. If there is a need for public hints, the header metadata is just fine.&lt;/p&gt;
&lt;h3 id="key-management-and-token-expiry"&gt;Key Management and Token Expiry &lt;a class="heading-anchor" href="#key-management-and-token-expiry" aria-label="Link to section: Key Management and Token Expiry"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Proper key management is essential for maintaining the security of JWE tokens. Identity providers must store the long-lived key management keys securely and rotate them regularly to prevent unauthorized access, as compromise might result in disclosing all contents protected with that key.&lt;/p&gt;
&lt;p&gt;Similarly, successful attacks on the CEK will strip all confidentiality properties from the corresponding token. Implementing token expiry to limit the amount of time token usage before it becomes invalid is necessary for all everyday use cases.&lt;/p&gt;
&lt;h3 id="weak-algorithms"&gt;Weak algorithms &lt;a class="heading-anchor" href="#weak-algorithms" aria-label="Link to section: Weak algorithms"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The JWE specification includes a limited range of supported encryption algorithms. And also, the officially supported ones rarely convince security experts: The ECDH-ES algorithm &lt;a href="https://web.archive.org/web/20201130103442/https://blogs.adobe.com/security/2017/03/critical-vulnerability-uncovered-in-json-encryption.html" title="Critical Vulnerability Uncovered in JSON Encryption" class="ext"&gt;allows an attacker to recover the private key&lt;/a&gt; if not adequately implemented. &lt;a href="https://rwc.iacr.org/2017/Slides/nguyen.quan.pdf" title="Practical Cryptanalysis of Json Web Token and Galois Counter Mode’s Implementations" class="ext"&gt;GCM is likely fragile&lt;/a&gt;, as Google researchers claim. And &lt;a href="https://archiv.infsec.ethz.ch/education/fs08/secsem/bleichenbacher98.pdf" title="Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard PKCS #1" class="ext"&gt;RSA encryption with PKCS1v1.5&lt;/a&gt; padding is broken.&lt;/p&gt;
&lt;p&gt;When leveraging JWE, I recommend supporting short notice and timely transitioning to alternative encryption algorithms.&lt;/p&gt;
&lt;h2 id="comparison-of-jwe-and-other-json-security-standards"&gt;Comparison of JWE and Other JSON Security Standards &lt;a class="heading-anchor" href="#comparison-of-jwe-and-other-json-security-standards" aria-label="Link to section: Comparison of JWE and Other JSON Security Standards"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="jwe-vs-jwt"&gt;JWE vs JWT &lt;a class="heading-anchor" href="#jwe-vs-jwt" aria-label="Link to section: JWE vs JWT"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;While both JWE and JWT are part of the JSON Object Signing and Encryption (JOSE) security framework, they &lt;a href="https://www.janbrennenstuhl.eu/jwt-stateless-authentication/" title="The Purpose of JWT: Stateless Authentication"&gt;serve different purposes&lt;/a&gt;. As mentioned, JWEs provide JSON data encryption, while unsecured JWTs (&lt;a href="https://datatracker.ietf.org/doc/html/rfc7519" title="JSON Web Token (JWT)" class="ext"&gt;RFC 7519&lt;/a&gt;) provide no particular security properties. In identity and access management (IAM) scenarios where a client sends a token to a resource server as proof of identity, JSON Web Tokens commonly appear in their signed JWS form.&lt;/p&gt;
&lt;h3 id="jwe-vs-jws-json-web-signature"&gt;JWE vs JWS (JSON Web Signature) &lt;a class="heading-anchor" href="#jwe-vs-jws-json-web-signature" aria-label="Link to section: JWE vs JWS (JSON Web Signature)"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;JWS is a JSON-based format for representing digital signatures (&lt;a href="https://datatracker.ietf.org/doc/html/rfc7515" title="JSON Web Signature (JWS)" class="ext"&gt;RFC 7515&lt;/a&gt;). JWS assures integrity and authentication, but it does not provide confidentiality. JWS tokens contain three elements: the JOSE header, payload, and signature. On the other hand, JSON Web Encryption (JWE) is a standard for encrypting JSON data. JWE tokens protect sensitive data by also providing confidentiality.&lt;/p&gt;
&lt;h3 id="jwe-vs-jwk-json-web-key"&gt;JWE vs JWK (JSON Web Key) &lt;a class="heading-anchor" href="#jwe-vs-jwk-json-web-key" aria-label="Link to section: JWE vs JWK (JSON Web Key)"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;JWK is another standard in the JOSE family (RFC 7517) that defines JSON format for cryptographic keys. A &lt;a href="https://www.janbrennenstuhl.eu/jwks/" title="Mastering JWKS: JSON Web Key Sets Explained"&gt;JWK Key Set (JWKS)&lt;/a&gt; can contain keys used for either encryption or signing, depending on their type. JWKs can be used with both JWS and JWE standards to provide cryptographic operations such as decryption or verification of digital signatures.&lt;/p&gt;
&lt;h2 id="practical-applications-of-jwe-tokens"&gt;Practical Applications of JWE Tokens &lt;a class="heading-anchor" href="#practical-applications-of-jwe-tokens" aria-label="Link to section: Practical Applications of JWE Tokens"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The nature of JWE tokens makes them ideal for enabling stateless information exchange in modern AAA processes or exotic &lt;a href="https://www.janbrennenstuhl.eu/single-use-jwt/" title="Single-Use JWT: The Power of Stateless One Time Token"&gt;one-time-token&lt;/a&gt; (OTT) scenarios. In this section, I will discuss some practical applications of JWEs.&lt;/p&gt;
&lt;h3 id="bearer-token-a-powerful-authentication-and-authorization-tool"&gt;Bearer Token: A Powerful Authentication and Authorization Tool &lt;a class="heading-anchor" href="#bearer-token-a-powerful-authentication-and-authorization-tool" aria-label="Link to section: Bearer Token: A Powerful Authentication and Authorization Tool"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;JWEs often appear as bearer tokens to authenticate and authorize access to protected resources. Bearer tokens are powerful tools because they allow users to access resources without repeatedly providing credentials. Instead, the bearer token serves as proof of identity and authorization.&lt;/p&gt;
&lt;h3 id="jwe-in-oauth2-and-oidc"&gt;JWE in OAuth2 and OIDC &lt;a class="heading-anchor" href="#jwe-in-oauth2-and-oidc" aria-label="Link to section: JWE in OAuth2 and OIDC"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.janbrennenstuhl.eu/topics/identity-authentication/" title="Delegated Authorization with OAuth 2.0"&gt;OAuth2&lt;/a&gt; and OpenID Connect (OIDC) are widely used authentication/ authorization protocols, often used for securing web APIs. They allow users to grant access to their resources without sharing their credentials with third-party applications. These protocols can use JWE Tokens to provide an additional layer of security by encrypting the access token. Enforcing clients to treat them as genuinely opaque tokens allows the token issuer (authorization server) to transport sensitive information like PII statelessly. At the same time, it also ensures that even if an attacker intercepts the token, they cannot read its contents without the &lt;strong&gt;decryption key&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="jwe-for-data-at-rest"&gt;JWE for Data at Rest &lt;a class="heading-anchor" href="#jwe-for-data-at-rest" aria-label="Link to section: JWE for Data at Rest"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Data at rest refers to data stored on disk or other storage media. This data is vulnerable to attacks if it is not adequately secured. Although not common, JWE tokens can encrypt sensitive data before storing it on disk, ensuring that even if an attacker gains access to the storage media, they cannot read its contents without the decryption key.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="heading-anchor" href="#conclusion" aria-label="Link to section: Conclusion"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;JSON Web Encryption (JWE) is a powerful tool for ensuring the confidentiality and security of data transmissions. JWE tokens carry an encrypted payload between multiple parties. The secured data can only be read with the proper decryption key, even if intercepted. Authenticated encryption ensures that sensitive information remains confidential and tamper-proof, providing both senders and receivers peace of mind.&lt;/p&gt;
&lt;p&gt;The use cases for JWE tokens are varied and versatile. Use JWE in situations where confidential data exchange is necessary. When used as a bearer token within modern authorization and authentication frameworks like OpenID Connect (OIDC), JWE tokens transport sensitive information often as access tokens.&lt;/p&gt;
&lt;h2 id="frequently-asked-questions-faqs"&gt;Frequently Asked Questions (FAQs) &lt;a class="heading-anchor" href="#frequently-asked-questions-faqs" aria-label="Link to section: Frequently Asked Questions (FAQs)"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;What is the purpose of JWE?&lt;/b&gt; – JWE tokens securely transmit data between parties in a JSON format. They provide confidentiality, integrity, and authenticity to the transmitted data.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;How does JWE differ from JWT?&lt;/b&gt; JWE focuses on encrypting the payload, while plain JWT provides no additional security properties.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;What are standard encryption algorithms used in JWE?&lt;/b&gt; Some common encryption algorithms include RSA-OAEP, AES-GCM, and ECDH-ES.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Is it safe to use JWE tokens for sensitive data?&lt;/b&gt; Yes, as long as proper security measures are taken, such as using robust encryption algorithms and protecting the encryption and decryption keys.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Can JWE be used with other JSON security standards?&lt;/b&gt; JWE can be combined with other JOSE, such as JWS, to support even more complex scenarios with nested JWTs.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>JWT vs OAuth 2.0: Understanding the Key Differences</title><link>https://www.janbrennenstuhl.eu/jwt-vs-oauth/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/jwt-vs-oauth/</guid><pubDate>Wed, 24 May 2023 00:00:00 +0200</pubDate><description>&lt;h2 id="tldr"&gt;TL;DR &lt;a class="heading-anchor" href="#tldr" aria-label="Link to section: TL;DR"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OAuth 2.0&lt;/strong&gt; is an open standard that describes an authorization framework. It allows a third-party application to access a user’s resources without user credentials.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JWT&lt;/strong&gt; (JSON Web Tokens) is a standard that describes a JSON-based token format used to securely transfer information between two parties across an insecure environment.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Combining OAuth 2.0 and JWT:&lt;/strong&gt; JWT can be integral to the &lt;a href="https://www.janbrennenstuhl.eu/topics/identity-authentication/" title="OAuth 2.0 in Action"&gt;OAuth 2.0 framework&lt;/a&gt; . In fact, JWT has often been used as the bearer token in OAuth 2.0 implementations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenID Connect (OIDC):&lt;/strong&gt; Modern authentication and authorization mechanisms leverage the OAuth 2.0 fundamentals with JWT tokens by following &lt;a href="https://www.janbrennenstuhl.eu/topics/identity-authentication/" title="OpenID Connect: Streamlining User Authentication &amp;amp; Identity"&gt;OpenID Connect&lt;/a&gt; protocols.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="introduction-to-jwt-vs-oauth-20"&gt;Introduction to JWT vs OAuth 2.0 &lt;a class="heading-anchor" href="#introduction-to-jwt-vs-oauth-20" aria-label="Link to section: Introduction to JWT vs OAuth 2.0"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most people encounter OAuth2 and JSON Web Tokens (JWT) in the context of authentication and authorization for web applications. While both concepts nowadays get used together, comparing &lt;strong&gt;OAuth2 vs JWT&lt;/strong&gt; is like comparing apples to kittens.&lt;/p&gt;
&lt;p&gt;10 years after the last update to the OAuth 2.0 Authorization Framework standard (&lt;a href="https://datatracker.ietf.org/doc/html/rfc6749" title="The OAuth 2.0 Authorization Framework" class="ext"&gt;RFC 6749&lt;/a&gt;) and over eight years after JSON Web Tokens got unleashed to the world, there is still a lot of confusion around these two widespread open standards among software engineers and security engineering novices. In this article, I will explain why comparisons like &lt;em&gt;&amp;ldquo;JWT vs OAuth 2.0&amp;rdquo;&lt;/em&gt; or questions like &lt;em&gt;&amp;ldquo;OAuth vs JWT which is best&amp;rdquo;&lt;/em&gt; make little sense.&lt;/p&gt;
&lt;h3 id="what-is-oauth2"&gt;What is OAuth2? &lt;a class="heading-anchor" href="#what-is-oauth2" aria-label="Link to section: What is OAuth2?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;OAuth2 is an open standard describing an authorization framework that allows a third-party application to access a user&amp;rsquo;s resources without giving them the user&amp;rsquo;s credentials. The keywords here are &lt;strong&gt;authorization protocol&lt;/strong&gt; and &lt;strong&gt;delegated access&lt;/strong&gt;. It does this by providing the concept of &lt;strong&gt;access tokens&lt;/strong&gt; that can be used by a client application to access protected resources (like an API) exposed by a resource server on behalf of the resource owner (a user). These opaque tokens are issued by an authorization server after the user grants permission to the third-party application.&lt;/p&gt;
&lt;h3 id="what-is-jwt"&gt;What is JWT? &lt;a class="heading-anchor" href="#what-is-jwt" aria-label="Link to section: What is JWT?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;On the other hand, the JWT standards describe a &lt;strong&gt;JSON-based token format&lt;/strong&gt; and how it can &lt;strong&gt;securely transfer information&lt;/strong&gt; between two parties across an insecure environment (like HTTP or HTTPS). Their multipart JSON format structure allows JWTs to carry &lt;strong&gt;custom claims&lt;/strong&gt; as payloads and additional cryptographic accessories. They are self-contained and usually occur in their JSON Web Signature form, signed with a secret key or public/private key pair. I wrote about &amp;ldquo;&lt;a href="https://www.janbrennenstuhl.eu/jwt-stateless-authentication/" title="The Purpose of JWT: Stateless Authentication"&gt;The Purpose of JWT&lt;/a&gt;&amp;rdquo; a few years ago.&lt;/p&gt;
&lt;h2 id="when-to-use-oauth-20-vs-when-to-use-jwt"&gt;When to Use OAuth 2.0 vs When to Use JWT &lt;a class="heading-anchor" href="#when-to-use-oauth-20-vs-when-to-use-jwt" aria-label="Link to section: When to Use OAuth 2.0 vs When to Use JWT"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Use OAuth 2.0 with HTTPS when authorizing third-party access.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;OAuth 2.0 is a protocol that allows users to grant limited access to resources on one site, such as Facebook, to another location or application, without sharing their credentials or giving them complete control over their account. It provides a secure way of authorizing third-party access to your resources by using access tokens in the form of bearer tokens.&lt;/p&gt;
&lt;p&gt;After the resource owner grants permission for the client application to access their resources using OAuth2, the responsible authorization server issues the proof of authentication. These tokens are then sent with each request made by the client application to the resource server, verifying them and granting or denying access based on the services requested and claims provided.&lt;/p&gt;
&lt;p&gt;Bearer tokens are a type of access token that can be used by arbitrary parties in possession of them to gain access to the protected resources they represent. They do not contain any cryptographic proof of authenticity other than possession itself, so they must be kept secret and transmitted securely.&lt;/p&gt;
&lt;p&gt;OAuth 2.0 is an excellent choice when you must permit controlled interaction between third-party applications or services managed by different entities or individuals with your system without compromising sensitive information or risking unauthorized access. This is possible through various security mechanisms such as opaque tokens, bearer tokens, identity servers, and refresh tokens.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use JWT when securely transmitting information between parties in a stateless form.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;JSON Web Tokens are basically use cases agnostic and can generally be used for securely transmitting information between parties in stateless form. It provides a simple way of representing claims (e.g., user identity, permissions) as JSON objects that can be signed and/or encrypted using industry-standard algorithms.&lt;/p&gt;
&lt;p&gt;JWTs are often used for transporting proof of authenticity across multiple domains or applications without storing session data on the server side, significantly contributing to performance. They are also helpful for implementing single sign-on (SSO) functionality, where a user logs in once and gains access to multiple applications or services without claiming their identity again. And this is basically where OAuth 2.0 and JWT touch on each other.&lt;/p&gt;
&lt;h2 id="combining-oauth-20-and-jwt-how-to-use-them-together"&gt;Combining OAuth 2.0 and JWT: How to Use Them Together &lt;a class="heading-anchor" href="#combining-oauth-20-and-jwt-how-to-use-them-together" aria-label="Link to section: Combining OAuth 2.0 and JWT: How to Use Them Together"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The apparent overlap between JWT and OAuth 2.0 springs from a misunderstanding of their distinct roles in digital communications. JWT can be an integral part of the OAuth 2.0 framework. In fact, JWT often serves as the bearer token in OAuth 2.0 implementations, becoming the vehicle by which authorization information is conveyed.&lt;/p&gt;
&lt;h3 id="jwt-as-bearer-token"&gt;JWT as Bearer Token &lt;a class="heading-anchor" href="#jwt-as-bearer-token" aria-label="Link to section: JWT as Bearer Token"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;JWTs can be used by an app as &lt;a href="https://www.rfc-editor.org/rfc/rfc6750" title="The OAuth 2.0 Authorization Framework: Bearer Token Usage (RFC)" class="ext"&gt;OAuth2 bearer tokens&lt;/a&gt; to enable stateless authentication and local authorization by a resource server to grant access to a protected resource.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bearer tokens are a type of token&lt;/strong&gt; that is widely used in authentication protocols like OAuth 2.0. They are used to grant access to protected resources, and they come in two types: access tokens and refresh tokens. While access tokens are short-lived, refresh tokens can be renewed, allowing users to maintain their session for an extended period.&lt;/p&gt;
&lt;p&gt;JWTs are often used in combination with OAuth 2.0 as a means of transmitting state and user data (claims) between the authorization server and the resource server. They can also be used for client-side authentication, where a JWT is issued by an &lt;strong&gt;identity provider&lt;/strong&gt; after successful login and then sent to the client application, which uses it to authenticate itself on behalf of the actual user with other services.&lt;/p&gt;
&lt;h3 id="advantages-of-using-jwt-with-oauth-20"&gt;Advantages of Using JWT with OAuth 2.0 &lt;a class="heading-anchor" href="#advantages-of-using-jwt-with-oauth-20" aria-label="Link to section: Advantages of Using JWT with OAuth 2.0"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One significant advantage of using JWT with OAuth 2.0 is eliminating the need for multiple tokens for different app purposes. One token can contain all the necessary information for authentication and authorization purposes.&lt;/p&gt;
&lt;p&gt;Another benefit can be improved performance through stateless authentication. Since &lt;a href="https://auth0.com/learn/json-web-tokens" title="Get Started with JSON Web Tokens" class="ext"&gt;JWT tokens&lt;/a&gt; are self-contained and signed with a secret key or public/private key pair, there is less reliance on external servers for validation and introspection. JWT is very suitable for stateless applications as they relieve the server side from the need to store any particular session data between requests from the clients.&lt;/p&gt;
&lt;p&gt;Instead, all necessary data is carried around within each JWT token itself, making it easy for clients and servers alike to verify its authenticity without looking up anything outside of it. This reduces the number of database lookups required during token verification, leading to faster response times, increased reliability due to fewer bottlenecks, and a potentially cleaner architecture.&lt;/p&gt;
&lt;h2 id="which-bearer-token-format-is-right-for-you"&gt;Which Bearer Token Format is Right for You? &lt;a class="heading-anchor" href="#which-bearer-token-format-is-right-for-you" aria-label="Link to section: Which Bearer Token Format is Right for You?"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Choosing the suitable OAuth 2.0 access token format can be a daunting task. Both &lt;strong&gt;stateful tokens&lt;/strong&gt; and &lt;strong&gt;stateless JWT&lt;/strong&gt; have their strengths and weaknesses. It ultimately depends on specific use cases, requirements, and infrastructural preconditions.&lt;/p&gt;
&lt;p&gt;Modern authentication and authorization mechanisms leverage the &lt;strong&gt;OAuth 2.0 fundamentals&lt;/strong&gt; together with JWT tokens by following &lt;strong&gt;OpenID Connect&lt;/strong&gt; (OIDC) protocols, which is an extension on top of OAuth 2.0 that introduces the concept of an identity provider (aka identity server) and uses JWTs instead of opaque tokens.&lt;/p&gt;
&lt;h2 id="jwt--oauth2--openid-connect-oidc"&gt;JWT + OAuth2 = OpenID Connect (OIDC) &lt;a class="heading-anchor" href="#jwt--oauth2--openid-connect-oidc" aria-label="Link to section: JWT &amp;#43; OAuth2 = OpenID Connect (OIDC)"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Big tech organizations such as Google, Facebook, and Microsoft are OIDC power users:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/identity/openid-connect/openid-connect" title="Google&amp;#39;s OAuth 2.0 APIs" class="ext"&gt;Google Identity uses OIDC&lt;/a&gt; and its identity token to transport user details.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.facebook.com/docs/facebook-login/guides/access-tokens/get-oidc" title="OIDC Tokens in Facebook Login" class="ext"&gt;Facebook also uses OIDC with JWTs&lt;/a&gt; in its Graph API authentication mechanism.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens" title="Microsoft identity platform access tokens" class="ext"&gt;Microsoft&amp;rsquo;s Azure Active Directory&lt;/a&gt; (AAD) also leverages the JWT token to implement OIDC.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether you choose classic OAuth 2.0 with opaque, non-JWT tokens, OAuth 2.0 with JWT bearer token, or OIDC, make sure you understand how these frameworks work under the hood, embrace their core concepts and get your implementation externally certified to ensure maximum security for your users&amp;rsquo; data while also providing seamless access to your application&amp;rsquo;s features and resources. The better way, however, is to outsource the authentication to Google, Microsoft, Okta, or someone else and let them deal with all the nifty little details in these specifications.&lt;/p&gt;
&lt;h2 id="conclusion-choosing-between-jwt-and-oauth2"&gt;Conclusion: Choosing Between JWT and OAuth2 &lt;a class="heading-anchor" href="#conclusion-choosing-between-jwt-and-oauth2" aria-label="Link to section: Conclusion: Choosing Between JWT and OAuth2"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Combining OAuth 2.0 and JWT can give you the best of both worlds. OpenID Connect is built on both open standards, embracing OAuth 2.0 concepts to &lt;strong&gt;delegate access with external services&lt;/strong&gt; while using JWT as a bearer to &lt;strong&gt;transport claims from the authorization server&lt;/strong&gt; to resource servers for stateless authorization.&lt;/p&gt;
&lt;p&gt;JWTs allow client-side introspection of ID tokens, enable resource server serving APIs to verify access tokens locally, and even be used as refresh tokens. Although slightly controversial, JSON web tokens are versatile and can be used &lt;a href="https://www.janbrennenstuhl.eu/single-use-jwt/" title="Single-Use JWT: The Power of Stateless One Time Token"&gt;as one-time token&lt;/a&gt; (OTT).&lt;/p&gt;</description></item><item><title>Where do OpenID Connect implementations break?</title><link>https://www.janbrennenstuhl.eu/knowledge-base/oidc/openid-connect-security/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/knowledge-base/oidc/openid-connect-security/</guid><pubDate>Mon, 15 May 2023 00:00:00 +0200</pubDate><description>&lt;p&gt;&lt;em&gt;Latest change (2026-10-13): Rewritten as a field-guide entry: question title, short answer, key findings and evidence table. Study summaries kept and extended with numbers from the thesis abstract.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; Implementations break mostly where tokens and redirects get checked. Documented attacks on relying parties include token substitution, key confusion and replay, and attacks on providers include redirect URI manipulation, PKCE downgrade and sub claim spoofing. Certification doesn&amp;rsquo;t rule these out, as a 2020 lab analysis of OpenID Certified implementations disclosed 12 flaws.&lt;/p&gt;&lt;h2 id="key-findings"&gt;Key findings &lt;a class="heading-anchor" href="#key-findings" aria-label="Link to section: Key findings"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class="finding" id="f-oidc-certified-12-flaws"&gt;
&lt;blockquote&gt;&lt;p&gt;Testing 6 OpenID Certified identity providers and 8 service providers against 11 service provider attacks and 7 identity provider attacks uncovered 12 implementation flaws.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.nds.ruhr-uni-bochum.de/media/ei/arbeiten/2021/05/03/masterthesis.pdf" class="ext"&gt;&lt;cite&gt;Fries, Security Analysis of Real-Life OpenID Connect Implementations (Master&amp;#39;s thesis, Ruhr-University Bochum, 2020)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-oidc-certified-12-flaws" title="#f-oidc-certified-12-flaws"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Testing 6 OpenID Certified identity providers and 8 service providers against 11 service provider attacks and 7 identity provider attacks uncovered 12 implementation flaws." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/oidc/openid-connect-security/#f-oidc-certified-12-flaws" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/oidc/openid-connect-security/f-oidc-certified-12-flaws.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-oidc-spec-flaws"&gt;
&lt;blockquote&gt;&lt;p&gt;Mladenov and Mainka classify session overwriting and IdP confusion as flaws in the OpenID Connect specification itself, separate from implementation bugs.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.nds.ruhr-uni-bochum.de/media/ei/veroeffentlichungen/2017/01/13/OIDCSecurity_1.pdf" class="ext"&gt;&lt;cite&gt;Mladenov and Mainka, OpenID Connect Security Considerations (Ruhr-University Bochum, 2017)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-oidc-spec-flaws" title="#f-oidc-spec-flaws"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Mladenov and Mainka classify session overwriting and IdP confusion as flaws in the OpenID Connect specification itself, separate from implementation bugs." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/oidc/openid-connect-security/#f-oidc-spec-flaws" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/oidc/openid-connect-security/f-oidc-spec-flaws.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-oidc-attacker-needs-no-network"&gt;
&lt;blockquote&gt;&lt;p&gt;The attacks in the OpenID Connect Security Considerations report work for a web attacker who sends ordinary HTTP requests and has no control over the network.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.nds.ruhr-uni-bochum.de/media/ei/veroeffentlichungen/2017/01/13/OIDCSecurity_1.pdf" class="ext"&gt;&lt;cite&gt;Mladenov and Mainka, OpenID Connect Security Considerations (Ruhr-University Bochum, 2017)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-oidc-attacker-needs-no-network" title="#f-oidc-attacker-needs-no-network"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="The attacks in the OpenID Connect Security Considerations report work for a web attacker who sends ordinary HTTP requests and has no control over the network." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/oidc/openid-connect-security/#f-oidc-attacker-needs-no-network" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/oidc/openid-connect-security/f-oidc-attacker-needs-no-network.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="evidence"&gt;Evidence &lt;a class="heading-anchor" href="#evidence" aria-label="Link to section: Evidence"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="table-scroll studies" tabindex="0" role="region" aria-label="OpenID Connect security studies"&gt;&lt;table&gt;
&lt;caption&gt;OpenID Connect security studies&lt;/caption&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th scope="col"&gt;Study&lt;/th&gt;&lt;th scope="col"&gt;Year&lt;/th&gt;&lt;th scope="col"&gt;Sample&lt;/th&gt;&lt;th scope="col"&gt;Method&lt;/th&gt;&lt;th scope="col"&gt;Finding&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.nds.ruhr-uni-bochum.de/media/ei/arbeiten/2021/05/03/masterthesis.pdf" class="ext"&gt;Security Analysis of Real-Life OpenID Connect Implementations&lt;/a&gt;&lt;span class="org"&gt;Ruhr-University Bochum&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2020&lt;/td&gt;&lt;td&gt;6 identity providers, 8 service providers&lt;/td&gt;&lt;td&gt;Docker lab with PrOfESSOS, automatic and manual tests&lt;/td&gt;&lt;td&gt;18 attack types tested; 12 implementation flaws disclosed.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.nds.ruhr-uni-bochum.de/media/ei/veroeffentlichungen/2017/01/13/OIDCSecurity_1.pdf" class="ext"&gt;OpenID Connect Security Considerations&lt;/a&gt;&lt;span class="org"&gt;Ruhr-University Bochum&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2017&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Technical report on specification and implementation flaws&lt;/td&gt;&lt;td&gt;Catalogues attacks on clients and providers with defence recommendations.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id="what-to-do"&gt;What to do &lt;a class="heading-anchor" href="#what-to-do" aria-label="Link to section: What to do"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="for-engineers"&gt;For engineers &lt;a class="heading-anchor" href="#for-engineers" aria-label="Link to section: For engineers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;On the relying party:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Validate every &lt;a class="term" href="https://www.janbrennenstuhl.eu/glossary/#id-token"&gt;ID token&lt;/a&gt;: signature with a key from the expected issuer&amp;rsquo;s key set, algorithm, issuer, audience, expiry and nonce. Signature manipulation, key confusion, token recipient confusion and replay attacks all exploit a missing check. My essays on &lt;a href="https://www.janbrennenstuhl.eu/jwks/"&gt;JWKS&lt;/a&gt; and &lt;a href="https://www.janbrennenstuhl.eu/jwt-stateless-authentication/"&gt;the purpose of JWT&lt;/a&gt; cover the token side.&lt;/li&gt;
&lt;li&gt;Bind each login to the browser session that started it, and remember which identity provider you sent the user to. Session overwriting and IdP confusion exploit clients that don&amp;rsquo;t.&lt;/li&gt;
&lt;li&gt;Identify users by issuer and subject together, never by subject or email alone.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the OpenID provider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compare redirect URIs exactly against the registered values.&lt;/li&gt;
&lt;li&gt;Enforce &lt;a class="term" href="https://www.janbrennenstuhl.eu/glossary/#pkce"&gt;&lt;abbr title="Proof Key for Code Exchange"&gt;PKCE&lt;/abbr&gt;&lt;/a&gt; for clients that started with it, so an attacker can&amp;rsquo;t downgrade the flow.&lt;/li&gt;
&lt;li&gt;Accept each authorization code once and only from the client it was issued to.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="for-product-and-ux"&gt;For product and UX &lt;a class="heading-anchor" href="#for-product-and-ux" aria-label="Link to section: For product and UX"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Treat &amp;ldquo;OpenID Certified&amp;rdquo; as a conformance signal, not a security audit. Fries tested certified implementations and still disclosed 12 flaws. When you choose a library or vendor, ask for penetration test results that cover these attack classes.&lt;/li&gt;
&lt;li&gt;If your product offers several identity providers, show users which one they&amp;rsquo;re signing in with. IdP confusion attacks rely on the client mixing them up.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-studies-in-detail"&gt;The studies in detail &lt;a class="heading-anchor" href="#the-studies-in-detail" aria-label="Link to section: The studies in detail"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="security-analysis-of-real-life-openid-connect-implementations"&gt;Security Analysis of Real-Life OpenID Connect Implementations &lt;a class="heading-anchor" href="#security-analysis-of-real-life-openid-connect-implementations" aria-label="Link to section: Security Analysis of Real-Life OpenID Connect Implementations"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In this Master&amp;rsquo;s thesis from December 2020, Christian Fries presents a Docker-based lab environment for developers and penetration testers. The lab helps to find security flaws in real-world OpenID Connect Certified service provider and identity provider implementations, and it includes the PrOfESSOS tool for automatic tests. Fries selected 6 identity providers and 8 service providers that support the implicit and hybrid flows. He tested them against 11 service provider attacks and 7 identity provider attacks and disclosed 12 implementation flaws to the developers.&lt;/p&gt;
&lt;p&gt;The thesis also describes common threats and attack scenarios. These include single- and cross-phase attacks on relying parties, like token substitution, key confusion and replay attacks. It also covers attacks on OpenID providers, like message flow confusion, PKCE downgrade and sub claim spoofing.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.nds.ruhr-uni-bochum.de/media/ei/arbeiten/2021/05/03/masterthesis.pdf" class="ext"&gt;Read the paper (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="openid-connect-security-considerations"&gt;OpenID Connect Security Considerations &lt;a class="heading-anchor" href="#openid-connect-security-considerations" aria-label="Link to section: OpenID Connect Security Considerations"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In this 2017 technical report, Vladislav Mladenov and Christian Mainka from Ruhr-University Bochum look at OpenID Connect specification flaws and implementation issues that open up attack vectors. They outline attack scenarios like session overwriting, redirect URI manipulation and token recipient confusion, and give recommendations for defending against them.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.nds.ruhr-uni-bochum.de/media/ei/veroeffentlichungen/2017/01/13/OIDCSecurity_1.pdf" class="ext"&gt;Read the paper (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="related"&gt;Related &lt;a class="heading-anchor" href="#related" aria-label="Link to section: Related"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/step-up-authentication/"&gt;Step-up authentication with OpenID Connect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/"&gt;How do attackers take over accounts?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/glossary/"&gt;Glossary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Step-Up Authentication: Elevating Security with OpenID Connect (OIDC)</title><link>https://www.janbrennenstuhl.eu/step-up-authentication/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/step-up-authentication/</guid><pubDate>Sun, 14 May 2023 00:00:00 +0200</pubDate><description>&lt;p&gt;Security measures are effective when they cause the least friction while providing the highest level of security necessary for the targeted, user-friendly business process. Asking for too little gives users (or whoever is posing as them) too much freedom, but asking for too much, especially up front, generates obtrusive friction.&lt;/p&gt;
&lt;p&gt;Minimal friction is essential to success, especially in conversion-sensitive flows like sales funnels. Services or apps are meant to be simple to access, and customers who want to utilize a product or purchase within as little time as possible may do so with as little friction. Making authentication even slightly more complicated risks alienating prospective customers.&lt;/p&gt;
&lt;h2 id="what-is-step-up-authentication"&gt;What is Step-Up Authentication? &lt;a class="heading-anchor" href="#what-is-step-up-authentication" aria-label="Link to section: What is Step-Up Authentication?"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Step-up authentication is one way of balancing friction and security that has received much attention and application in recent years. Step-up authentication ensures that users can access specific resources or execute the most typical actions with a single set of credentials. Users will be prompted for additional authentication factors when requesting to access sensitive resources or initiating privileged operations.&lt;/p&gt;
&lt;h3 id="the-rationale-behind-step-up-authentication"&gt;The Rationale Behind Step-Up Authentication &lt;a class="heading-anchor" href="#the-rationale-behind-step-up-authentication" aria-label="Link to section: The Rationale Behind Step-Up Authentication"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Step-up authentication aims to tailor identity requests to the value of the resource and the local risk level and anticipated impact if it is compromised. By enabling risk-based authentication, step-up authentication allows organizations to provide easy access to one tier of non-critical resources while providing secure access to another.&lt;/p&gt;
&lt;p&gt;As a result, security stays out of the way most of the time and only intervenes when further proofs of authenticity are absolutely required. This makes authentication work for both organizations and customers since both can be certain that their most sensitive resources are safe and secure.&lt;/p&gt;
&lt;p&gt;It also opens new ways to conduct authorization by allowing organizations to privilege access for paying users.&lt;/p&gt;
&lt;h3 id="step-up-authentication-vs-single-factor-authentication"&gt;Step-Up Authentication vs Single-Factor Authentication &lt;a class="heading-anchor" href="#step-up-authentication-vs-single-factor-authentication" aria-label="Link to section: Step-Up Authentication vs Single-Factor Authentication"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Although ubiquitous, single-factor authentication (SFA) frequently falls short of offering adequate security against common identity attacks. This traditional approach, which usually requires only a username and password, is widely regarded as insufficient due to its susceptibility to breaches ranging from brute-force attacks like &lt;a href="https://www.janbrennenstuhl.eu/password-spraying/" title="What is Password Spraying, How It Works &amp;amp; How to Prevent It"&gt;password spaying&lt;/a&gt; to phishing schemes.&lt;/p&gt;
&lt;p&gt;In contrast, step-up authentication provides a more dynamic and context-sensitive security barrier. Instead of depending on a single, static layer of protection, it adjusts to changing risk levels by providing additional verification steps as needed. Step-up authentication provides a more sophisticated and scalable approach to security, delivering a higher level of protection without losing user convenience under normal conditions.&lt;/p&gt;
&lt;h3 id="step-up-authentication-vs-multi-factor-authentication"&gt;Step-Up Authentication vs Multi-Factor Authentication &lt;a class="heading-anchor" href="#step-up-authentication-vs-multi-factor-authentication" aria-label="Link to section: Step-Up Authentication vs Multi-Factor Authentication"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In many security-conscious environments, multi-factor authentication (MFA) has become the gold standard, requiring users to present a second factor (or multiple authentication factors) to access their online accounts. While MFA considerably improves security over single-factor authentication, it may cause user annoyance, particularly if additional verification steps are required for every login or transaction, regardless of the associated risk.&lt;/p&gt;
&lt;p&gt;Step-up authentication is a flexible form of multifactor authentication, adding additional security layers only when necessary, such as during high-risk transactions or unusual account activity. This method ensures essential security requirements and improves the user experience by reducing unnecessary disruptions.&lt;/p&gt;
&lt;h3 id="step-up-authentication-vs-adaptive-authentication"&gt;Step-Up Authentication vs Adaptive Authentication &lt;a class="heading-anchor" href="#step-up-authentication-vs-adaptive-authentication" aria-label="Link to section: Step-Up Authentication vs Adaptive Authentication"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Adaptive authentication, like step-up authentication, is a more intelligent, context-aware approach to account security. It dynamically increases the level of necessary user authentication based on a risk assessment of each individual login or access attempt, considering parameters like geolocation (e.g., impossible travel), &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/" title="Reinforced Authentication: Studies Redefine Account Security"&gt;IP reputation, device characteristics, and behavior patterns&lt;/a&gt;, or user&amp;rsquo;s risk profile.&lt;/p&gt;
&lt;p&gt;However, there is a subtle distinction between the two. While responding to perceived risks, step-up authentication often initiates additional authentication processes in predetermined conditions and based on static risk assessments, such as when a user attempts a high-value transaction.&lt;/p&gt;
&lt;p&gt;In contrast, adaptive authentication uses advanced risk analysis algorithms, sometimes powered by artificial intelligence or machine learning, to assess the need for extra real-time authentication steps. While both give a more personalized and responsive approach to security compared to previous static techniques, Adaptive Authentication provides a more granular and automated risk assessment, possibly providing a higher level of protection and user experience when applied successfully.&lt;/p&gt;
&lt;h2 id="how-step-up-authentication-works"&gt;How Step-Up Authentication Works &lt;a class="heading-anchor" href="#how-step-up-authentication-works" aria-label="Link to section: How Step-Up Authentication Works"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Step-up authentication generally requires multiple stages of verification. When a user initiates an action that requires enhanced security, such as accessing confidential documents or conducting financial transactions, the system prompts the user for multi-factor authentication. This step up can manifest itself in a variety of ways, including, but not limited to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Two-Factor Authentication (2FA)&lt;/strong&gt; – To verify a user&amp;rsquo;s authenticity, this method combines something the user knows (e.g., a password) with something the user owns (possession factor), such as a unique code generated by a mobile app.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Biometric Authentication&lt;/strong&gt; – Biometric authentication delivers high security and convenience for users by using unique biological traits (inherence factor) such as fingerprints, facial recognition, or iris scans.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="implementing-step-up-authentication"&gt;Implementing Step-Up Authentication &lt;a class="heading-anchor" href="#implementing-step-up-authentication" aria-label="Link to section: Implementing Step-Up Authentication"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In traditional authentication systems, step-up authentication was handled by integrating the relevant business logic within the web applications. Custom engineering efforts and heterogeneous implementations could have used more resources by neglecting to reuse well-tested code and incurring ongoing maintenance costs. Still, they also increased the possibility of security flaws.&lt;/p&gt;
&lt;p&gt;Since federation protocols like OpenID Connect (OIDC) are becoming increasingly popular for modern applications that want to improve security by relying on a reliable identity provider, there are also better, standardized options for implementing step-up authentication.&lt;/p&gt;
&lt;h3 id="step-up-authentication-with-openid-connect"&gt;Step-up Authentication with OpenID Connect &lt;a class="heading-anchor" href="#step-up-authentication-with-openid-connect" aria-label="Link to section: Step-up Authentication with OpenID Connect"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;OIDC is &lt;a href="https://openid.net/specs/openid-connect-core-1_0.html" title="OpenID Connect Specification" class="ext"&gt;an open standard&lt;/a&gt; with built-in support for relying parties (RP) that require more potent authentication methods (AMR) to be used depending on the authentication context classes. Because conventional federation protocols such as OIDC are business context agnostic and do not track every user interaction, business apps must initiate step-up scenarios independently.&lt;/p&gt;
&lt;h3 id="forced-re-authentication-methods"&gt;Forced Re-Authentication Methods &lt;a class="heading-anchor" href="#forced-re-authentication-methods" aria-label="Link to section: Forced Re-Authentication Methods"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Following successful authentication, IdPs frequently provide long-running login sessions bound to user agents. The goal is to eliminate consumer friction by removing the need for regular active credential authentication. However, depending on an RP’s local risk assessment, certain business operations may require the most recent functional proof of authenticity check to be no more than a particular period old.&lt;/p&gt;
&lt;p&gt;Relying parties use the optional authentication request variable &lt;code&gt;max_age&lt;/code&gt; to communicate session age expectations to an IdP service. OIDC-compliant IdPs ensure that all session age requirements are met by requiring authentication as needed.&lt;/p&gt;
&lt;figure class="code" data-lang="bash"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" aria-label="Code (bash)" class="chroma"&gt;&lt;code data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /authorize?
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;response_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;code
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;openid%20profile%20email
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;client_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;s6BhdRkqt3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;af0ifjsldkj
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;redirect_uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https%3A%2F%2Fclient.example.org%2Fcb
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;max_age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;300&lt;/span&gt; HTTP/1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host: server.example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Requiring re-authentication of existing sessions every time a user attempts to access sensitive information or protected areas of an application adds friction to the user experience. Session elevation can be used to successfully achieve a balance between a smooth user experience and security considerations.&lt;/p&gt;
&lt;p&gt;The authentication context class concept allows apps to build such scenarios and coordinate with an identity provider (IdP) for smooth step-up service in a declarative policy-driven method.&lt;/p&gt;
&lt;h3 id="authentication-context-class-reference-acr"&gt;Authentication Context Class Reference (ACR) &lt;a class="heading-anchor" href="#authentication-context-class-reference-acr" aria-label="Link to section: Authentication Context Class Reference (ACR)"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The optional authentication request parameter &lt;code&gt;acr_values&lt;/code&gt; is a space-separated list of ACRs that determines the client application’s minimum degree of authentication. If the parameter is present, the IdP takes all measures necessary to verify and match the requested class. Users may be asked to re-authenticate using additional or different authentication methods to achieve this objective.&lt;/p&gt;
&lt;p&gt;The authentication context class met by the completed identity authentication is returned as the ACR claim value within the provided identity token, which can then be utilized for authorized purposes by the RP.&lt;/p&gt;
&lt;p&gt;ACR values and their semantics must be established, aligned, and documented between IdP and RPs out of the band. Only then business owners effectively employ them to precisely determine what ACR relates to the local risk assessment of their specific business operations.&lt;/p&gt;
&lt;h3 id="authentication-level-elevation"&gt;Authentication Level Elevation &lt;a class="heading-anchor" href="#authentication-level-elevation" aria-label="Link to section: Authentication Level Elevation"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Access to sensitive information and operations must be logged appropriately and authorized by resource servers. Verifying the validity of the provided bearer token is required to ensure that a client is eligible to undertake a specific operation.&lt;/p&gt;
&lt;p&gt;The goal of session authentication and assurance level elevation is to provide a relatively seamless user experience by maintaining a minimum level of assurance for a user session when the user first authenticates to the application and then raising their authenticity levels based on local risk assessments:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Assuming that a user successfully established a session after &lt;a href="https://www.janbrennenstuhl.eu/password-manager-friendly/" title="How to Make Your Login Forms Password-Manager Friendly"&gt;logging in with a username and password&lt;/a&gt; and now attempts to access a sensitive resource, they are prompted to apply extra authentication factors.&lt;/li&gt;
&lt;li&gt;The session is upgraded to a higher assurance level after a successful step-up using an additional authentication method.&lt;/li&gt;
&lt;li&gt;Because their session is already at the raised authentication levels, no extra authentication challenge will be prompted the next time users enter the sensitive section within the specified duration.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="code" data-lang="bash"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" aria-label="Code (bash)" class="chroma"&gt;&lt;code data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /authorize?
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;response_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;code
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;openid%20profile%20email
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;client_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;s6BhdRkqt3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;af0ifjsldkj
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;redirect_uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https%3A%2F%2Fclient.example.org%2Fcb
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;acr_values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mfa
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;max_age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;300&lt;/span&gt; HTTP/1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host: server.example.com&lt;span class="err"&gt;\&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="heading-anchor" href="#conclusion" aria-label="Link to section: Conclusion"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Step-up authentication aims to adapt authentication requirements to the significance associated with a resource and the level of risk if it is exposed. It is one way to strike a balance between friction and security by allowing customers to continue using already known, established, and understood authentication concepts (username and password, for example) to access regular resources while prompting them for additional proof of authenticity and a different form of two-step authentication (such as confirmation via email or push notifications) in the context of more sensitive business operations (such as financial transactions or accessing sensitive data).&lt;/p&gt;
&lt;p&gt;Enabling session authentication level elevation and step-up authentication can resolve the target conflict of providing customers with a smooth experience on the one hand and enforcing more significant security standards for specified operations or resources on the other.&lt;/p&gt;
&lt;h2 id="frequently-asked-questions-faqs"&gt;Frequently Asked Questions (FAQs) &lt;a class="heading-anchor" href="#frequently-asked-questions-faqs" aria-label="Link to section: Frequently Asked Questions (FAQs)"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="what-are-the-minimum-requirements-to-implement-step-up-authentication"&gt;What are the minimum requirements to implement Step-Up Authentication? &lt;a class="heading-anchor" href="#what-are-the-minimum-requirements-to-implement-step-up-authentication" aria-label="Link to section: What are the minimum requirements to implement Step-Up Authentication?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;First and foremost, a reliable and secure primary authentication mechanism, such as a secure password system or biometric identification method, is essential. Second, an additional authentication method, such as text message verification, email confirmation codes, security questions, or biometric checks, must be available and compatible with the user base.&lt;/p&gt;
&lt;p&gt;The user’s technological capabilities and the amount of security required to determine which to utilize. Third, an effective risk assessment system must be established to detect circumstances requiring more verification. Finally, to support all the complex procedures involved in step-up authentication, an IT infrastructure that is both adaptable and secure is necessary.&lt;/p&gt;
&lt;h3 id="how-does-step-up-authentication-improve-user-experience"&gt;How does Step-Up Authentication improve user experience? &lt;a class="heading-anchor" href="#how-does-step-up-authentication-improve-user-experience" aria-label="Link to section: How does Step-Up Authentication improve user experience?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Step-up authentication is intended to improve the user experience by requiring further verification only when necessary. Step-up authentication, as opposed to standard static multi-factor authentication, which requires additional steps every time a user signs in or performs specific actions, only increases security measures in the context of higher-risk activities.&lt;/p&gt;
&lt;p&gt;This means that for most ordinary actions, consumers may enjoy a frictionless, seamless experience without being burdened by additional security precautions. However, when it comes to more sensitive procedures, such as changing personal information or completing large transactions, consumers can welcome the added degree of protection, knowing their accounts and data are secure.&lt;/p&gt;
&lt;h3 id="how-can-step-up-authentication-prevent-data-breaches"&gt;How can Step-Up Authentication prevent data breaches? &lt;a class="heading-anchor" href="#how-can-step-up-authentication-prevent-data-breaches" aria-label="Link to section: How can Step-Up Authentication prevent data breaches?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Step-up authentication is a powerful technique that adds complexity and layers to the authentication process. Step-up authentication adapts to the perceived risk level of a user’s activity. This means that even if an attacker successfully steals or guesses a user’s primary credentials, they will still face additional, often unanticipated, obstacles before getting access. Many cyberattacks are deterred by this since it considerably increases the work and skill required to compromise an account.&lt;/p&gt;</description></item><item><title>Passwordless: Critical Notes on FIDO2 Passkeys</title><link>https://www.janbrennenstuhl.eu/fido-passkeys/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/fido-passkeys/</guid><pubDate>Mon, 08 May 2023 00:00:00 +0200</pubDate><description>&lt;p&gt;Passkeys are currently on everyone’s lips, thanks to recent announcements to enable Passkeys for authentication on Google accounts. And, while the passwordless hype train did not stop in front of my desk either, there are some problems surrounding the imminent password killer, disregarded mainly by the relatively uncritical media coverage. In this essay, I&amp;rsquo;ll consider some of the biggest concerns.&lt;/p&gt;
&lt;p&gt;I briefly mentioned Passkeys in my recent piece about &lt;a href="https://www.janbrennenstuhl.eu/passwordless-authentication/" title="Passwordless Authentication: The Future of Cybersecurity"&gt;passwordless authentication&lt;/a&gt;, so I&amp;rsquo;ll keep this introduction brief. Let&amp;rsquo;s get started!&lt;/p&gt;
&lt;h2 id="introduction-to-fido2--passkeys"&gt;Introduction to FIDO2 &amp;amp; Passkeys &lt;a class="heading-anchor" href="#introduction-to-fido2--passkeys" aria-label="Link to section: Introduction to FIDO2 &amp;amp; Passkeys"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The FIDO Alliance developed FIDO2 as an open standard that enables secure and user-friendly passwordless authentication. One of FIDO2&amp;rsquo;s key goals is to provide passwordless authentication, removing the need for users to remember and manage multiple passwords. &lt;a href="https://fidoalliance.org/members/" class="ext"&gt;Members of the FIDO Alliance&lt;/a&gt; include the whole Big Tech ecosystem, from 1Password through Amazon, Apple, Google, Meta, and Microsoft, as well as Yahoo and Yubico.&lt;/p&gt;
&lt;h3 id="phishing-resistant-passwordless-authentication"&gt;Phishing-resistant Passwordless Authentication &lt;a class="heading-anchor" href="#phishing-resistant-passwordless-authentication" aria-label="Link to section: Phishing-resistant Passwordless Authentication"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://media.fidoalliance.org/wp-content/uploads/2022/03/How-FIDO-Addresses-a-Full-Range-of-Use-Cases-March24.pdf" class="ext"&gt;The FIDO master plan&lt;/a&gt; is to turn every mobile phone into a phishing-resistant, roaming authenticator by augmenting the FIDO WebAuthn specs with a protocol that uses Bluetooth to communicate between the FIDO authenticator (a mobile phone) and the device from which a user is attempting to authenticate. Specialized security keys (hardware tokens like YubiKeys) will be rendered obsolete.&lt;/p&gt;
&lt;p&gt;The term &lt;em&gt;&amp;ldquo;Passkeys&amp;rdquo;&lt;/em&gt; refers to the credentials used in this authentication procedure based on cryptographic concepts. Passkeys for FIDO2 allow users to authenticate themselves without entering a &lt;a href="https://www.janbrennenstuhl.eu/max-password-length/" title="Password Length Recommendation: The Ultimate Guide to Strong Passwords"&gt;long password&lt;/a&gt;, lowering the risk of password-related security breaches.&lt;/p&gt;
&lt;h3 id="public-key-cryptography"&gt;Public-Key Cryptography &lt;a class="heading-anchor" href="#public-key-cryptography" aria-label="Link to section: Public-Key Cryptography"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Unlike many other passwordless login approaches, FIDO2 Passkeys provide a robust authentication mechanism immune to phishing attacks, man-in-the-middle, and replay attacks. This is accomplished through public-key cryptography, a cryptographic technique that employs two keys: a public key and a private key.&lt;/p&gt;
&lt;p&gt;Data is encrypted using the public key and decrypted using the private key. In FIDO2 authentication, the private key is securely maintained on the user’s device, while the public key is registered with the online service. The Passkeys protocol defines proof of possession challenges that allow holders of a public key to verify whether the authenticating actor owns the corresponding private key (possession factor). This is a more secure solution than traditional password-based authentication methods (knowledge factor) in most end-user use cases.&lt;/p&gt;
&lt;p&gt;Even if your favorite e-commerce site or platform is compromised, malicious actors will only have access to the public component of your key pair, which they will find absolutely useless.&lt;/p&gt;
&lt;h3 id="biometrics"&gt;Biometrics &lt;a class="heading-anchor" href="#biometrics" aria-label="Link to section: Biometrics"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now that the most essential authentication proof is stored on a mobile device, FIDO experts anticipate that Big Tech companies will protect access to the private keys as they protect screen lock, with biometric authentication incorporated into the user’s personal device OS. Using Face ID, Touch ID, or any other equivalent facial recognition or fingerprint scanning technology on a Microsoft or Android device to gain access to the valuable private key material, which is then used to sign in with a relying party, effectively results in a multi-factor authentication (MFA) process, combining an inherence factor and a possession factor.&lt;/p&gt;
&lt;h2 id="passkeys-controversies"&gt;Passkeys Controversies &lt;a class="heading-anchor" href="#passkeys-controversies" aria-label="Link to section: Passkeys Controversies"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="possession--biometrics-over-knowledge"&gt;Possession &amp;amp; Biometrics over Knowledge &lt;a class="heading-anchor" href="#possession--biometrics-over-knowledge" aria-label="Link to section: Possession &amp;amp; Biometrics over Knowledge"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The most crucial conceptual objective of Passkeys is to shift the broad consumer market away from knowledge-based authentication systems and toward possession-based authentication systems. Although this is undoubtedly a quantum leap forward in account security, far-reaching repercussions may still need to be fully recognized.&lt;/p&gt;
&lt;p&gt;For example, something only you know cannot be taken away as quickly as something physical that you own. A secret in someone&amp;rsquo;s head cannot be found anyplace else and can only be gained from that individual. Of course, there&amp;rsquo;s blackmailing, &lt;em&gt;&amp;ldquo;rubber-hose cryptanalysis,&amp;rdquo;&lt;/em&gt; and other methods, but these appear to take much more effort than merely having access to an unlocked cellphone.&lt;/p&gt;
&lt;p&gt;Losing that knowledge component makes you more vulnerable to police seizures of electronics and keys, for example. Forcing someone to give up a password is considered a violation of the Fifth Amendment to the United States Constitution by courts in the United States. However, forcing someone to unlock biometrically secured devices is entirely legal. A similar situation might exist in other jurisdictions as well.&lt;/p&gt;
&lt;p&gt;While the combination of possession- and inherence factors that FIDO Passkeys promise provides a significant convenience advantage over password-based authentication methods, they appear less effective against close-proximity, physical attacks.&lt;/p&gt;
&lt;h3 id="device-lock-in"&gt;Device Lock-in &lt;a class="heading-anchor" href="#device-lock-in" aria-label="Link to section: Device Lock-in"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Possession-based systems, in general, rely on tangible items that can be misplaced, stolen, or damaged, potentially locking users out of their accounts.&lt;/p&gt;
&lt;p&gt;The FIDO Alliance anticipates that FIDO authenticator providers, particularly influential organizations who embed FIDO authenticators within their operating systems, will make the Passkeys consumer market usable by overcoming the difficulty of making FIDO credentials multi-device available.&lt;/p&gt;
&lt;p&gt;Of course, for all of this to function, you&amp;rsquo;ll need a reliable, modern computer or phone. This means owning a current iPhone, Pixel, or computer that supports Windows Hello, Apple Touch ID, or other biometrics. You also need multiple devices because you are only safe against single device failure if you have a backup device.&lt;/p&gt;
&lt;p&gt;Passkeys are likely to be risky to use, if not utterly inaccessible to the poor, underprivileged, or anyone who does not own or operate their own devices.&lt;/p&gt;
&lt;h3 id="vendor-lock-in"&gt;Vendor Lock-in &lt;a class="heading-anchor" href="#vendor-lock-in" aria-label="Link to section: Vendor Lock-in"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Vendor lock-in shouldn&amp;rsquo;t be necessary by design, but it may be in reality. Even the FIDO Alliance does not guarantee interoperability when syncing the cryptographic keys of FIDO credentials between devices from different vendors. This is where the additional cross-device authentication Bluetooth protocol comes into play because FIDO believes that users will always have another (backup?) device nearby with all the necessary Passkeys.&lt;/p&gt;
&lt;p&gt;This is at least a partial vendor lock-in and disregards the reality of life for many individuals outside of Silicon Valley.&lt;/p&gt;
&lt;h3 id="proprietary-only"&gt;Proprietary-only &lt;a class="heading-anchor" href="#proprietary-only" aria-label="Link to section: Proprietary-only"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The FIDO Passkey standard deliberately excludes any explicit vendor agnosticism. Implementations still heavily rely on proprietary software embedded into Apple, Google, Microsoft, and others&amp;rsquo; devices and solutions. The general strategy results in Big Tech creating and overseeing the key storage. There are no OSS implementations for creating and exchanging keys yet.&lt;/p&gt;
&lt;p&gt;As a result, the Passkey concept pushes data ownership one step closer to the Big Tech industry. Taking another vital element of informational self-determination out of the hands of end users by favoring possession- and biometric-based authentication factors over something that is actually available solely to the user is an intentional feature of Passkey rather than a flaw.&lt;/p&gt;
&lt;h3 id="100-trust-in-big-tech"&gt;100% Trust in Big Tech &lt;a class="heading-anchor" href="#100-trust-in-big-tech" aria-label="Link to section: 100% Trust in Big Tech"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Although FIDO specifies &lt;a href="https://fidoalliance.org/fido-authentication/privacy-principles/" class="ext"&gt;privacy principles&lt;/a&gt; that must be followed in designing and implementing FIDO authenticators, clients, and servers, it is still determined how strictly these guiding principles will be enforced and by whom.&lt;/p&gt;
&lt;p&gt;The fact that Passkeys is strengthening the need to trust massive tech corporations, whose business model frequently entails selling data and information, is critical. Having FIDO credentials, which basically log end-users into every service they use while vowing not to do evil with them, necessitates some level of trust by the users.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="heading-anchor" href="#conclusion" aria-label="Link to section: Conclusion"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;FIDO2 Passkeys provide a passwordless authentication solution that is secure, user-friendly, and scalable. Unlike passwords, they provide increased protection against common threats and a better user experience for those who can afford it by utilizing public-key cryptography. While there are compelling reasons to join the password-killer bandwagon, and I honestly believe that Passkeys will solve many problems for the general &amp;ldquo;my password is password&amp;rdquo; end-user market, there is an undercurrent.&lt;/p&gt;
&lt;p&gt;Despite being a multi-national tech industry association, some people see the FIDO Alliance and their Passkeys as another large Silicon Valley solution that doesn&amp;rsquo;t care about all their users. Potential downsides, such as device dependence, compatibility, and interoperability difficulties, contribute to this debate and should be considered when advocating for FIDO2 Passkeys.&lt;/p&gt;
&lt;p&gt;Given the widespread support and work that Big Tech is putting towards modern passwordless authentication, I am confident that adoption rates will skyrocket soon. And some security-conscious individuals will continue to place their stack of unique, complex passwords in a credible password manager with 2FA as a second line of defense rather than a select handful of Big Tech gatekeeping providers.&lt;/p&gt;
&lt;p&gt;I advise everyone else to &lt;strong&gt;wait until passkeys gain broader support&lt;/strong&gt; and for the ecosystem to mature before going all-in! Only switch to Passkey-only authentication once you know how it works, &lt;a href="https://www.elliotali.com/passkeys/" title="An easy introduction to Passkeys" class="ext"&gt;how to set it up&lt;/a&gt;, and how to back it up.&lt;/p&gt;
&lt;h2 id="faqs"&gt;FAQs &lt;a class="heading-anchor" href="#faqs" aria-label="Link to section: FAQs"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="what-is-fido2"&gt;What is FIDO2? &lt;a class="heading-anchor" href="#what-is-fido2" aria-label="Link to section: What is FIDO2?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The FIDO Alliance created FIDO2, an open standard to enable secure and user-friendly passwordless authentication using public-key cryptography.&lt;/p&gt;
&lt;h3 id="how-do-fido2-passkeys-work"&gt;How do FIDO2 Passkeys work? &lt;a class="heading-anchor" href="#how-do-fido2-passkeys-work" aria-label="Link to section: How do FIDO2 Passkeys work?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Upon registration, FIDO2 Passkeys produce a one-of-a-kind public-private key pair on the user&amp;rsquo;s device. The public key is supplied to the web service, while the private key is kept protected on the device. During authentication, the machine uses its private key to satisfy a cryptographic challenge given by the service, and the service verifies the signature using the stored public key.&lt;/p&gt;
&lt;h3 id="what-are-the-benefits-of-fido2-passkeys"&gt;What are the benefits of FIDO2 Passkeys? &lt;a class="heading-anchor" href="#what-are-the-benefits-of-fido2-passkeys" aria-label="Link to section: What are the benefits of FIDO2 Passkeys?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;FIDO2 Passkeys improve security, user experience, and scalability across various devices, platforms, and services.&lt;/p&gt;
&lt;h3 id="what-are-the-potential-drawbacks-of-fido2-passkeys"&gt;What are the potential drawbacks of FIDO2 Passkeys? &lt;a class="heading-anchor" href="#what-are-the-potential-drawbacks-of-fido2-passkeys" aria-label="Link to section: What are the potential drawbacks of FIDO2 Passkeys?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Device dependence, which could result in users losing access to their accounts if their device is lost or broken, and compatibility difficulties, as not all online services offer FIDO2 authentication yet, are potential downsides of FIDO2 Passkeys. Switching from knowledge to possession factors has its own set of issues.&lt;/p&gt;
&lt;h3 id="can-i-use-fido2-passkeys-on-multiple-devices"&gt;Can I use FIDO2 Passkeys on multiple devices? &lt;a class="heading-anchor" href="#can-i-use-fido2-passkeys-on-multiple-devices" aria-label="Link to section: Can I use FIDO2 Passkeys on multiple devices?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Yes, FIDO2 Passkeys can be used on numerous devices as long as they support FIDO2 authentication and the online service supports multiple device registrations.&lt;/p&gt;</description></item><item><title>Passwordless Authentication: Future of Cybersecurity</title><link>https://www.janbrennenstuhl.eu/passwordless-authentication/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/passwordless-authentication/</guid><pubDate>Sun, 07 May 2023 00:00:00 +0200</pubDate><description>&lt;p&gt;In the context of internet security, implementing passwordless authentication really is a game changer. Say goodbye to traditional, complicated, and insecure passwords! It&amp;rsquo;s time for us to investigate the myriad advantages of implementing passwordless authentication and understand why it&amp;rsquo;s necessary for improving cybersecurity.&lt;/p&gt;
&lt;p&gt;In this detailed introduction, I&amp;rsquo;ll delve deep into the realm of how passwordless authentication works, its various forms, and how it might improve security. Let&amp;rsquo;s get this party started!&lt;/p&gt;
&lt;h2 id="passwordless-authentication-a-new-era-of-security"&gt;Passwordless Authentication: A New Era of Security &lt;a class="heading-anchor" href="#passwordless-authentication-a-new-era-of-security" aria-label="Link to section: Passwordless Authentication: A New Era of Security"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="what-is-passwordless-authentication"&gt;What is Passwordless Authentication? &lt;a class="heading-anchor" href="#what-is-passwordless-authentication" aria-label="Link to section: What is Passwordless Authentication?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Passwordless authentication refers to a way of validating a user&amp;rsquo;s identity that does not require the use of passwords. Instead of remembering long strings of characters, this solution depends on biometrics, one-time codes, or hardware token for verification. By minimizing the usage of weak or reused passwords, it gives a more secure and user-friendly experience.&lt;/p&gt;
&lt;h3 id="passwordless-authentication-vs-mfa"&gt;Passwordless Authentication vs. MFA &lt;a class="heading-anchor" href="#passwordless-authentication-vs-mfa" aria-label="Link to section: Passwordless Authentication vs. MFA"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Multi-factor authentication (MFA) is a layered authentication method that includes at least two of the following authentication factors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;something the user knows (knowledge-based, such as a &lt;a href="https://www.janbrennenstuhl.eu/long-password-support/" title="Long Password Support: A Key to Stronger &amp;amp; Safer Login Systems"&gt;long password&lt;/a&gt;),&lt;/li&gt;
&lt;li&gt;something the user has (possession-based, such as a hardware token), or&lt;/li&gt;
&lt;li&gt;something the user is (biometric, such as a retinal scan).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This approach assures that even if one authentication factor is compromised, an attacker must still penetrate the additional strong authentication layers to get unauthorized access.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Passwordless authentication occurs whenever a user or device is authenticated using a method other than a knowledge-based authentication process.&lt;/strong&gt; It is related to MFA in the sense that it can be utilized as a supplementary verification requirement, often on top of a user&amp;rsquo;s account and passwords, in any multi-factor authentication process.&lt;/p&gt;
&lt;h3 id="why-is-passwordless-authentication-important"&gt;Why is Passwordless Authentication Important? &lt;a class="heading-anchor" href="#why-is-passwordless-authentication-important" aria-label="Link to section: Why is Passwordless Authentication Important?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the age of rampant cyberattacks, securing online accounts has never been more important. Passwordless authentication has several advantages over traditional password-based approaches:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Enhanced security&lt;/strong&gt; – Passwordless authentication solves the inherent risks of password-based systems by eliminating the requirement for traditional login credentials. Password reuse, weak passwords, compromised credentials and phishing scams become obsolete when users no longer need to remember, store, or enter passwords in order to access their accounts. &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/credential-stuffing/" title="Credential Stuffing &amp;amp; Compromised Credentials"&gt;Credential stuffing&lt;/a&gt; and other classical brute-force attacks come to nothing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improved user experience&lt;/strong&gt; – By removing the need for passwords, users are relieved of the tedious task of creating, remembering, and keeping several complex passwords for different accounts. There will be no more forgotten passwords, lengthy password resets, or irritating lockouts due to erroneous password authentication. With no need for corrupt &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/password-strength-meter/" title="5 Studies on Password Strength Meters"&gt;password strength meters&lt;/a&gt; or restrictive password-based authentication policies, there is less friction during sign-up and sign-in processes. Your conversion rate will be happy!&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="how-does-passwordless-authentication-work"&gt;How Does Passwordless Authentication Work? &lt;a class="heading-anchor" href="#how-does-passwordless-authentication-work" aria-label="Link to section: How Does Passwordless Authentication Work?"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Passwordless authentication may appear to be a difficult concept at first, but it is actually a comprehensive authentication method, that streamlines and secures user access to online services and apps. Passwordless authentication, as opposed to standard passwords, uses a combination of modern technology and unique identifiers to authenticate a user&amp;rsquo;s identity.&lt;/p&gt;
&lt;p&gt;Typically, the process starts with the user initiating an authentication request, such as signing into an account or accessing a protected resource. Instead of requesting a password, the system demands the user enters an alternative, pre-configured authentication factor, such as a fingerprint, face recognition, or a one-time passcode. These solutions are more secure and personal by definition, making it extremely difficult for attackers to impersonate the legitimate user and steal credentials.&lt;/p&gt;
&lt;p&gt;When the user enters the requested authentication factor into the login box, the system verifies the information and, if it matches, grants the user access. The beauty of passwordless authentication is its ability to simplify the login process while also increasing security, resulting in a smooth and secure user experience that is changing the way we interact with the digital world.&lt;/p&gt;
&lt;h2 id="types-of-passwordless-authentication-methods"&gt;Types of Passwordless Authentication Methods &lt;a class="heading-anchor" href="#types-of-passwordless-authentication-methods" aria-label="Link to section: Types of Passwordless Authentication Methods"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="biometric-authentication-factors"&gt;Biometric Authentication Factors &lt;a class="heading-anchor" href="#biometric-authentication-factors" aria-label="Link to section: Biometric Authentication Factors"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Biometric authentication is based on distinguishing bodily traits such as fingerprints, facial recognition, or iris scans. The controversial authentication method gained popularity with the rise of Face ID and fingerprint sensors in mobile devices. Biometric data is claimed to be harder to falsify or steal, and offers a level of convenience for endusers. &lt;/p&gt;
&lt;h3 id="one-time-passcodes-otp"&gt;One-Time Passcodes (OTP) &lt;a class="heading-anchor" href="#one-time-passcodes-otp" aria-label="Link to section: One-Time Passcodes (OTP)"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;OTPs are temporary codes that are delivered to a user&amp;rsquo;s registered mobile device, typically by SMS, email or push notifications. Users enter the code for authentication, giving a secure and simple way that does not require static passwords.&lt;/p&gt;
&lt;h3 id="hardware-tokens"&gt;Hardware Tokens &lt;a class="heading-anchor" href="#hardware-tokens" aria-label="Link to section: Hardware Tokens"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Hardware tokens, such as the popular YubiKeys, are physical devices that create authentication codes. Commonly these security token are plugged into a computer via USB or use near-field communication (NFC) for user identity verification. These tokens give an extra degree of security because attackers must physically possess the security token in order gain access.&lt;/p&gt;
&lt;h3 id="software-tokens"&gt;Software tokens &lt;a class="heading-anchor" href="#software-tokens" aria-label="Link to section: Software tokens"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Passwordless authentication with software tokens is a popular, adaptable, and cost-effective solution. Software tokens, as opposed to hardware tokens, are digital representations of cryptographic keys that are safely held on a user&amp;rsquo;s device, such as a smartphone or computer. Users can quickly authenticate themselves by creating and submitting an unique, time-sensitive code via dedicated authenticator apps or a system function.&lt;/p&gt;
&lt;h3 id="magic-links"&gt;Magic Links &lt;a class="heading-anchor" href="#magic-links" aria-label="Link to section: Magic Links"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Magic links have long been recognized in computer systems as a user-friendly and convenient alternative to other, more elaborate passwordless login techniques. These one-time-only URLs are delivered to a user&amp;rsquo;s registered email address, allowing them to access a secure service or application with a single click. After clicking the magic link, the user is immediately authenticated and logged into the system without the need for a password.&lt;/p&gt;
&lt;h2 id="the-challenges-of-passwordless-authentication"&gt;The Challenges of Passwordless Authentication &lt;a class="heading-anchor" href="#the-challenges-of-passwordless-authentication" aria-label="Link to section: The Challenges of Passwordless Authentication"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="infrastructure-changes"&gt;Infrastructure Changes &lt;a class="heading-anchor" href="#infrastructure-changes" aria-label="Link to section: Infrastructure Changes"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To make passwordless authentication work, significant changes to an organization&amp;rsquo;s existing infrastructure may be required, which can be time-consuming and costly. Distributing hardware tokens to all employees and managing their life-cycle might be a challenge for some organisations.&lt;/p&gt;
&lt;h3 id="user-acceptance"&gt;User Acceptance &lt;a class="heading-anchor" href="#user-acceptance" aria-label="Link to section: User Acceptance"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Passwordless authentication requires user acceptance in order to be successful. Some users may be hesitant to adopt new passwordless solutions, especially if they&amp;rsquo;re not familiar with them or perceive them as less convenient. To steer user adoption, educate your users and staff about the new passwordless system benefits, recommended practices, and support them on any problems they may have.&lt;/p&gt;
&lt;h2 id="passwordless-authentication-in-action"&gt;Passwordless Authentication in Action &lt;a class="heading-anchor" href="#passwordless-authentication-in-action" aria-label="Link to section: Passwordless Authentication in Action"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="fido2-web-authentication-webauthn"&gt;FIDO2 Web Authentication (WebAuthn) &lt;a class="heading-anchor" href="#fido2-web-authentication-webauthn" aria-label="Link to section: FIDO2 Web Authentication (WebAuthn)"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The FIDO2 Web Authentication (WebAuthn) standard describes a passwordless authentication mechanisms that enable users to access websites and apps using biometrics, mobile devices, or security keys. This standard is supported by major browsers and platforms such as Google, Microsoft, and Apple.&lt;/p&gt;
&lt;h3 id="apple-face-id--touch-id"&gt;Apple Face ID &amp;amp; Touch ID &lt;a class="heading-anchor" href="#apple-face-id--touch-id" aria-label="Link to section: Apple Face ID &amp;amp; Touch ID"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With its Face ID and Touch ID fingerprint scanning technology, Apple has been a pioneer in passwordless authentication. Users can access their mobile devices and authenticate transactions utilizing only their face or fingerprint via these two biometric authentication technologies.&lt;/p&gt;
&lt;h3 id="google-passwordless"&gt;Google Passwordless &lt;a class="heading-anchor" href="#google-passwordless" aria-label="Link to section: Google Passwordless"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Google has also embraced passwordless implementations, employing a variety of approaches such as biometrics and security keys. Google&amp;rsquo;s strategy has made it easier for users to gain secure access to their accounts, leading to increasing adoption.&lt;/p&gt;
&lt;h3 id="microsoft-windows-hello"&gt;Microsoft Windows Hello &lt;a class="heading-anchor" href="#microsoft-windows-hello" aria-label="Link to section: Microsoft Windows Hello"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Microsoft has been among the pioneers in the adoption of passwordless authentication solutions. Users can sign in using Windows Hello, Microsoft Authenticator, or security keys in their implementation. This change has greatly increased security while also streamlining the user experience.&lt;/p&gt;
&lt;h3 id="the-rise-of-passwordless-authentication-startups"&gt;The Rise of Passwordless Authentication Startups &lt;a class="heading-anchor" href="#the-rise-of-passwordless-authentication-startups" aria-label="Link to section: The Rise of Passwordless Authentication Startups"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As passwordless authentication gets more popular, multiple businesses have started to provide novel solutions in this field. Passwordless technology and &lt;strong&gt;authentication-as-a-service providers such as HYPR, Trusona, and Beyond Identity&lt;/strong&gt; assist enterprises in improving their security posture and user experience with off-the-shelf solutions. But also established players such as &lt;a href="https://www.okta.com/passwordless-authentication/" class="ext"&gt;Okta (Fastpass)&lt;/a&gt; and Auth0 provide and implement passwordless authentication solutions as part of their authentication system to their customers.&lt;/p&gt;
&lt;h2 id="passwordless-authentication-faqs"&gt;Passwordless Authentication FAQs &lt;a class="heading-anchor" href="#passwordless-authentication-faqs" aria-label="Link to section: Passwordless Authentication FAQs"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="is-passwordless-authentication-safe--truly-secure"&gt;Is passwordless authentication safe &amp;amp; truly secure? &lt;a class="heading-anchor" href="#is-passwordless-authentication-safe--truly-secure" aria-label="Link to section: Is passwordless authentication safe &amp;amp; truly secure?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Yes, passwordless authentication is more secure than traditional password-based techniques and password management in general. It decreases the risk of unwantedly granted access by eliminating the usage of &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/password-reuse/" title="5 Alarming Password Reuse Studies"&gt;weak or reused passwords&lt;/a&gt;. No stolen passwords and no lost or stolen credentials anymore! &lt;strong&gt;The overall security depends on the private keys being securely stored.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="how-can-i-implement-passwordless-authentication-in-my-organization"&gt;How can I implement passwordless authentication in my organization? &lt;a class="heading-anchor" href="#how-can-i-implement-passwordless-authentication-in-my-organization" aria-label="Link to section: How can I implement passwordless authentication in my organization?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To enable passwordless authentication, select a suitable solution (biometrics, OTP, etc.) and perform the necessary infrastructure adjustments. It is also critical to educate users on the new authentication system and its advantages.&lt;/p&gt;
&lt;h3 id="can-i-still-use-two-factor-authentication-2fa-with-passwordless-authentication"&gt;Can I still use two-factor authentication (2FA) with passwordless authentication? &lt;a class="heading-anchor" href="#can-i-still-use-two-factor-authentication-2fa-with-passwordless-authentication" aria-label="Link to section: Can I still use two-factor authentication (2FA) with passwordless authentication?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Absolutely! In fact, passwordless authentication methods can be paired with additional other authentication methods and factors to increase security even further. For example, biometrics combined with a hardware token can be used for multi-factor authentication.&lt;/p&gt;
&lt;h3 id="what-happens-if-i-lose-my-hardware-token-or-registered-device"&gt;What happens if I lose my hardware token or registered device? &lt;a class="heading-anchor" href="#what-happens-if-i-lose-my-hardware-token-or-registered-device" aria-label="Link to section: What happens if I lose my hardware token or registered device?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In such circumstances, having a backup authentication solution in place is critical. To ensure that you don&amp;rsquo;t lose access to your account, you can set up backup procedures like biometrics, OTP, or even an alternative device or hardware token.&lt;/p&gt;
&lt;h3 id="how-does-passwordless-authentication-affect-user-privacy"&gt;How does passwordless authentication affect user privacy? &lt;a class="heading-anchor" href="#how-does-passwordless-authentication-affect-user-privacy" aria-label="Link to section: How does passwordless authentication affect user privacy?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Biometric authentication processes, such as passwordless authentication, can pose privacy concerns. Users may be cautious to submit sensitive information since there is no way to avoid biometric surveillance because, unlike passwords, biometric data cannot be changed. Only recently the Chaos Computer Club (CCC) restored &lt;a href="https://www.ccc.de/en/updates/2022/afghanistan-biometrie" class="ext"&gt;an U.S. military biometrics database&lt;/a&gt; from unused former military biometric devices containing fingerprints, iris scans, and photographs of more than 2,600 Afghans and Iraqis.&lt;/p&gt;
&lt;h3 id="are-there-any-drawbacks-to-passwordless-authentication"&gt;Are there any drawbacks to passwordless authentication? &lt;a class="heading-anchor" href="#are-there-any-drawbacks-to-passwordless-authentication" aria-label="Link to section: Are there any drawbacks to passwordless authentication?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;While implementing passwordless authentication has numerous advantages, it can come with certain drawbacks, such as required investment in infrastructure and user acceptance. However, the benefits of better security and user experience frequently outweigh the disadvantages.&lt;/p&gt;
&lt;h2 id="passkeys-the-future-of-passwordless-authentication"&gt;Passkeys: The Future of Passwordless Authentication &lt;a class="heading-anchor" href="#passkeys-the-future-of-passwordless-authentication" aria-label="Link to section: Passkeys: The Future of Passwordless Authentication"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Passwordless authentication is clearly the way forward as technology progresses and security concerns about data breaches grow. We can anticipate big improvements in online security, access management and user experience as more organizations adopt this method. One of these innovations are passkeys!&lt;/p&gt;
&lt;p&gt;Passkeys are gaining the attention of both consumers and security experts in the quickly evolving world of passwordless authentication. By seamlessly merging the greatest parts of existing passwordless authentication mechanisms, this cutting-edge technology promises to transform online security and user experience. I recently wrote about &lt;a href="https://www.janbrennenstuhl.eu/fido-passkeys/" title="Critical Notes on Passkeys"&gt;the Passkey controversies&lt;/a&gt;, make sure to read!&lt;/p&gt;
&lt;h3 id="what-are-passkeys"&gt;What are Passkeys? &lt;a class="heading-anchor" href="#what-are-passkeys" aria-label="Link to section: What are Passkeys?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Passkeys are digital credentials enabling a novel kind of passwordless login &lt;a href="https://fidoalliance.org/passkeys/" class="ext"&gt;based on FIDO protocols&lt;/a&gt; that combines the ease of use of one-time passcodes (OTPs) with the security of cryptographic keys. Unlike traditional OTPs, which are often provided via SMS or email and are vulnerable to interception, passkeys produce unique, time-sensitive codes using standard public key cryptography techniques.&lt;/p&gt;
&lt;p&gt;During online service sign-up, the user&amp;rsquo;s client device generates a new cryptographic public private key pair. The user&amp;rsquo;s private key is kept and securely stored within the device, while the corresponding public key, is registered with the online service. The client device authenticates itself by signing a authentication challenge which then is verified using the public key, thus proving possession of the private key to the service. In this way, a passkey can replace password-based authentication and a second factor in a single step.&lt;/p&gt;
&lt;p&gt;Microsoft, Apple, and Google have all updated their operating systems and apps &lt;a href="https://security.googleblog.com/2023/05/so-long-passwords-thanks-for-all-phish.html" title="Creating passkeys on your Google Account" class="ext"&gt;to include passkeys&lt;/a&gt; in recent months and are focussed on finally killing passwords.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="heading-anchor" href="#conclusion" aria-label="Link to section: Conclusion"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Passwordless authentication is an effective answer to today&amp;rsquo;s cybersecurity challenges. It provides a more secure and user-friendly experience for users while lowering support costs for enterprises by eliminating the dependency on passwords. As more businesses decide to go with a passwordless authentication solution, the digital world will become brighter and more secure. Go and setup your passkeys now!&lt;/p&gt;</description></item><item><title>Do login challenges and risk scoring stop account takeover?</title><link>https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/</guid><pubDate>Thu, 27 Apr 2023 00:00:00 +0200</pubDate><description>&lt;p&gt;&lt;em&gt;Latest change (2026-10-13): Rewritten as a field-guide entry: question title, short answer, key findings and evidence table. Study summaries kept and extended with numbers from the papers.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; They are an important barrier if you pick the right challenge: device-based challenges blocked over 94% of phishing-rooted hijacking attempts at Google, while knowledge-based challenges stopped as few as 10%. The cost is friction, as 52% of legitimate users who got a challenge failed to sign in at first.&lt;/p&gt;&lt;h2 id="key-findings"&gt;Key findings &lt;a class="heading-anchor" href="#key-findings" aria-label="Link to section: Key findings"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class="finding" id="f-login-device-challenge-94pct"&gt;
&lt;blockquote&gt;&lt;p&gt;Device-based login challenges blocked over 94% of hijacking attempts rooted in phishing and 100% of automated hijacking attempts.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://damonmccoy.com/papers/loginchallenges.pdf" class="ext"&gt;&lt;cite&gt;Doerfler et al., Evaluating Login Challenges as a Defense Against Account Takeover (WWW 2019)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-login-device-challenge-94pct" title="#f-login-device-challenge-94pct"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Device-based login challenges blocked over 94% of hijacking attempts rooted in phishing and 100% of automated hijacking attempts." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/#f-login-device-challenge-94pct" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/f-login-device-challenge-94pct.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-login-knowledge-challenge-10pct"&gt;
&lt;blockquote&gt;&lt;p&gt;Knowledge-based login challenges prevented as few as 10% of hijacking attempts rooted in phishing.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://damonmccoy.com/papers/loginchallenges.pdf" class="ext"&gt;&lt;cite&gt;Doerfler et al., Evaluating Login Challenges as a Defense Against Account Takeover (WWW 2019)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-login-knowledge-challenge-10pct" title="#f-login-knowledge-challenge-10pct"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Knowledge-based login challenges prevented as few as 10% of hijacking attempts rooted in phishing." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/#f-login-knowledge-challenge-10pct" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/f-login-knowledge-challenge-10pct.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-login-challenge-friction-52pct"&gt;
&lt;blockquote&gt;&lt;p&gt;Login challenges caused 52% of legitimate users to fail to sign in, although 97% got into their account within a short period.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://damonmccoy.com/papers/loginchallenges.pdf" class="ext"&gt;&lt;cite&gt;Doerfler et al., Evaluating Login Challenges as a Defense Against Account Takeover (WWW 2019)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-login-challenge-friction-52pct" title="#f-login-challenge-friction-52pct"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Login challenges caused 52% of legitimate users to fail to sign in, although 97% got into their account within a short period." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/#f-login-challenge-friction-52pct" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/f-login-challenge-friction-52pct.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-login-risk-score-recall-89pct"&gt;
&lt;blockquote&gt;&lt;p&gt;A statistical login classifier using IP and user-agent history reached a recall of up to 89% at a 10% false-positive rate on LinkedIn login data.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.ndss-symposium.org/wp-content/uploads/2017/09/who-are-you-statistical-approach-measuring-user-authenticity.pdf" class="ext"&gt;&lt;cite&gt;Freeman et al., Who Are You? A Statistical Approach to Measuring User Authenticity (NDSS 2016)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-login-risk-score-recall-89pct" title="#f-login-risk-score-recall-89pct"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="A statistical login classifier using IP and user-agent history reached a recall of up to 89% at a 10% false-positive rate on LinkedIn login data." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/#f-login-risk-score-recall-89pct" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/f-login-risk-score-recall-89pct.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-login-protect-frequent-guesses"&gt;
&lt;blockquote&gt;&lt;p&gt;If you can implement only one defence against online guessing, protect users whose passwords attackers guess frequently more aggressively than others.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://www.microsoft.com/en-us/research/uploads/prod/2018/06/stopGuessingTR.pdf" class="ext"&gt;&lt;cite&gt;Tian, Herley and Schechter, StopGuessing: Using Guessed Passwords to Thwart Online Guessing&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-login-protect-frequent-guesses" title="#f-login-protect-frequent-guesses"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="If you can implement only one defence against online guessing, protect users whose passwords attackers guess frequently more aggressively than others." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/#f-login-protect-frequent-guesses" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/f-login-protect-frequent-guesses.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="evidence"&gt;Evidence &lt;a class="heading-anchor" href="#evidence" aria-label="Link to section: Evidence"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="table-scroll studies" tabindex="0" role="region" aria-label="Reinforced authentication studies"&gt;&lt;table&gt;
&lt;caption&gt;Reinforced authentication studies&lt;/caption&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th scope="col"&gt;Study&lt;/th&gt;&lt;th scope="col"&gt;Year&lt;/th&gt;&lt;th scope="col"&gt;Sample&lt;/th&gt;&lt;th scope="col"&gt;Method&lt;/th&gt;&lt;th scope="col"&gt;Finding&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://damonmccoy.com/papers/loginchallenges.pdf" class="ext"&gt;Evaluating Login Challenges as a Defense Against Account Takeover&lt;/a&gt;&lt;span class="org"&gt;Google, New York University&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2019&lt;/td&gt;&lt;td&gt;Over 350,000 hijacking attempts; 1.2 million legitimate users&lt;/td&gt;&lt;td&gt;Case study of 14 challenge types at Google&lt;/td&gt;&lt;td&gt;Device-based challenges work best; 52% of legitimate users failed at first.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.microsoft.com/en-us/research/uploads/prod/2018/06/stopGuessingTR.pdf" class="ext"&gt;StopGuessing: Using Guessed Passwords to Thwart Online Guessing&lt;/a&gt;&lt;span class="org"&gt;Carnegie Mellon University, Microsoft Research&lt;/span&gt;&lt;/th&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Open-source implementation and attack simulations&lt;/td&gt;&lt;td&gt;Penalize failures with frequently guessed passwords and forgive typos.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.ndss-symposium.org/wp-content/uploads/2017/09/who-are-you-statistical-approach-measuring-user-authenticity.pdf" class="ext"&gt;Who Are You? A Statistical Approach to Measuring User Authenticity&lt;/a&gt;&lt;span class="org"&gt;LinkedIn, Ruhr-Universität Bochum, Università di Cagliari&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2016&lt;/td&gt;&lt;td&gt;LinkedIn login data and simulated attacks&lt;/td&gt;&lt;td&gt;Statistical classifier, prototype evaluation&lt;/td&gt;&lt;td&gt;Recall of up to 89% at a 10% false-positive rate.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://www.microsoft.com/en-us/research/uploads/prod/2018/06/distinguishingBotsFromLegit.pdf" class="ext"&gt;Distinguishing Attacks from Legitimate Traffic at an Authentication Server&lt;/a&gt;&lt;span class="org"&gt;Microsoft Research&lt;/span&gt;&lt;/th&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;Statistical estimation with sensitivity analysis&lt;/td&gt;&lt;td&gt;Estimating the bad-to-good traffic ratio avoids fixed lockout thresholds.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id="what-to-do"&gt;What to do &lt;a class="heading-anchor" href="#what-to-do" aria-label="Link to section: What to do"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="for-engineers"&gt;For engineers &lt;a class="heading-anchor" href="#for-engineers" aria-label="Link to section: For engineers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Score every login on signals the user doesn&amp;rsquo;t type, such as IP address history, device and browser. Freeman et al. reached a recall of up to 89% using IP and user-agent history.&lt;/li&gt;
&lt;li&gt;Prefer device-based challenges, such as a prompt on a known device, over knowledge questions. Doerfler et al. measured a large gap between the two. My essay on &lt;a href="https://www.janbrennenstuhl.eu/step-up-authentication/"&gt;step-up authentication&lt;/a&gt; shows how to request a stronger factor only when the risk justifies it.&lt;/li&gt;
&lt;li&gt;Count failed logins by how likely they are to be an attack. Penalize failures with frequently guessed passwords, protect accounts with weak passwords harder, and be lenient with typos. Tian et al. do this without storing anything that would expose accounts if leaked.&lt;/li&gt;
&lt;li&gt;Breadth-first guessing spreads attempts thinly over many accounts, so per-account lockouts don&amp;rsquo;t see it. Herley and Schechter estimate the share of attack traffic instead of relying on fixed thresholds. See &lt;a href="https://www.janbrennenstuhl.eu/password-spraying/"&gt;password spraying&lt;/a&gt; and &lt;a href="https://www.janbrennenstuhl.eu/honeytoken/"&gt;honeytokens&lt;/a&gt; for related detection.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="for-product-and-ux"&gt;For product and UX &lt;a class="heading-anchor" href="#for-product-and-ux" aria-label="Link to section: For product and UX"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Budget for friction. A challenge that half of your legitimate users fail at first needs a clear path back in, or it turns into support tickets and lost users.&lt;/li&gt;
&lt;li&gt;Challenge only suspicious logins, so most users never see a challenge. The 2 risk-scoring studies above show how to pick them out.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-studies-in-detail"&gt;The studies in detail &lt;a class="heading-anchor" href="#the-studies-in-detail" aria-label="Link to section: The studies in detail"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="evaluating-login-challenges-as-a-defense-against-account-takeover"&gt;Evaluating Login Challenges as a Defense Against Account Takeover &lt;a class="heading-anchor" href="#evaluating-login-challenges-as-a-defense-against-account-takeover" aria-label="Link to section: Evaluating Login Challenges as a Defense Against Account Takeover"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Google and New York University teamed up to &amp;ldquo;study the efficacy of login challenges at preventing account takeover&amp;rdquo; and to &amp;ldquo;evaluate the amount of friction these challenges create for normal users&amp;rdquo;. Using Google as a case study, they evaluated 14 device-based, delegation-based, knowledge-based and resource-based challenges against over 350,000 real-world hijacking attempts, and measured usability on a sample of 1.2 million legitimate users.&lt;/p&gt;
&lt;p&gt;Device-based challenges blocked over 94% of phishing-rooted attempts and all automated ones. Knowledge-based challenges stopped as few as 10% of phishing-rooted attempts and 73% of automated ones. The conclusion is sobering:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Our results illustrate that login challenges act as an important barrier to hijacking, but that friction in the process leads to 52% of legitimate users failing to sign-in—though 97% of users eventually access their account in a short period.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://damonmccoy.com/papers/loginchallenges.pdf" class="ext"&gt;Read the paper (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="using-guessed-passwords-to-thwart-online-guessing"&gt;Using Guessed Passwords to Thwart Online Guessing &lt;a class="heading-anchor" href="#using-guessed-passwords-to-thwart-online-guessing" aria-label="Link to section: Using Guessed Passwords to Thwart Online Guessing"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This paper from Microsoft Research and Carnegie Mellon University gives practitioners who defend password-protected resources against online guessing a set of techniques to better balance friction and security:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Among our contributions are features to make better benign/attack traffic classification decisions. These include mechanisms to penalize fail events with commonly guessed passwords more, to protect accounts with weak passwords better, and to distinguish user-generated typos from other fails. We do all of these without storing any information which exposes accounts to new risk in the event of a server breach. These innovations allow much greater flexibility over the previous state-of-the-art, which treats all failures equally&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The authors publish an open-source implementation and a guessing-attack simulator. If practitioners can implement only one of the techniques, they recommend protecting users who rely on frequently guessed passwords more aggressively.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.microsoft.com/en-us/research/uploads/prod/2018/06/stopGuessingTR.pdf" class="ext"&gt;Read the paper (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="a-statistical-approach-to-measuring-user-authenticity"&gt;A Statistical Approach to Measuring User Authenticity &lt;a class="heading-anchor" href="#a-statistical-approach-to-measuring-user-authenticity" aria-label="Link to section: A Statistical Approach to Measuring User Authenticity"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Researchers from LinkedIn, Ruhr-Universität Bochum and Università di Cagliari evaluated a statistical framework for &amp;ldquo;strengthening password-based authentication by classifying login attempts into normal and suspicious activity based on parameters available during login&amp;rdquo;. Suspicious attempts can then get an extra verification step, such as a phone-based one.&lt;/p&gt;
&lt;p&gt;They tested the approach on real-life login data from LinkedIn and on simulated attacks. Using the user&amp;rsquo;s IP history and user-agent history, it showed a &amp;ldquo;recall of up to 89% for a false-positive rate of 10%&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ndss-symposium.org/wp-content/uploads/2017/09/who-are-you-statistical-approach-measuring-user-authenticity.pdf" class="ext"&gt;Read the paper (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="distinguishing-attacks-from-legitimate-traffic-at-an-authentication-server"&gt;Distinguishing Attacks from Legitimate Traffic at an Authentication Server &lt;a class="heading-anchor" href="#distinguishing-attacks-from-legitimate-traffic-at-an-authentication-server" aria-label="Link to section: Distinguishing Attacks from Legitimate Traffic at an Authentication Server"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In this paper, Microsoft researchers look at how to defend against breadth-first attacks that spread guesses very widely. Lockout rules such as &amp;ldquo;three strikes&amp;rdquo; work against attacks on one account, but at large providers breadth-first attacks can send millions of guesses without triggering them. The authors describe &amp;ldquo;a simple robust procedure to estimate the ratio of bad-to-good traffic and show how this can be used to calculate the likelihood that any particular observation is indicative of malice.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;They conclude that their &amp;ldquo;approach has the advantage over three strikes type lockout and variants that it has no dependence on arbitrary thresholds and we avoid base rate neglect. It has the advantages over machine learning schemes that it requires no labels, and does not assume stationarity of attack traffic.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.microsoft.com/en-us/research/uploads/prod/2018/06/distinguishingBotsFromLegit.pdf" class="ext"&gt;Read the paper (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="related"&gt;Related &lt;a class="heading-anchor" href="#related" aria-label="Link to section: Related"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/credential-stuffing/"&gt;How do you protect accounts from stolen credentials?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/"&gt;How do attackers take over accounts?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/password-reuse/"&gt;How common is password reuse?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>How secure are email-based password resets?</title><link>https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/</guid><pubDate>Fri, 21 Apr 2023 00:00:00 +0200</pubDate><description>&lt;p&gt;&lt;em&gt;Latest change (2026-10-13): Rewritten as a field-guide entry: question title, short answer, key findings and evidence table. Study summary kept and extended with the paper&amp;rsquo;s measured results.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; In a 2021 study of 366 websites from the Alexa Top 5K, 72% of account recovery mechanisms had at least one implementation weakness. Common gaps were multiple valid reset tokens, missing change notifications and long-lived reset links.&lt;/p&gt;&lt;h2 id="key-findings"&gt;Key findings &lt;a class="heading-anchor" href="#key-findings" aria-label="Link to section: Key findings"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class="finding" id="f-recovery-72pct-weakness"&gt;
&lt;blockquote&gt;&lt;p&gt;In a study of 366 popular websites, 72% of account recovery mechanisms had at least one implementation weakness.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://kharraz.org/publications/dimva2021youvegotmail.pdf" class="ext"&gt;&lt;cite&gt;Innocenti et al., You&amp;#39;ve Got (a Reset) Mail (DIMVA 2021)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-recovery-72pct-weakness" title="#f-recovery-72pct-weakness"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="In a study of 366 popular websites, 72% of account recovery mechanisms had at least one implementation weakness." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/#f-recovery-72pct-weakness" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/f-recovery-72pct-weakness.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-recovery-40pct-multiple-tokens"&gt;
&lt;blockquote&gt;&lt;p&gt;40% of the websites studied generated multiple valid password reset tokens at the same time.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://kharraz.org/publications/dimva2021youvegotmail.pdf" class="ext"&gt;&lt;cite&gt;Innocenti et al., You&amp;#39;ve Got (a Reset) Mail (DIMVA 2021)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-recovery-40pct-multiple-tokens" title="#f-recovery-40pct-multiple-tokens"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="40% of the websites studied generated multiple valid password reset tokens at the same time." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/#f-recovery-40pct-multiple-tokens" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/f-recovery-40pct-multiple-tokens.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-recovery-45pct-no-notification"&gt;
&lt;blockquote&gt;&lt;p&gt;45% of the websites studied did not notify the account owner after a password change, so an unauthorised reset went unnoticed.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://kharraz.org/publications/dimva2021youvegotmail.pdf" class="ext"&gt;&lt;cite&gt;Innocenti et al., You&amp;#39;ve Got (a Reset) Mail (DIMVA 2021)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-recovery-45pct-no-notification" title="#f-recovery-45pct-no-notification"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="45% of the websites studied did not notify the account owner after a password change, so an unauthorised reset went unnoticed." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/#f-recovery-45pct-no-notification" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/f-recovery-45pct-no-notification.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-recovery-13pct-owasp"&gt;
&lt;blockquote&gt;&lt;p&gt;Only 13% of the websites studied followed the OWASP guidelines for password reset.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://kharraz.org/publications/dimva2021youvegotmail.pdf" class="ext"&gt;&lt;cite&gt;Innocenti et al., You&amp;#39;ve Got (a Reset) Mail (DIMVA 2021)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-recovery-13pct-owasp" title="#f-recovery-13pct-owasp"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Only 13% of the websites studied followed the OWASP guidelines for password reset." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/#f-recovery-13pct-owasp" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/f-recovery-13pct-owasp.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="evidence"&gt;Evidence &lt;a class="heading-anchor" href="#evidence" aria-label="Link to section: Evidence"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="table-scroll studies" tabindex="0" role="region" aria-label="Account recovery studies"&gt;&lt;table&gt;
&lt;caption&gt;Account recovery studies&lt;/caption&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th scope="col"&gt;Study&lt;/th&gt;&lt;th scope="col"&gt;Year&lt;/th&gt;&lt;th scope="col"&gt;Sample&lt;/th&gt;&lt;th scope="col"&gt;Method&lt;/th&gt;&lt;th scope="col"&gt;Finding&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://kharraz.org/publications/dimva2021youvegotmail.pdf" class="ext"&gt;You&amp;#39;ve Got (a Reset) Mail: A Security Analysis of Email-Based Password Reset Procedures&lt;/a&gt;&lt;span class="org"&gt;Northeastern University, University of Trento, KU Leuven, Florida International University&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2021&lt;/td&gt;&lt;td&gt;366 websites from the Alexa Top 5K&lt;/td&gt;&lt;td&gt;Manual registration and semi-automated checks against 8 OWASP-based controls&lt;/td&gt;&lt;td&gt;72% had at least one weakness; only 13% followed the OWASP guidelines.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id="what-to-do"&gt;What to do &lt;a class="heading-anchor" href="#what-to-do" aria-label="Link to section: What to do"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="for-engineers"&gt;For engineers &lt;a class="heading-anchor" href="#for-engineers" aria-label="Link to section: For engineers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The weaknesses Innocenti et al. measured map to concrete controls:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep one valid reset token per account. Invalidate older tokens when a user requests a new one, and accept each token only once.&lt;/li&gt;
&lt;li&gt;Give reset links a short expiry. The study counted any link still valid after 24 hours as a weakness, and found that in 75 websites.&lt;/li&gt;
&lt;li&gt;Send reset links over HTTPS only. 52 websites sent tokens in insecure links.&lt;/li&gt;
&lt;li&gt;End existing sessions after a reset. 38% of the websites kept them alive.&lt;/li&gt;
&lt;li&gt;Protect the flow against login CSRF and header manipulation. Build reset links from configuration, not from the request&amp;rsquo;s host header.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Treat recovery as a high-risk action that deserves the same scrutiny as login. &lt;a href="https://www.janbrennenstuhl.eu/step-up-authentication/"&gt;Step-up authentication&lt;/a&gt; shows how to require more proof for sensitive actions.&lt;/p&gt;
&lt;h3 id="for-product-and-ux"&gt;For product and UX &lt;a class="heading-anchor" href="#for-product-and-ux" aria-label="Link to section: For product and UX"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Notify the account owner after every password change, and include a way to report &amp;ldquo;this wasn&amp;rsquo;t me&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Keep the reset email plain and predictable, so users can spot a fake one.&lt;/li&gt;
&lt;li&gt;Recovery is also an account takeover path. The &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/"&gt;account hijacking entry&lt;/a&gt; covers attacks that start before sign-up.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-studies-in-detail"&gt;The studies in detail &lt;a class="heading-anchor" href="#the-studies-in-detail" aria-label="Link to section: The studies in detail"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="security-analysis-of-email-based-password-reset-procedures"&gt;Security Analysis of Email-Based Password Reset Procedures &lt;a class="heading-anchor" href="#security-analysis-of-email-based-password-reset-procedures" aria-label="Link to section: Security Analysis of Email-Based Password Reset Procedures"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;An international group of researchers from the USA, Italy and Belgium analyzed the email-based account recovery mechanisms of websites in the Alexa Top 5K. They manually registered accounts and triggered password recovery on sites from 3 popularity groups, ending up with 366 websites. They checked each site against 8 implementation controls derived from the OWASP guidelines.&lt;/p&gt;
&lt;p&gt;The paper describes a heterogeneous reality. 72% of the websites had at least one weakness, and only 13% followed the OWASP guidelines. 40% generated multiple valid tokens, 45% sent no notification after a password change, and 22% were vulnerable to login CSRF. The authors also outline concrete password-recovery attacks that can lead to account takeover.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;We hope that this paper will pave the way in highlighting the importance of improving the email-based account recovery mechanisms in real-world websites.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://kharraz.org/publications/dimva2021youvegotmail.pdf" class="ext"&gt;Read the paper (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="related"&gt;Related &lt;a class="heading-anchor" href="#related" aria-label="Link to section: Related"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/"&gt;How do attackers take over accounts?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/"&gt;Do login challenges and risk scoring stop account takeover?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>How do attackers take over accounts?</title><link>https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/</guid><pubDate>Fri, 21 Apr 2023 00:00:00 +0200</pubDate><description>&lt;p&gt;&lt;em&gt;Latest change (2026-10-13): Rewritten as a field-guide entry: question title, short answer, key findings and evidence table. Study summaries kept and extended with numbers from the papers.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; Some attackers prepare an account before the victim even signs up: at least 35 of 75 popular services studied were vulnerable to such pre-hijacking. Others are paid to break into a specific account and mostly use tailored phishing that can get past SMS two-factor authentication.&lt;/p&gt;&lt;h2 id="key-findings"&gt;Key findings &lt;a class="heading-anchor" href="#key-findings" aria-label="Link to section: Key findings"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class="finding" id="f-hijack-prehijack-35-of-75"&gt;
&lt;blockquote&gt;&lt;p&gt;At least 35 of 75 popular online services were vulnerable to one or more account pre-hijacking attacks.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://arxiv.org/pdf/2205.10174.pdf" class="ext"&gt;&lt;cite&gt;Sudhodanan and Paverd, Pre-hijacked accounts (USENIX Security 2022)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-hijack-prehijack-35-of-75" title="#f-hijack-prehijack-35-of-75"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="At least 35 of 75 popular online services were vulnerable to one or more account pre-hijacking attacks." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/#f-hijack-prehijack-35-of-75" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/f-hijack-prehijack-35-of-75.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-hijack-prehijack-email-only"&gt;
&lt;blockquote&gt;&lt;p&gt;In an account pre-hijacking attack, an attacker who knows only the victim&amp;rsquo;s email address acts before the victim creates an account and gains access after the victim has signed up.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://arxiv.org/pdf/2205.10174.pdf" class="ext"&gt;&lt;cite&gt;Sudhodanan and Paverd, Pre-hijacked accounts (USENIX Security 2022)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-hijack-prehijack-email-only" title="#f-hijack-prehijack-email-only"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="In an account pre-hijacking attack, an attacker who knows only the victim&amp;rsquo;s email address acts before the victim creates an account and gains access after the victim has signed up." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/#f-hijack-prehijack-email-only" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/f-hijack-prehijack-email-only.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-hijack-hire-5-of-27"&gt;
&lt;blockquote&gt;&lt;p&gt;Of 27 hack-for-hire services that researchers approached as buyers, only 5 succeeded in attacking the email accounts of the test identities.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://dl.acm.org/doi/pdf/10.1145/3308558.3313489" class="ext"&gt;&lt;cite&gt;Mirian et al., Hack for Hire (WWW 2019)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-hijack-hire-5-of-27" title="#f-hijack-hire-5-of-27"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Of 27 hack-for-hire services that researchers approached as buyers, only 5 succeeded in attacking the email accounts of the test identities." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/#f-hijack-hire-5-of-27" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/f-hijack-hire-5-of-27.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class="finding" id="f-hijack-hire-phishing-sms-2fa"&gt;
&lt;blockquote&gt;&lt;p&gt;Hack-for-hire attackers relied mainly on tailored phishing messages that were sophisticated enough to bypass SMS two-factor authentication.&lt;/p&gt;&lt;/blockquote&gt;
&lt;figcaption&gt;&lt;span class="finding-source"&gt;Source: &lt;a href="https://dl.acm.org/doi/pdf/10.1145/3308558.3313489" class="ext"&gt;&lt;cite&gt;Mirian et al., Hack for Hire (WWW 2019)&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="finding-tools"&gt;&lt;a class="finding-id" href="#f-hijack-hire-phishing-sms-2fa" title="#f-hijack-hire-phishing-sms-2fa"&gt;Link&lt;span class="sr-only"&gt; to this finding&lt;/span&gt;&lt;/a&gt;&lt;button type="button" class="text-button" data-quote="Hack-for-hire attackers relied mainly on tailored phishing messages that were sophisticated enough to bypass SMS two-factor authentication." data-quote-url="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/#f-hijack-hire-phishing-sms-2fa" hidden&gt;Copy quote&lt;/button&gt;&lt;a class="finding-card" href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-takeover/f-hijack-hire-phishing-sms-2fa.png" download&gt;Save as image&lt;span class="sr-only"&gt; (PNG, 1200 by 630 pixels)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="evidence"&gt;Evidence &lt;a class="heading-anchor" href="#evidence" aria-label="Link to section: Evidence"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="table-scroll studies" tabindex="0" role="region" aria-label="Account hijacking studies"&gt;&lt;table&gt;
&lt;caption&gt;Account hijacking studies&lt;/caption&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th scope="col"&gt;Study&lt;/th&gt;&lt;th scope="col"&gt;Year&lt;/th&gt;&lt;th scope="col"&gt;Sample&lt;/th&gt;&lt;th scope="col"&gt;Method&lt;/th&gt;&lt;th scope="col"&gt;Finding&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://arxiv.org/pdf/2205.10174.pdf" class="ext"&gt;Pre-hijacked accounts: An Empirical Study of Security Failures in User Account Creation on the Web&lt;/a&gt;&lt;span class="org"&gt;Independent researcher, Microsoft Security Response Center&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2022&lt;/td&gt;&lt;td&gt;75 popular online services&lt;/td&gt;&lt;td&gt;Attack design and testing against live services&lt;/td&gt;&lt;td&gt;At least 35 services were vulnerable to one or more of 5 pre-hijacking attacks.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th scope="row"&gt;&lt;a href="https://dl.acm.org/doi/pdf/10.1145/3308558.3313489" class="ext"&gt;Hack for Hire: Exploring the Emerging Market for Account Hijacking&lt;/a&gt;&lt;span class="org"&gt;UC San Diego, Google&lt;/span&gt;&lt;/th&gt;&lt;td&gt;2019&lt;/td&gt;&lt;td&gt;27 English, Russian and Chinese hack-for-hire services&lt;/td&gt;&lt;td&gt;Posing as buyers against synthetic victim identities&lt;/td&gt;&lt;td&gt;5 services succeeded, mostly through tailored phishing.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id="what-to-do"&gt;What to do &lt;a class="heading-anchor" href="#what-to-do" aria-label="Link to section: What to do"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="for-engineers"&gt;For engineers &lt;a class="heading-anchor" href="#for-engineers" aria-label="Link to section: For engineers"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Don&amp;rsquo;t let anyone use an account before they have proven they control its identifier. Verify the email address before the account becomes usable, and before you merge a password account with a federated login for the same address.&lt;/li&gt;
&lt;li&gt;Only trust email addresses from identity providers that verify them. One of the 5 attacks relies on a non-verifying identity provider.&lt;/li&gt;
&lt;li&gt;End all sessions and expire pending email-change links when the password is reset or the email address changes. Two of the attacks rely on unexpired sessions and email changes.&lt;/li&gt;
&lt;li&gt;Offer phishing-resistant factors. The hack-for-hire services got past SMS codes with phishing. See &lt;a href="https://www.janbrennenstuhl.eu/passwordless-authentication/"&gt;passwordless authentication&lt;/a&gt; and my &lt;a href="https://www.janbrennenstuhl.eu/fido-passkeys/"&gt;critical notes on passkeys&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="for-product-and-ux"&gt;For product and UX &lt;a class="heading-anchor" href="#for-product-and-ux" aria-label="Link to section: For product and UX"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Show users which sign-in methods are linked to their account, and notify them when one is added.&lt;/li&gt;
&lt;li&gt;When someone signs up with an address that already has a pending or unverified account, guide them through verification instead of silently signing them in.&lt;/li&gt;
&lt;li&gt;Recovery flows are another takeover path. The &lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/"&gt;account recovery entry&lt;/a&gt; lists the common weaknesses.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-studies-in-detail"&gt;The studies in detail &lt;a class="heading-anchor" href="#the-studies-in-detail" aria-label="Link to section: The studies in detail"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="account-pre-hijacking-attacks-security-failures-in-user-account-creation"&gt;Account Pre-Hijacking Attacks: Security Failures in User Account Creation &lt;a class="heading-anchor" href="#account-pre-hijacking-attacks-security-failures-in-user-account-creation" aria-label="Link to section: Account Pre-Hijacking Attacks: Security Failures in User Account Creation"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;The ubiquity of user accounts in websites and online services makes account hijacking a serious security concern. Although previous research has studied various techniques through which an attacker can gain access to a victim&amp;rsquo;s account, relatively little attention has been directed towards the process of account creation.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;In this study, Avinash Sudhodanan and Andrew Paverd show that there is a whole class of &lt;strong&gt;account pre-hijacking attacks&lt;/strong&gt;. The key point: &amp;ldquo;The distinctive feature of these attacks is that the attacker performs some action before the victim creates an account, which makes it trivial for the attacker to gain access after the victim has created/recovered the account.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The authors assume a realistic attacker who knows only the victim&amp;rsquo;s email address. They describe 5 attacks: Classic-Federated Merge, Unexpired Session, Trojan Identifier, Unexpired Email Change and Non-verifying IdP. Of 75 popular services they analyzed, at least 35 were vulnerable to one or more of them. Some attacks were completely undetectable from the victim&amp;rsquo;s point of view. The paper closes with security requirements that prevent these vulnerabilities.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://arxiv.org/pdf/2205.10174.pdf" class="ext"&gt;Read the paper (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="hack-for-hire-exploring-the-emerging-market-for-account-hijacking"&gt;Hack for Hire: Exploring the Emerging Market for Account Hijacking &lt;a class="heading-anchor" href="#hack-for-hire-exploring-the-emerging-market-for-account-hijacking" aria-label="Link to section: Hack for Hire: Exploring the Emerging Market for Account Hijacking"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In this paper, researchers from UC San Diego and Google &amp;ldquo;study a segment of targeted attackers known as &amp;lsquo;hack for hire&amp;rsquo; services to understand the playbook that attackers use to gain access to victim accounts.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Posing as buyers, they contacted 27 English, Russian and Chinese black-market services, and only 5 succeeded in attacking the synthetic but realistic identities the researchers controlled. The attackers mostly used tailored phishing that could bypass SMS two-factor authentication. The authors also observed low volume, poor customer service and multiple scammers in this market. The paper is a good read if you want to understand the commercial account hijacking ecosystem and the techniques criminals use.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://dl.acm.org/doi/pdf/10.1145/3308558.3313489" class="ext"&gt;Read the paper (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="related"&gt;Related &lt;a class="heading-anchor" href="#related" aria-label="Link to section: Related"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/account-recovery/"&gt;How secure are email-based password resets?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/account-security/reinforced-authentication/"&gt;Do login challenges and risk scoring stop account takeover?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/knowledge-base/oidc/openid-connect-security/"&gt;Where do OpenID Connect implementations break?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>About Jan Brennenstuhl</title><link>https://www.janbrennenstuhl.eu/about/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/about/</guid><pubDate>Thu, 08 Apr 2021 00:00:00 +0200</pubDate><description>&lt;p&gt;Hi. My name is Jan Brennenstuhl, I live and work in Berlin Germany, where I was born and raised. I am a product-minded software engineer, security enthusiast &amp;amp; clean code artist with a huge interest in &lt;a href="https://www.janbrennenstuhl.eu/topics/application-security/"&gt;interdisciplinary software development&lt;/a&gt; and engineering leadership. I am a big fan of cycling sports, coffee &amp;amp; &lt;a href="https://www.rucksackrebellen.de" title="Rucksackrebellen Wander-Blog"&gt;hiking&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I currently work in Berlin as principal engineer, focused on application security and making &lt;a href="https://www.janbrennenstuhl.eu/topics/agentic-engineering/"&gt;agentic engineering&lt;/a&gt; more secure and efficient. I spent years building and operating identity solutions used by millions of customers — balancing UX and security in high-stakes revenue funnels — and have since moved into the broader AppSec space, where I&amp;rsquo;m most interested in the intersection of security, usability, and automation.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve worked as software engineer and lead on e-commerce funnels, rule engines, cloud strategies, IAM and SSO solutions, REST APIs, system integrations, technology research, legacy migrations, decommissioning projects and modularizing monolithic systems — various things, mostly in e-commerce and security. I practiced software archaeology more than I set up greenfield web services.&lt;/p&gt;
&lt;p&gt;I am an internet standards enthusiast, who values open source software and open formats over custom builds. For me, quality software products are created best by small teams of product-minded engineers with a narrow, well-defined business scope and a clear vision. I&amp;rsquo;m especially passionate about leading and influencing engineers as well as creating and operating reliable, secure and maintainable software products.&lt;/p&gt;
&lt;p&gt;I hold a M.Sc. in Computer Science from the &lt;strong&gt;University of Potsdam&lt;/strong&gt;, where I completed my thesis on &lt;em&gt;&amp;ldquo;Certificate Management in the Cloud for Authentication in university Environment&amp;rdquo;&lt;/em&gt;. I’ve also studied Media Informatics at the &lt;strong&gt;Beuth University&lt;/strong&gt; of Applied Sciences in Berlin.&lt;/p&gt;</description></item><item><title>The Purpose of JWT: Stateless Authentication</title><link>https://www.janbrennenstuhl.eu/jwt-stateless-authentication/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/jwt-stateless-authentication/</guid><pubDate>Fri, 28 Apr 2017 00:00:00 +0200</pubDate><description>&lt;p&gt;The demand for reliable and effective authentication methods has increased in the modern, distributed, and fast-paced digital world. Stateless authentication solutions are being used by developers and identity providers to deliver secure and scalable single sign-on solutions. JSON Web Token (JWT) are the new fancy kids around the block when it comes to transporting proofs of identity within an untrusted environment like the web.&lt;/p&gt;
&lt;h2 id="stateless-sessions-thanks-to-json-web-token"&gt;Stateless Sessions Thanks to JSON Web Token &lt;a class="heading-anchor" href="#stateless-sessions-thanks-to-json-web-token" aria-label="Link to section: Stateless Sessions Thanks to JSON Web Token"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While there are many articles that describe specific aspects, &lt;a href="https://dev.to/neilmadden/7-best-practices-for-json-web-tokens" title="7 Best Practices for JSON Web Tokens" class="ext"&gt;best practices&lt;/a&gt; or single use-cases of JWTs, the bigger picture and the actual problem definition is often missing. With JWTs gaining in popularity, that missing knowledge of the fundamental ideas of JSON &lt;a href="https://www.janbrennenstuhl.eu/single-use-jwt/" title="Single-Use JWT: The Power of Stateless One Time Token"&gt;Web Token&lt;/a&gt; leads to questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/21871029/logout-invalidate-a-jwt" class="ext"&gt;How to invalidate a JWT?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/26739167/jwt-json-web-token-automatic-prolongation-of-expiration" class="ext"&gt;How to prolongate a JWTs expiration date?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/41865108/why-should-i-use-jwt-not-simple-hashed-token" class="ext"&gt;Why should I use JWT, not simple hashed token?&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this article, I describe the true purpose of JWT tokens – &lt;strong&gt;Getting rid of stateful authentication!&lt;/strong&gt; – and compare classical, stateful sessions with modern, stateless authentication. Let&amp;rsquo;s start now!&lt;/p&gt;
&lt;h2 id="what-is-jwt"&gt;What is JWT? &lt;a class="heading-anchor" href="#what-is-jwt" aria-label="Link to section: What is JWT?"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="definition"&gt;Definition &lt;a class="heading-anchor" href="#definition" aria-label="Link to section: Definition"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;JSON Web Tokens are a self-contained, URL-safe way of conveying data, unique identifier and claims between two parties in an untrusted environment. They are frequently employed in online applications for the purposes of authentication and authorization of users, transporting proof of authenticity between an identity provider and relying parties.&lt;/p&gt;
&lt;h3 id="components-of-jwt-tokens"&gt;Components of JWT tokens &lt;a class="heading-anchor" href="#components-of-jwt-tokens" aria-label="Link to section: Components of JWT tokens"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;JWTs carry claims that are encoded as JSON object as the payload of a JSON Web Signature (JWS) structure or of a [JSON Web Encryption (JWE)]
(https://www.janbrennenstuhl.eu/jwe/ &amp;ldquo;JWE Token: A Comprehensive Guide&amp;rdquo;) structure, allowing the claims to be encrypted and/or digitally signed in order to protect their integrity. A signed JWT is made up of three components: a header, a payload, and a signature. The header contains metadata, like the type of token and signing algorithm. The claims are stored in the payload and hold details about the particular user and other necessary data. Finally, the signature is used to affirm the token&amp;rsquo;s integrity.&lt;/p&gt;
&lt;p&gt;&lt;figure class="figure"&gt;&lt;picture&gt;&lt;source type="image/avif" srcset="https://www.janbrennenstuhl.eu/jwt-stateless-authentication/jwt_hu_3ec2a5379b49976b.avif 480w, https://www.janbrennenstuhl.eu/jwt-stateless-authentication/jwt_hu_2f84c7cb00261ea9.avif 600w" sizes="(min-width: 760px) 720px, calc(100vw - 2.5rem)"&gt;&lt;img src="https://www.janbrennenstuhl.eu/jwt-stateless-authentication/jwt_hu_9780d59cfa850089.webp" srcset="https://www.janbrennenstuhl.eu/jwt-stateless-authentication/jwt_hu_a84f55b55744eafd.webp 480w, https://www.janbrennenstuhl.eu/jwt-stateless-authentication/jwt_hu_9780d59cfa850089.webp 600w" sizes="(min-width: 760px) 720px, calc(100vw - 2.5rem)" width="600" height="321" alt="A JSON Web Token" loading="lazy" decoding="async"&gt;&lt;/picture&gt;&lt;figcaption&gt;Parts of a signed JWT&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="the-need-for-stateless-authentication"&gt;The Need for Stateless Authentication &lt;a class="heading-anchor" href="#the-need-for-stateless-authentication" aria-label="Link to section: The Need for Stateless Authentication"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Stateless authentication is essential for modern web applications because it eliminates the need for the central authentication server to retain session id and session information. Ideally, this minimizes backend load and enables more effective application scaling. By removing bottlenecks, a decentralized authorization approach is said to simplify system landscape.&lt;/p&gt;
&lt;h3 id="stateful-authentication"&gt;Stateful Authentication &lt;a class="heading-anchor" href="#stateful-authentication" aria-label="Link to section: Stateful Authentication"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the old days of the web, authentication was a purely stateful affair. With a centralized overlord entity being responsible for tokens, the world is fairly simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tokens are issued and stored as stateful session data in a single service for future checking and revocation.&lt;/li&gt;
&lt;li&gt;Clients and resource servers know a single point of truth for token verification and information gathering.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This works rather well in a world of integrated systems, where servers render frontends and dependencies exist on package-level rather than distributed applications.&lt;/p&gt;
&lt;p&gt;In a world where applications are composed by a zoo of microservices however, this stateful authentication approach comes with a couple of serious drawbacks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No service can operate without a synchronous dependency towards the central token store.&lt;/li&gt;
&lt;li&gt;The token overlord, storing session data, becomes an infrastructural bottleneck and a single point of failure.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both facts oppose the fundamental ideas of a stateless services landscape. Stateful authentication introduces not just another dependency for all your single-purpose services (network latency!) but also makes them heavily rely on access to it. Without the full session information and data database being available, authorization decisions can&amp;rsquo;t be taken anymore and everything is doomed.&lt;/p&gt;
&lt;h3 id="stateless-authentication"&gt;Stateless Authentication &lt;a class="heading-anchor" href="#stateless-authentication" aria-label="Link to section: Stateless Authentication"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Stateless token-based authentication describes a system or process, that enables its components to decentrally verify and introspect tokens. This ability to delegate session token verification allows to (partially) get rid of the direct coupling to a central session data database and in that way enables state transfer for authentication proves. The benefits are clear:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Less latency through service-local, decentralized token verification and authorization decisions.&lt;/li&gt;
&lt;li&gt;Increased resilience through less network overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stateless authentication is also able to absolve you from the need to keep track of issued tokens and for that reason removes state (and hence reduces storage) dependencies from your system. The antiquated, heavy-weighted token overlord solution converges to &lt;a href="https://auth0.com/blog/stateless-auth-for-stateful-minds/" title="Auth0: Stateless Sessions for Stateful Minds" class="ext"&gt;to yet another microservice&lt;/a&gt; being mainly responsible for authentication and token issuing.&lt;/p&gt;
&lt;h3 id="stateful-vs-stateless"&gt;Stateful vs. Stateless &lt;a class="heading-anchor" href="#stateful-vs-stateless" aria-label="Link to section: Stateful vs. Stateless"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Today, an authentication system has to support stateless architecture service landscapes mainly characterized by fleets of thousands of services and millions of actors. Central bottlenecks by design become an operational burden. However there are no silver bullets, JWTs ain’t Swiss army knifes and also stateful authentication has its righteous place.&lt;/p&gt;
&lt;p&gt;If you really need a central authentication system to persist session data or if you simply don&amp;rsquo;t trust people &lt;a href="https://www.chosenplaintext.ca/2015/03/31/jwt-algorithm-confusion.html" title="Critical vulnerabilities in JSON Web Token libraries" class="ext"&gt;or library source code&lt;/a&gt; to correctly verify session information in your JWTs, a stateful overlord approach is still the way to go and there is nothing wrong about it.&lt;/p&gt;
&lt;p&gt;&lt;figure class="figure"&gt;&lt;picture&gt;&lt;source type="image/avif" srcset="https://www.janbrennenstuhl.eu/jwt-stateless-authentication/stateful-vs-stateless_hu_5d638925703258d0.avif 480w, https://www.janbrennenstuhl.eu/jwt-stateless-authentication/stateful-vs-stateless_hu_3ea23d89eb8c3197.avif 600w" sizes="(min-width: 760px) 720px, calc(100vw - 2.5rem)"&gt;&lt;img src="https://www.janbrennenstuhl.eu/jwt-stateless-authentication/stateful-vs-stateless_hu_bbe3df90500d504.webp" srcset="https://www.janbrennenstuhl.eu/jwt-stateless-authentication/stateful-vs-stateless_hu_c510f3780ae8d2b8.webp 480w, https://www.janbrennenstuhl.eu/jwt-stateless-authentication/stateful-vs-stateless_hu_bbe3df90500d504.webp 600w" sizes="(min-width: 760px) 720px, calc(100vw - 2.5rem)" width="600" height="356" alt="Google Trends on Stateful vs Stateless" loading="lazy" decoding="async"&gt;&lt;/picture&gt;&lt;figcaption&gt;The World becomes Stateless - Google Trends&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="how-jwt-enables-stateless-authentication"&gt;How JWT Enables Stateless Authentication &lt;a class="heading-anchor" href="#how-jwt-enables-stateless-authentication" aria-label="Link to section: How JWT Enables Stateless Authentication"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="token-based-authentication"&gt;Token-based authentication &lt;a class="heading-anchor" href="#token-based-authentication" aria-label="Link to section: Token-based authentication"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Stateless authentication get enabled through the use of stateless tokens (JWT). The authentication server generates these token, which are self-contained and carry all necessary details about the session and the user. In order to avoid the backend from having to keep track of any session ID and session data, the client stores this token and includes it in subsequent requests.&lt;/p&gt;
&lt;h3 id="json-web-signature-jws"&gt;JSON Web Signature (JWS) &lt;a class="heading-anchor" href="#json-web-signature-jws" aria-label="Link to section: JSON Web Signature (JWS)"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To guarantee the authenticity and integrity of the token, JWT session token must always use JWS. Because the private key material used to create this digital signature is only known to the server, it prevents unauthorized modification of the token.&lt;/p&gt;
&lt;h2 id="pros-and-cons-of-stateless-authentication-with-jwt"&gt;Pros and Cons of Stateless Authentication with JWT &lt;a class="heading-anchor" href="#pros-and-cons-of-stateless-authentication-with-jwt" aria-label="Link to section: Pros and Cons of Stateless Authentication with JWT"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="advantages"&gt;Advantages &lt;a class="heading-anchor" href="#advantages" aria-label="Link to section: Advantages"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Scalability: Stateless authentication removes architectural bottlenecks, can reduce server load and allows for easier horizontal scaling.&lt;/li&gt;
&lt;li&gt;Performance: Less server overhead means faster response times.&lt;/li&gt;
&lt;li&gt;Simplified architecture: No need to manage sessions stored server-side.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="disadvantages"&gt;Disadvantages &lt;a class="heading-anchor" href="#disadvantages" aria-label="Link to section: Disadvantages"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Token size: Due to their metadata overhead, JWTs are generally larger than traditional session cookies, increasing bandwidth usage.&lt;/li&gt;
&lt;li&gt;Token theft: If a token is stolen, it can be used until it expires, posing a security risk.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="understanding-jwt-workflow"&gt;Understanding JWT Workflow &lt;a class="heading-anchor" href="#understanding-jwt-workflow" aria-label="Link to section: Understanding JWT Workflow"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One popular way to achieve stateless authentication is defined in &lt;a href="https://tools.ietf.org/html/rfc7523" title="JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants" class="ext"&gt;RFC 7523&lt;/a&gt; and leverages the OAuth 2.0 Authorization Framework (&lt;a href="https://tools.ietf.org/html/rfc6749" title="The OAuth 2.0 Authorization Framework" class="ext"&gt;RFC 6749&lt;/a&gt;) by combining it with signed JWT (&lt;a href="https://tools.ietf.org/html/rfc7519" title="JSON Web Token (JWT)" class="ext"&gt;RFC 7519&lt;/a&gt;, &lt;a href="https://tools.ietf.org/html/rfc7515" title="JSON Web Signature (JWS)" class="ext"&gt;RFC 7515&lt;/a&gt;). Instead of storing the token-to-principal relationship in a database in a stateful manner, cryptographic signatures allow decentralized clients to securely store and grant access, without need to retrieve data from a central system for every inbound request.&lt;/p&gt;
&lt;p&gt;Stateless tokens are also a key component of OpenID Connect (OIDC), an identity layer solution built on top of the OAuth 2.0 protocol. OpenID Connect specifies industry-standard flows that allow clients to access basic profile information about the end-user in an interoperable way and to confirm the end-user&amp;rsquo;s identity based on the authentication carried out by an authorization server.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Using a JWT as a bearer for authorization, you can statelessly verify if the user is authenticated by simply checking if the expiration in the payload hasn&amp;rsquo;t expired and if the signature is valid.”
— &lt;cite&gt;&lt;a href="http://jonatan.nilsson.is/stateless-tokens-with-jwt/" title="Stateless tokens with JWT"&gt;Jonatan Nilsson&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With tokens not being opaque but locally introspectable, clients can retrieve addition information about the corresponding identity directly from the token without the need of calling another remote API. The following is a simplified, non-normative lifecycle example of a stateless JWT.&lt;/p&gt;
&lt;h3 id="token-creation"&gt;Token Creation &lt;a class="heading-anchor" href="#token-creation" aria-label="Link to section: Token Creation"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;The user submits their credentials (e.g., username and password) to the authentication system.&lt;/li&gt;
&lt;li&gt;The server authenticates the actor by verifying the credentials and generates a JWT containing user-related claims.&lt;/li&gt;
&lt;li&gt;The server signs the token using a private key and returns it to the client side.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="token-verification"&gt;Token Verification &lt;a class="heading-anchor" href="#token-verification" aria-label="Link to section: Token Verification"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;The client includes the JWT as bearer token within the Authorization header in subsequent requests.&lt;/li&gt;
&lt;li&gt;The resource server verifies the token&amp;rsquo;s signature and validates the claims.&lt;/li&gt;
&lt;li&gt;If the token is valid and authorization successful, the resource server processes the request and returns the appropriate response.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="token-expiration"&gt;Token Expiration &lt;a class="heading-anchor" href="#token-expiration" aria-label="Link to section: Token Expiration"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;JWTs typically include an expiration time to limit their validity.&lt;/li&gt;
&lt;li&gt;Once the token expires, the client must request a new token by re-authenticating with the authorization server.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="use-cases-for-jwt"&gt;Use Cases for JWT &lt;a class="heading-anchor" href="#use-cases-for-jwt" aria-label="Link to section: Use Cases for JWT"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Authorization: Securely authorize actors based on user claims like roles and permissions without relying on server-side sessions.&lt;/li&gt;
&lt;li&gt;Information Exchange: Securely transmit information between parties in untrusted environments.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="security-concerns--considerations"&gt;Security Concerns &amp;amp; Considerations &lt;a class="heading-anchor" href="#security-concerns--considerations" aria-label="Link to section: Security Concerns &amp;amp; Considerations"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Token storage: Store tokens in a secure location on the client side, such HttpOnly cookies or other safe places.&lt;/li&gt;
&lt;li&gt;Transport security: Use HTTPS to protect tokens from being intercepted during transmission.&lt;/li&gt;
&lt;li&gt;Token revocation: By design, JWTs are not remotely revokable. To revoke tokens in case of token theft or user logout requires, a stateful mechanism to be in place – which sort of &lt;a href="https://web.archive.org/web/20241106205450/https://www.dinochiesa.net/?p=1388" title="Revoking or Blacklisting JWT" class="ext"&gt;counters the stateless approach&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Token update: There is no way of altering an issued JWT. Prolongating its expiration date for example is not possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="best-practices-for-jwt-implementation"&gt;Best Practices for JWT Implementation &lt;a class="heading-anchor" href="#best-practices-for-jwt-implementation" aria-label="Link to section: Best Practices for JWT Implementation"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use short expiration times&lt;/strong&gt;: Limit the window of opportunity for token theft.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rotate private keys&lt;/strong&gt;: Regularly update the signing key to mitigate risks associated with key compromise.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validate tokens&lt;/strong&gt;: Before processing requests, always check the tokens validity on the authorizing backend.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="heading-anchor" href="#conclusion" aria-label="Link to section: Conclusion"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In modern web applications, JWTs offer a reliable and adaptable stateless authentication method. Developers may create secure, scalable, and effective apps that satisfy the requirements of today&amp;rsquo;s digital ecosystem by utilizing their advantages and following best practices.&lt;/p&gt;
&lt;h2 id="faqs"&gt;FAQs &lt;a class="heading-anchor" href="#faqs" aria-label="Link to section: FAQs"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="what-is-the-main-purpose-of-using-jwt-in-stateless-authentication"&gt;What is the main purpose of using JWT in stateless authentication? &lt;a class="heading-anchor" href="#what-is-the-main-purpose-of-using-jwt-in-stateless-authentication" aria-label="Link to section: What is the main purpose of using JWT in stateless authentication?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The major goal is enhanced scalability and performance by securely authorizing users without relying on server-side sessions.&lt;/p&gt;
&lt;h3 id="how-can-i-prevent-jwt-theft"&gt;How can I prevent JWT theft? &lt;a class="heading-anchor" href="#how-can-i-prevent-jwt-theft" aria-label="Link to section: How can I prevent JWT theft?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Tokens must be stored securely on the client side and transmitted encrypted using HTTPS. If stateful revocation procedures are not implemented, tokens should have a short expiration time.&lt;/p&gt;
&lt;h3 id="can-i-use-jwt-for-authorization-as-well-as-authentication"&gt;Can I use JWT for authorization as well as authentication? &lt;a class="heading-anchor" href="#can-i-use-jwt-for-authorization-as-well-as-authentication" aria-label="Link to section: Can I use JWT for authorization as well as authentication?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;JWTs can function as bearer tokens. Authorization decisions can be made either purely on token validity or take into consideration claims carried by the token.&lt;/p&gt;
&lt;h3 id="do-i-need-to-store-jwt-session-data-in-a-database"&gt;Do I need to store JWT session data in a database? &lt;a class="heading-anchor" href="#do-i-need-to-store-jwt-session-data-in-a-database" aria-label="Link to section: Do I need to store JWT session data in a database?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;No, JWTs are self-contained and do not require server-side storage. Actually that would be an anti-pattern.&lt;/p&gt;
&lt;h3 id="how-do-i-handle-jwt-expiration"&gt;How do I handle JWT expiration? &lt;a class="heading-anchor" href="#how-do-i-handle-jwt-expiration" aria-label="Link to section: How do I handle JWT expiration?"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Implement a mechanism for clients to request a new token when the existing one expires. OAuth 2.0 for example distinguishes between access token and refresh token and defines protocols on how to continuously refresh tokens without need to actively re-authenticate the user.&lt;/p&gt;</description></item><item><title>On Making Spring Security OAuth RFC-compliant</title><link>https://www.janbrennenstuhl.eu/spring-security-oauth-rfc/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/spring-security-oauth-rfc/</guid><pubDate>Wed, 01 Feb 2017 00:00:00 +0100</pubDate><description>&lt;p&gt;Often supporting open source software is just fixing one tiny thing you stumbled upon. However, getting ready and diving into even the smallest piece of source-code can lead to surprising results. I fixed a small HTTP header extractor for the &lt;a href="https://github.com/spring-projects/spring-security-oauth" class="ext"&gt;Spring Security OAuth&lt;/a&gt; project recently. Here&amp;rsquo;s what happened.&lt;/p&gt;
&lt;h2 id="i-fixed-something-for-me"&gt;I fixed something for me &lt;a class="heading-anchor" href="#i-fixed-something-for-me" aria-label="Link to section: I fixed something for me"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At the very least, fixing this issue has made me happier. The problem was that the Spring Security OAuth &lt;code&gt;BearerTokenExtractor&lt;/code&gt; was not acting in compliance to &lt;a href="https://tools.ietf.org/html/rfc7230#section-3.2.2" class="ext"&gt;RFC7230&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Every time someone sends a request with multiple, comma-separated Authorization-Header values towards an application I am currently developing the extractor would fail in doing its job. The application would simply not accept the yet valid (and RFC compliant) request.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;RFC7230, Section 3.2.2&lt;/strong&gt; - A sender MUST NOT generate multiple header fields with the same field name in a message
unless either the entire field value for that header field is defined as a comma-separated list [i.e., #(values)] &amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="i-fixed-something-for-someone-else"&gt;I fixed something for someone else &lt;a class="heading-anchor" href="#i-fixed-something-for-someone-else" aria-label="Link to section: I fixed something for someone else"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is a guess, but if I found this an issue then we can presume at least one other person out there on the internet did. Also, being RFC-compliant usually is a good thing and every library should handle user-generated input as resilient as possible.&lt;/p&gt;
&lt;h2 id="i-learned-more-about-library-maintenance"&gt;I learned more about Library Maintenance &lt;a class="heading-anchor" href="#i-learned-more-about-library-maintenance" aria-label="Link to section: I learned more about Library Maintenance"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I started by making a mistake. My original fix was a custom implementation of the &lt;code&gt;TokenExtractor&lt;/code&gt; interface that is also implemented by the original &lt;code&gt;BearerTokenExtractor&lt;/code&gt; within my application. This however would require me to maintain and test this piece of code that is not part of my actual business logic. I would totally loose the advantages of abstraction through a battle-proven library. It also ignored the problems true essence.&lt;/p&gt;
&lt;p&gt;That thought lead me to try again. This time I cloned the Spring Security OAuth project and tried copy-and-pasting my slim Java8 Streams API based &lt;code&gt;TokenExtractor&lt;/code&gt; and its tests into the library. This lead to a bunch of discoveries about library maintenance — Spring Security OAuth&amp;hellip;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;hellip; is written in Java6,&lt;/li&gt;
&lt;li&gt;&amp;hellip; has only other Spring projects as dependencies,&lt;/li&gt;
&lt;li&gt;&amp;hellip; needs to be backward compatible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, if you plan to support a project that is out there for a while, keep in mind to leave all your fancy tooling at home. Also try to read and follow the projects code and style guidelines before receiving requests for change in your pull-requests.&lt;/p&gt;
&lt;p&gt;Of course, as with anything around the globe, &lt;a href="https://github.com/spring-projects/spring-security-oauth/blob/master/CODE_OF_CONDUCT.adoc" class="ext"&gt;there is even more to this than meet the eye&lt;/a&gt;. However, this was &lt;a href="https://github.com/spring-projects/spring-security-oauth/pull/895" class="ext"&gt;my resulting pull request&lt;/a&gt; &lt;del&gt;and it is waiting to get merged&lt;/del&gt;.&lt;/p&gt;
&lt;h2 id="i-learned-more-about-http-headers"&gt;I learned more about HTTP Headers &lt;a class="heading-anchor" href="#i-learned-more-about-http-headers" aria-label="Link to section: I learned more about HTTP Headers"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the beginning, I learned about the diversity of HTTP Headers. Being spoiled by all these framework abstraction layers nowadays, it hit me that HTTP Headers are simply yet another interface. And we want to handle all interface interaction in the most resilient way.&lt;/p&gt;
&lt;p&gt;Inspired by some of my colleagues, I started to delve into RFCs. I started with &lt;a href="https://tools.ietf.org/html/rfc6750" class="ext"&gt;RFC6750&lt;/a&gt; (describing the Bearer Token Usage within OAuth 2.0) and ended up in the even more fundamental &lt;a href="https://tools.ietf.org/html/rfc7230" class="ext"&gt;RFC7230&lt;/a&gt; (on Message Syntax and Routing of the Hypertext Transfer Protocol).&lt;/p&gt;
&lt;p&gt;Now I am more familiar with the possible appearances of HTTP Headers and the work behind the Spring Security OAuth project.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;With my fix in one of the next releases, Spring Security OAuth is going to also be able to handle requests like this:&lt;/del&gt;&lt;/p&gt;
&lt;figure class="code" data-lang="text"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" aria-label="Code" class="chroma"&gt;&lt;code data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /presence/alice HTTP/1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host: server.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Authorization: Basic YXNkZnNhZGZzYWRmOlZLdDVOMVhk, Bearer mF_9.B5f-4.1JqM&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Update 16.02.2017:&lt;/strong&gt; As Joe Grandja (Spring Security Engineer) argued, the user agent is supposed to choose &lt;em&gt;&amp;ldquo;only 1 of the challenges (if there is more than 1 challenge) to authenticate against&amp;rdquo;&lt;/em&gt;, so my pull request was rejected. Feel free to read all the comments in the &lt;a href="https://github.com/spring-projects/spring-security-oauth/issues/894" class="ext"&gt;corresponding issue&lt;/a&gt; for all the details.&lt;/p&gt;
&lt;h2 id="the-simplest-piece-of-work-can-lead-you-anywhere"&gt;The simplest piece of work can lead you anywhere &lt;a class="heading-anchor" href="#the-simplest-piece-of-work-can-lead-you-anywhere" aria-label="Link to section: The simplest piece of work can lead you anywhere"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I just wanted to make the Bearer Token extraction more resilient. Yet, this lead to a ticket and a pull request, a rabbit hole of discovery about HTTP Headers and open source library maintenance and the motivation to write a blog post about it. Ultimately, I did get what I wanted in the first place though: More fun during work.&lt;/p&gt;
&lt;p&gt;Open source is a lot of things to a lot of people. To me, it&amp;rsquo;s a way to learn while I help, however small the task may seem. I&amp;rsquo;d love for you to share with &lt;a href="https://twitter.com/jbspeakr" class="ext"&gt;me on Twitter&lt;/a&gt; what open source means to you.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;small&gt;This post was heavily &lt;a href="https://philna.sh/blog/2017/01/27/on-fixing-a-favicon/" class="ext"&gt;inspired by Phil Nash&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description></item></channel></rss>