<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Agentic Engineering · Brennenstuhl on Security</title><link>https://www.janbrennenstuhl.eu/topics/agentic-engineering/</link><description>Building software with coding agents, and giving agents scoped, revocable authority over the tools they use.</description><language>en-GB</language><copyright>Original writing CC BY 4.0, Jan Brennenstuhl</copyright><atom:link href="https://www.janbrennenstuhl.eu/topics/agentic-engineering/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>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>What I Learned Building an Identity Broker With Coding Agents</title><link>https://www.janbrennenstuhl.eu/agentic-identity-broker/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/agentic-identity-broker/</guid><pubDate>Thu, 24 Sep 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;On 18 September 2026, Magnus Jungsbluth and I presented the &lt;a href="https://agenticidentitybroker.dev/" title="Agentic Identity Broker documentation" class="ext"&gt;Agentic Identity Broker&lt;/a&gt; at &lt;a href="https://agntconmcpconeu26.sched.com/event/2RBAI" title="Economies of Scale for MCP and Agents: Why You Need an Identity Broker" class="ext"&gt;AGNTCon + MCPCon Europe&lt;/a&gt; in Amsterdam. We had published &lt;a href="https://github.com/zalando-incubator/agentic-identity-broker" title="Agentic Identity Broker source repository" class="ext"&gt;its source code&lt;/a&gt; under the MIT license 3 days earlier. The broker lets people in enterprise environments give an AI agent scoped, revocable access to services such as GitHub or Google without handing the agent their credentials.&lt;/p&gt;
&lt;p&gt;Magnus is my mentor and the mastermind behind the broker, and I&amp;rsquo;ve been his sidekick since we started at the end of 2025. We built the broker with coding agents from the first prototype in January 2026, put the first Model Context Protocol (MCP) server behind it in production in March, and had the first users in April. Over those 10 months, I switched agent harnesses 6 times and worked with 9 models from Anthropic and OpenAI. What kept the project on track through all those changes was the spec work we did up front and the effort we put into verifying every change. Most of what I learned is about specs, tests, and review.&lt;/p&gt;
&lt;h2 id="why-we-started-with-agent-identity"&gt;Why We Started With Agent Identity &lt;a class="heading-anchor" href="#why-we-started-with-agent-identity" aria-label="Link to section: Why We Started With Agent Identity"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Around the end of 2025, new Claude Sonnet and Opus models pushed the hype around agents through the roof. From a platform and security perspective, Magnus and I could see where that would lead. Without central capabilities that come with guardrails, every team would connect its agents to tools in its own way, and cleaning that up later would be very difficult. So we set out to solve the hard parts first: agent identity and access to tools. As far as we could tell, no product covered this at the time.&lt;/p&gt;
&lt;p&gt;The quickest way to connect an agent to a tool is a robot account, where the agent holds a long-lived credential for each MCP server or API it calls. That breaks down as soon as several people share the agent. The agent then acts with the combined permissions of all its users, nobody can tell whose request was whose, and anything that tricks the agent can reach for those credentials. I made the case for &lt;a href="https://www.janbrennenstuhl.eu/appsec-agentic-engineering/" title="AppSec in the Age of Agentic Engineering"&gt;delegation and consent infrastructure&lt;/a&gt; from the AppSec side earlier this year.&lt;/p&gt;
&lt;p&gt;The broker keeps both the user and the agent in every authorization decision. 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. The broker stores the provider tokens encrypted. On each tool call, an MCP gateway such as &lt;a href="https://agentgateway.dev/" title="agentgateway" class="ext"&gt;agentgateway&lt;/a&gt; exchanges the agent&amp;rsquo;s token for the matching provider token through &lt;a href="https://www.rfc-editor.org/rfc/rfc8693" title="RFC 8693: OAuth 2.0 Token Exchange" class="ext"&gt;OAuth 2.0 Token Exchange (RFC 8693)&lt;/a&gt;, so the provider token never reaches the agent.&lt;/p&gt;
&lt;p&gt;Magnus and I describe the platform around the broker and the reasoning behind its design in &lt;a href="https://engineering.zalando.com/posts/2026/09/agentic-platform-open-sourcing-agentic-identity-broker.html" title="Agentic Platform: Open-Sourcing the Agentic Identity Broker" class="ext"&gt;the post that announced the release&lt;/a&gt;, and our &lt;a href="https://agenticidentitybroker.dev/docs/presentations/2026-09-18_agntcon-mcpcon-agentic-identity-broker.pdf" title="Economies of Scale for MCP and Agents" class="ext"&gt;talk slides&lt;/a&gt; explain the delegation model. Alejandro Saucedo, who adopted the broker for his Kubernetes Agent Orchestration System (KAOS), covers the identity side in his series &lt;a href="https://ethical.institute/blog/agentic-security-and-identity-part-1/" title="Agentic Security &amp;amp; Identity, Part 1" class="ext"&gt;Agentic Security &amp;amp; Identity&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="we-used-spec-kit-from-the-first-day"&gt;We Used Spec Kit From the First Day &lt;a class="heading-anchor" href="#we-used-spec-kit-from-the-first-day" aria-label="Link to section: We Used Spec Kit From the First Day"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Magnus had already experimented with GitHub&amp;rsquo;s &lt;a href="https://github.com/github/spec-kit" title="Spec Kit source repository" class="ext"&gt;Spec Kit&lt;/a&gt; before we started, and he did most of the heavy upfront work on our constitution. With Spec Kit, a team writes its binding principles into a constitution. For each feature, an agent then drafts a specification, a technical plan, and a task list before it writes any code. A newer command, &lt;a href="https://github.com/github/spec-kit/blob/main/docs/reference/agentic-sdd.md" title="Spec Kit: Agentic spec-driven development" class="ext"&gt;&lt;code&gt;/speckit.converge&lt;/code&gt;&lt;/a&gt;, checks the implementation against all 3 and appends tasks for the gaps it finds. We run implement and converge in turns until converge reports no gaps.&lt;/p&gt;
&lt;p&gt;The broker repository shows how much of this piled up in 10 months. As of 26 September, it holds 42 feature specs, 38 architecture decision records (ADRs), and a &lt;a href="https://github.com/zalando-incubator/agentic-identity-broker/blob/main/.specify/memory/constitution.md" title="Agentic Identity Broker constitution" class="ext"&gt;constitution&lt;/a&gt; with 13 principles at version 2.1.0. Among other things, the principles require that the broker fails closed and forbid custom cryptography. An &lt;code&gt;AGENTS.md&lt;/code&gt; file at the root sends every agent to the constitution, the relevant ADRs, and more specific &lt;code&gt;AGENTS.md&lt;/code&gt; files for each part of the code base.&lt;/p&gt;
&lt;p&gt;All that setup cost time before the first feature existed, and it pays off every day now. Whether I start an agent on a feature or a new contributor does, the agent reads the same principles, decisions, and earlier specs.&lt;/p&gt;
&lt;p&gt;To start a similar project today, I&amp;rsquo;d own the spec work myself, hand the building to agents, and put more agents on review than on writing.&lt;/p&gt;
&lt;h2 id="early-models-wrote-tests-that-tested-nothing"&gt;Early Models Wrote Tests That Tested Nothing &lt;a class="heading-anchor" href="#early-models-wrote-tests-that-tested-nothing" aria-label="Link to section: Early Models Wrote Tests That Tested Nothing"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The models I used in the first months of 2026 failed mostly by inventing things I never asked for and claiming things that weren&amp;rsquo;t true. Tests were our biggest problem, and for code that holds other people&amp;rsquo;s credentials, a passing test suite has to mean something. In those months, I regularly got green test suites for broken behavior. Agents implemented tests halfway or wrote assertions that didn&amp;rsquo;t check anything. Magnus and I spent most of our time getting them to write proper tests.&lt;/p&gt;
&lt;p&gt;The constitution records that fight. It requires red-green-refactor test-driven development (TDD), where every test fails before the implementation exists, and a 1:1 mapping from each spec to an end-to-end (E2E) test that covers a complete user flow. Its version history shows that we added the E2E principle later, extended it to browser tests for the frontend, and clarified the rules for the red phase twice.&lt;/p&gt;
&lt;p&gt;As of 26 September, the public repository contains about 105,000 lines of Go test code and about 49,000 lines of Go production code, counting non-blank, non-comment lines. We didn&amp;rsquo;t plan that ratio. About a quarter of the test code is E2E tests, which the constitution requires for every spec. I still think the broker needs more tests. I&amp;rsquo;d love to have a performance test suite and dedicated compliance checks against the RFCs the broker implements. Right now my agents and I are working on the stability, structure, and run time of the existing suites.&lt;/p&gt;
&lt;h2 id="i-wrote-skills-for-the-libraries-the-models-didnt-know"&gt;I Wrote Skills for the Libraries the Models Didn&amp;rsquo;t Know &lt;a class="heading-anchor" href="#i-wrote-skills-for-the-libraries-the-models-didnt-know" aria-label="Link to section: I Wrote Skills for the Libraries the Models Didn’t Know"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The models&amp;rsquo; knowledge of the less common libraries we use was really bad. The broker encrypts tokens before storing them with the Go releases of the AWS Encryption SDK and the AWS Cryptographic Material Providers Library, and Claude failed hard at wiring them together. So I wrote a dedicated &lt;a href="https://github.com/zalando-incubator/agentic-identity-broker/tree/main/.agents/skills/aws-crypto-go" title="aws-crypto-go skill" class="ext"&gt;skill&lt;/a&gt; that the agent loads when a task touches encryption. The skill explains how the pieces fit together, includes a reference and complete examples, and tells the agent never to answer from its training data alone. I still make the cryptography decisions myself.&lt;/p&gt;
&lt;p&gt;The repository holds a second &lt;a href="https://github.com/zalando-incubator/agentic-identity-broker/tree/main/.agents/skills/jwx-guide-v4" title="jwx-guide-v4 skill" class="ext"&gt;skill&lt;/a&gt; of this kind for version 4 of jwx, the library the broker uses for JSON Web Tokens (JWTs). It tells the agent where to look up the current API before it answers, because earlier versions of that library have a different API.&lt;/p&gt;
&lt;h2 id="why-i-switched-harnesses-6-times"&gt;Why I Switched Harnesses 6 Times &lt;a class="heading-anchor" href="#why-i-switched-harnesses-6-times" aria-label="Link to section: Why I Switched Harnesses 6 Times"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For the first 4 months, I used Claude Code, mostly with Sonnet 4.5 and 4.6 and some Opus 4.6 on the side. It felt too heavy and talkative for me, so I moved to &lt;a href="https://pi.dev/" title="Pi coding agent" class="ext"&gt;Pi&lt;/a&gt; and spent 2 months customizing it. With Pi, I switched from Claude models to GPT-5.4, then GPT-5.5 and GPT-5.6 Terra. After that, I went back and forth between Pi and &lt;a href="https://omp.sh/" title="oh-my-pi" class="ext"&gt;oh-my-pi (OMP)&lt;/a&gt;, an opinionated fork of Pi, for about a month. The full sequence was Claude Code, Pi, OMP, Pi, OMP, Pi, and finally OMP, which has been my only harness for the last 2 months. Since we published the broker, I&amp;rsquo;ve worked with GPT-6 Sol, GPT-6 Astra, and Claude Fable 5.1, and the agents got better with each step.&lt;/p&gt;
&lt;p&gt;Most switches came down to harness details. Early OMP felt more autonomous and proactive than Pi, which I didn&amp;rsquo;t always want. In Pi, I really liked the &lt;a href="https://github.com/apmantza/pi-lens" title="pi-lens source repository" class="ext"&gt;pi-lens&lt;/a&gt; extension&amp;rsquo;s support for &lt;a href="https://github.com/opengrep/opengrep" title="Opengrep source repository" class="ext"&gt;Opengrep&lt;/a&gt;, an open-source static analysis engine. OMP is much better nowadays, although I still fight with its advisor, a second model that reads every turn of the main agent and adds notes. I regularly turn the advisor off and (a few days later) on again. I talked about my setup in more detail on the &lt;a href="https://bvc.fm/2026/08/13/010.html" title="When Coding Agents Ship at Machine Speed, AppSec Has to Move Into the Loop" class="ext"&gt;Beyond Vibe Coding podcast&lt;/a&gt; in August.&lt;/p&gt;
&lt;p&gt;What the agents knew about the project never depended on the harness, because the constitution, the specs, the ADRs, the &lt;code&gt;AGENTS.md&lt;/code&gt; files, and the skills live in the repository.&lt;/p&gt;
&lt;p&gt;Anyone starting now should pick a strong harness with good tool support, such as documentation lookup through &lt;a href="https://context7.com/" title="Context7" class="ext"&gt;Context7&lt;/a&gt; or web search through &lt;a href="https://exa.ai/" title="Exa" class="ext"&gt;Exa&lt;/a&gt;, and shouldn&amp;rsquo;t shy away from frontier models. I found them worth every penny for the broker.&lt;/p&gt;
&lt;h2 id="review-takes-more-agents-than-writing"&gt;Review Takes More Agents Than Writing &lt;a class="heading-anchor" href="#review-takes-more-agents-than-writing" aria-label="Link to section: Review Takes More Agents Than Writing"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For the release on 15 September, I squashed the private history into a single public commit. Agents helped remove internal references, build the documentation site, and run security reviews, while I worked on our &lt;a href="https://github.com/ossf/scorecard" title="OpenSSF Scorecard" class="ext"&gt;OpenSSF Scorecard&lt;/a&gt; results (the Open Source Security Foundation&amp;rsquo;s automated checks of a repository&amp;rsquo;s security practices), designed the wordmark logo, and set up the domain&amp;rsquo;s DNS.&lt;/p&gt;
&lt;p&gt;In the first 10 days after the release (15 to 24 September), the repository received 93 pull requests: 51 from me, 7 from Magnus, 26 from Dependabot (GitHub&amp;rsquo;s dependency update bot), and 9 from additional 2 contributors, Alejandro Saucedo and Farasath Ahamed. We merged 58 of them by 24 September.&lt;/p&gt;
&lt;p&gt;Nowadays, some agents are always working on the broker. They harden security, improve the test suites and continuous integration (CI), prepare and implement specs for new features, and review changes. Each agent works in its own git worktree, so parallel agents don&amp;rsquo;t overwrite each other&amp;rsquo;s changes. I try to keep it to 2 or 3 agents at a time, but depending on the day and my meeting schedule, it can be 6 to 8. I start most of them myself.&lt;/p&gt;
&lt;p&gt;Reviewing is the hard part. Early on, I expected &lt;a href="https://www.roborev.io/" title="roborev" class="ext"&gt;roborev&lt;/a&gt;, a local daemon that reviews each commit in the background, to be a great addition to my harness, and I used it extensively. It regularly got lost in endless loops where it fixed and discussed the same or similar issues again and again. Over time it produced more noise and distraction than help. As the models got better and the harnesses got stronger, I left it behind and replaced it with custom review skills in my harness.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/zalando-incubator/agentic-identity-broker/blob/main/.github/agents/architecture-review.agent.md" title="Architecture review agent" class="ext"&gt;architecture review agent&lt;/a&gt; in the repository is one example. It reads the constitution, the ADRs, and the port interfaces from the base branch, so a pull request can&amp;rsquo;t rewrite the rules we judge it by. It defaults to skepticism and looks for what agent-written pull requests tend to do: introduce a parallel mechanism instead of extending an existing one, add domain services that only delegate to repositories, and label tests as end-to-end when they cover a single segment of a flow.&lt;/p&gt;
&lt;p&gt;Today I regularly have more agents reviewing in parallel than writing code. The README promises that we review every pull request. Agents review the code, and I still review the specs and the E2E tests myself.&lt;/p&gt;
&lt;h2 id="what-we-havent-solved-yet"&gt;What We Haven&amp;rsquo;t Solved Yet &lt;a class="heading-anchor" href="#what-we-havent-solved-yet" aria-label="Link to section: What We Haven’t Solved Yet"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The broker solves cases where an agent acts on behalf of a human. Autonomous agents are harder: when no human is in the loop and machines or other agents call internal and external tools such as MCP servers, every approach I know of is still brittle. Central tool approvals are in the works, and the &lt;a href="https://github.com/zalando-incubator/agentic-identity-broker#roadmap" title="Agentic Identity Broker roadmap" class="ext"&gt;roadmap&lt;/a&gt; lists token exchange for agent-to-agent calls, intent-based authorization, and user-facing activity logs.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://agntconmcpconeu26.sched.com/" title="AGNTCon &amp;#43; MCPCon Europe 2026 schedule" class="ext"&gt;AGNTCon&lt;/a&gt; left me with the impression that the whole industry is still working on the same questions, and the standards are still catching up. Christian Posta from Solo.io gave a talk titled &amp;ldquo;What IS an Agent&amp;rsquo;s Identity?&amp;rdquo;, and the Identity Assertion JWT Authorization Grant (ID-JAG) talk by Aaron Parecki from Okta, Paul Carleton from Anthropic, and Joey Orlando from Archestra.AI named adoption by software-as-a-service (SaaS) providers as the missing piece. Some vendors already position early products, while working groups are still writing the underlying specs.&lt;/p&gt;
&lt;p&gt;If you want to try the broker, point your coding agent at the &lt;a href="https://github.com/zalando-incubator/agentic-identity-broker" title="Agentic Identity Broker source repository" class="ext"&gt;repository&lt;/a&gt; and ask it how the broker would fit your setup, or run the &lt;a href="https://agenticidentitybroker.dev/docs/get-started" title="Get started with the Agentic Identity Broker" class="ext"&gt;local stack&lt;/a&gt; and walk through a delegation yourself. Please report vulnerabilities through the process on the &lt;a href="https://agenticidentitybroker.dev/docs/resources/security" title="Security posture" class="ext"&gt;security page&lt;/a&gt;. If you want to exchange ideas on approaches or features, open an issue or reach out to me directly.&lt;/p&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>AppSec in the Age of Agentic Engineering</title><link>https://www.janbrennenstuhl.eu/talks/htw-berlin-agentic-appsec/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/talks/htw-berlin-agentic-appsec/</guid><pubDate>Fri, 03 Jul 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;Guest lecture by Jan Brennenstuhl for the cybersecurity course at Hochschule für Technik und Wirtschaft Berlin (HTW), summer term 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://www.janbrennenstuhl.eu/new-appsec-operating-model/htw-berlin-agentic-appsec-slides.pdf"&gt;Slides (PDF)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.janbrennenstuhl.eu/new-appsec-operating-model/"&gt;Supporting essay: Guest Lecture at HTW Berlin: AppSec in the Age of Agentic Engineering&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;Coding agents write a growing share of production code, so security feedback that arrives after the code exists cannot keep up. The lecture argues that AppSec teams get the most leverage from the harness the agent runs in: the rules, tools, sandboxes and credentials around the model, not the model itself. Three practices follow: deliver security findings while the task is still in the agent&amp;rsquo;s context, run agent tasks in disposable sandboxes with short-lived task-scoped credentials, and measure risk per change instead of per release.&lt;/p&gt;
&lt;p&gt;This is a short reading companion, not a transcript. The supporting essay is the condensed lecture with context and references in accessible HTML.&lt;/p&gt;</description></item><item><title>Guest Lecture at HTW Berlin: AppSec in the Age of Agentic Engineering</title><link>https://www.janbrennenstuhl.eu/new-appsec-operating-model/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/new-appsec-operating-model/</guid><pubDate>Fri, 03 Jul 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;I recently gave a guest lecture to the cybersecurity course at Hochschule für Technik und Wirtschaft Berlin (HTW). The topic was application security (AppSec) in the age of agentic engineering, and how coding agents change the daily work of developers and AppSec teams.&lt;/p&gt;
&lt;p&gt;My central argument: AppSec teams have to move from finding problems after code is written to shaping the systems that coding agents write code inside. Agentic engineering makes weak defaults, slow handoffs, and local exceptions more expensive, so the biggest wins now come from the harness, the platform, and the risk model.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://www.janbrennenstuhl.eu/new-appsec-operating-model/htw-berlin-agentic-appsec-slides.pdf" title="Application Security in the Age of Agentic Engineering"&gt;full slide deck&lt;/a&gt; contains the key points, examples, and references from the session. Below is a condensed version of the lecture with some additional context and links.&lt;/p&gt;
&lt;h2 id="fixing-findings-is-the-new-bottleneck"&gt;Fixing Findings Is the New Bottleneck &lt;a class="heading-anchor" href="#fixing-findings-is-the-new-bottleneck" aria-label="Link to section: Fixing Findings Is the New Bottleneck"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The adoption numbers make this hard to dismiss. &lt;a href="https://www.kaggle.com/whitepaper-the-new-SDLC-with-vibe-coding" title="The New SDLC With Vibe Coding" class="ext"&gt;Google&amp;rsquo;s New SDLC whitepaper&lt;/a&gt; estimates that as of early 2026, 85% of professional developers use AI coding agents regularly, 51% use them daily, and roughly 41% of new code is AI-generated. Addy Osmani, one of the authors, wrote a &lt;a href="https://addyosmani.com/blog/new-sdlc-vibe-coding/" title="The New Software Lifecycle" class="ext"&gt;readable summary&lt;/a&gt; if you don&amp;rsquo;t want to read the whole paper.&lt;/p&gt;
&lt;p&gt;Coding agents don&amp;rsquo;t write one function and wait for review. They write, test, read the failures, rewrite, and verify, often several times per hour. Security scanners can keep up with that loop. The old queue of triage, ticketing, and human remediation can&amp;rsquo;t. At that speed, an AppSec team has plenty of findings and lacks a fast way to turn them into fixes.&lt;/p&gt;
&lt;p&gt;The way to close that gap is to return security feedback while the agent still holds the task in its context, so it can repair the problem in the same session. I&amp;rsquo;d reserve tickets for 2 cases: the in-session loop failed, or new findings surface in artifacts that are already deployed.&lt;/p&gt;
&lt;p&gt;Remediation also changes shape at fleet scale. Instead of hunting down individual findings, the AppSec team designs the fix for a whole vulnerability class, and agents apply it to every affected service. I describe this model in more detail in &lt;a href="https://www.janbrennenstuhl.eu/appsec-agentic-engineering/" title="AppSec in the Age of Agentic Engineering"&gt;AppSec in the Age of Agentic Engineering&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="the-harness-is-the-control-plane"&gt;The Harness Is the Control Plane &lt;a class="heading-anchor" href="#the-harness-is-the-control-plane" aria-label="Link to section: The Harness Is the Control Plane"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The whitepaper offers a useful mental model: an agent is a model plus a harness. The harness is everything around the model: instructions and rule files, tools and Model Context Protocol (MCP) servers, guardrails, sandboxes, orchestration, and observability. The authors estimate the split at roughly 10% model and 90% harness. Osmani gives a public example in his summary: on Terminal Bench 2.0, 1 team moved a coding agent from outside the top 30 into the top 5 by changing only the harness and keeping the same model underneath.&lt;/p&gt;
&lt;p&gt;The harness is also where an AppSec team has the most control. A stronger model helps, but it won&amp;rsquo;t fix unsafe access defaults, missing tests, or an insecure tool configuration on its own. So I&amp;rsquo;d ship security skills, local scanning, and review feedback into the harness, where agents can check and improve their own work before a pull request exists.&lt;/p&gt;
&lt;h2 id="shift-security-down-into-the-platform"&gt;Shift Security Down into the Platform &lt;a class="heading-anchor" href="#shift-security-down-into-the-platform" aria-label="Link to section: Shift Security Down into the Platform"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Shift-left still catches mistakes early, but it doesn&amp;rsquo;t remove the security decisions that every team and every agent has to make. At agent speed, each local workaround becomes a reusable pattern, and architectural drift compounds across the fleet.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why I argued for &lt;a href="https://github.com/kubernetes/sig-security/blob/main/sig-security-docs/papers/shift-down/shift-down-security.md" title="Kubernetes SIG Security: Shifting Down Security" class="ext"&gt;shift-down security&lt;/a&gt;. Instead of asking whether a team implemented authentication correctly, ask why the team needs to implement authentication at all. A mature platform makes that question unnecessary: it exposes APIs with authentication built in, gives workloads scoped identity, and offers a deployment path that is secure by default.&lt;/p&gt;
&lt;p&gt;Hardened base images, service templates, platform-owned delivery pipelines, and workload identity remove whole categories of errors and make the secure path the easy path. In my experience, agents follow it. These constraints move undifferentiated choices into a maintained platform, and teams keep the engineering decisions that make their product different. &lt;a href="https://www.janbrennenstuhl.eu/shift-down-appsec/" title="Shift Down: Why Agentic Engineering Demands Platform-Level Security"&gt;Shift Down: Why Agentic Engineering Demands Platform-Level Security&lt;/a&gt; explains this platform role in more detail.&lt;/p&gt;
&lt;h2 id="give-risk-an-operational-budget"&gt;Give Risk an Operational Budget &lt;a class="heading-anchor" href="#give-risk-an-operational-budget" aria-label="Link to section: Give Risk an Operational Budget"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Agentic engineering also needs security decisions that work at machine speed. Blocking every finding doesn&amp;rsquo;t scale, and neither does ignoring them. I suggested borrowing the &lt;a href="https://sre.google/sre-book/embracing-risk/" title="Embracing Risk" class="ext"&gt;error-budget model&lt;/a&gt; from site reliability engineering (SRE) and applying it to security exposure.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;risk budget&lt;/strong&gt; caps how long a high-risk, reachable vulnerability may stay in production. Reachability analysis turns raw findings into business exposure: a known vulnerability (CVE) in dead code doesn&amp;rsquo;t consume the same budget as the same CVE behind a public API. The budget gives people and agents a clear decision rule: fix what burns the budget, defer what doesn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;Security then becomes a shared operating concern with an accountable number attached. Instead of an impossible demand (fix every finding), the team decides on an exposure window and defends it.&lt;/p&gt;
&lt;h2 id="the-coding-agent-is-an-attack-surface"&gt;The Coding Agent Is an Attack Surface &lt;a class="heading-anchor" href="#the-coding-agent-is-an-attack-surface" aria-label="Link to section: The Coding Agent Is an Attack Surface"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The agent itself belongs in the threat model. Each task is an untrusted workload: it executes arbitrary code and reads dependency metadata, issue descriptions, pull-request comments, and documentation. That creates a large internal code-execution surface and exposes the agent to &lt;a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/" title="OWASP Top 10 for Large Language Model Applications" class="ext"&gt;prompt injection and excessive agency&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A warning in a rule file won&amp;rsquo;t protect against that. Run agent tasks in disposable cages, such as &lt;a href="https://nono.sh/" class="ext"&gt;nono&lt;/a&gt; OS-level sandboxes or &lt;a href="https://firecracker-microvm.github.io/" title="Firecracker" class="ext"&gt;Firecracker microVMs&lt;/a&gt;, and issue short-lived, task-scoped credentials through an identity broker. Persistent roles and long-lived API keys don&amp;rsquo;t belong in an agent context.&lt;/p&gt;
&lt;h2 id="what-i-asked-the-students-to-learn"&gt;What I Asked the Students to Learn &lt;a class="heading-anchor" href="#what-i-asked-the-students-to-learn" aria-label="Link to section: What I Asked the Students to Learn"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I closed the session with direct advice: learn software engineering deeply, and learn to think in platforms. Get comfortable with distributed systems, identity and access management (IAM), observability, infrastructure as code, and the economics of risk.&lt;/p&gt;
&lt;p&gt;Agentic engineering makes AppSec more structural and more software-heavy. The next generation of AppSec engineers will still understand attacks and secure coding, but their biggest impact will come from building paved roads (maintained, secure defaults that teams use without asking), hardening harnesses, and designing systems where insecure choices are rare.&lt;/p&gt;</description></item><item><title>Shift Down: Why Agentic Engineering Demands Platform-Level Security</title><link>https://www.janbrennenstuhl.eu/shift-down-appsec/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/shift-down-appsec/</guid><pubDate>Sun, 14 Jun 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;An organization with 500 engineering teams rarely has a single way to build, deploy, and operate services. It has a preferred path, a few tolerated exceptions, and a long tail of custom setups. Over time, local optimizations pile up on top of historical accidents. Now give every engineer multiple coding agents that produce code at machine speed. The inconsistency does not grow linearly. It compounds.&lt;/p&gt;
&lt;p&gt;This is the core tension of &lt;a href="https://www.janbrennenstuhl.eu/appsec-agentic-engineering/" title="AppSec in the Age of Agentic Engineering"&gt;agentic engineering for AppSec&lt;/a&gt;: Agents amplify whatever patterns exist. Good patterns scale. Bad patterns scale faster. The response most organizations reach for is shift-left: More scanning, earlier detection, faster feedback loops. That helps. But it treats symptoms. The structural answer is &lt;strong&gt;shift-down&lt;/strong&gt;: Embedding security into the platform layer so that insecure choices become difficult or impossible, rather than merely detectable.&lt;/p&gt;
&lt;h2 id="shift-left-distributes-responsibility-shift-down-removes-decisions"&gt;Shift-Left Distributes Responsibility. Shift-Down Removes Decisions. &lt;a class="heading-anchor" href="#shift-left-distributes-responsibility-shift-down-removes-decisions" aria-label="Link to section: Shift-Left Distributes Responsibility. Shift-Down Removes Decisions."&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Shift-left answered the question: &lt;em&gt;Who should own security?&lt;/em&gt; The answer was everyone. Development teams run their own SAST, manage their own dependencies, configure their own infrastructure. The intent was sound. The result, in many organizations, was that hundreds of teams now make thousands of security-relevant decisions independently, with varying expertise and attention.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://cloud.google.com/blog/products/application-development/richard-seroter-on-shifting-down-vs-shifting-left" title="Richard Seroter on Shifting Down vs. Shifting Left" class="ext"&gt;Shift-down asks a different question&lt;/a&gt;: &lt;em&gt;Which security decisions should exist at all?&lt;/em&gt; Instead of teaching every team to build a secure CI/CD pipeline, the platform ships one standard pipeline that verifies, tests, scans, signs, and deploys by default. Instead of auditing IAM policies across services, the platform binds short-lived credentials to Kubernetes workloads automatically. Instead of reviewing pod security settings and container hardening across the fleet, a platform-owned &lt;code&gt;WebService&lt;/code&gt; resource deploys on a managed base image with secure defaults.&lt;/p&gt;
&lt;p&gt;The Kubernetes Security SIG formalized this distinction in their &lt;a href="https://github.com/kubernetes/sig-security/blob/main/sig-security-docs/papers/shift-down/shift-down-security.md" title="Kubernetes SIG Security: Shifting Down Security" class="ext"&gt;shift-down security paper&lt;/a&gt;: Security outcomes improve when platforms absorb complexity that individual teams previously handled alone. The two approaches are complementary. Shift-left catches what slips through. Shift-down reduces what can slip through in the first place.&lt;/p&gt;
&lt;h2 id="agentic-engineering-makes-this-urgent"&gt;Agentic Engineering Makes This Urgent &lt;a class="heading-anchor" href="#agentic-engineering-makes-this-urgent" aria-label="Link to section: Agentic Engineering Makes This Urgent"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Human engineers introduce inconsistency slowly. A team picks a non-standard auth library. Another team forks a deployment template. Over months, drift accumulates. Organizations notice, create governance processes, schedule remediation campaigns.&lt;/p&gt;
&lt;p&gt;Coding agents reproduce inconsistency at machine speed. Every non-standard pattern in the codebase becomes context for generation. Every local workaround becomes a template. Every exception becomes &lt;a href="https://www.devprojournal.com/software-development-trends/devops/in-2024-prepare-to-shift-down-not-left/" title="In 2024, Prepare to Shift Down, Not Left" class="ext"&gt;infinitely scalable&lt;/a&gt;. The risk is not that agents produce insecure code in isolation. It is that they rapidly multiply architectural entropy across the fleet.&lt;/p&gt;
&lt;p&gt;Shift-left tooling (scanners, gates, review agents) catches individual instances after they appear. That was viable when inconsistency grew at human speed. At agent speed, the detection-and-remediation loop cannot keep up. You cannot scan your way out of a problem that regenerates faster than you fix it. The leverage is upstream: Make the inconsistency impossible to produce.&lt;/p&gt;
&lt;h2 id="platforms-as-security-architecture"&gt;Platforms as Security Architecture &lt;a class="heading-anchor" href="#platforms-as-security-architecture" aria-label="Link to section: Platforms as Security Architecture"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Good platforms are opinionated. They encode architectural preferences and reject alternatives. This is not bureaucracy. It is &lt;a href="https://medium.com/google-cloud/shifting-security-down-early-1a42169d05a5" title="Shifting Security Down Early" class="ext"&gt;engineering leverage&lt;/a&gt;: Every abstraction that removes a choice also removes an opportunity for mistakes.&lt;/p&gt;
&lt;p&gt;Base images, Dockerfiles, CI/CD pipelines, pod security contexts: These are platform concerns, not product concerns. When organizations treat them as team responsibilities, they get 500 variations of the same solved problem, each with its own security gaps. The alternative: Product teams declare &lt;em&gt;what&lt;/em&gt; they need, and the platform handles &lt;em&gt;how&lt;/em&gt; it runs securely.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom platform resources&lt;/strong&gt; (Kubernetes CRDs, internal service APIs) abstract entire categories of security decisions. A team declares a &lt;code&gt;WebService&lt;/code&gt; resource. The platform operator provisions a hardened container from a managed base image, injects mTLS sidecars, attaches scoped credentials via workload identity, configures egress policies, and wires observability. No Dockerfile. No pipeline YAML. No security context to misconfigure.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Managed identity services&lt;/strong&gt; issue short-lived, scoped credentials automatically. Teams do not configure service accounts or rotate secrets. They annotate their workload, and the platform binds identity at deploy time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Platform-owned build and delivery pipelines&lt;/strong&gt; compile, test, scan, verify, sign, and deploy artifacts without team-maintained configuration. Security scanning is not opt-in. It is invisible. Teams push code. The platform does the rest.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of these shifts security from &amp;ldquo;a thing teams do&amp;rdquo; to &amp;ldquo;a property teams cannot opt out of&amp;rdquo;. Agents, which follow the path of least resistance by design, naturally produce code that fits within platform constraints rather than working around them.&lt;/p&gt;
&lt;h2 id="appsec-moves-from-enforcement-to-architecture"&gt;AppSec Moves from Enforcement to Architecture &lt;a class="heading-anchor" href="#appsec-moves-from-enforcement-to-architecture" aria-label="Link to section: AppSec Moves from Enforcement to Architecture"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Traditional AppSec reviews decisions made elsewhere. Shift-down AppSec decides which decisions should exist. Instead of asking &lt;em&gt;&amp;ldquo;did this team implement authentication correctly?&amp;rdquo;&lt;/em&gt;, the question becomes &lt;em&gt;&amp;ldquo;why are teams implementing authentication themselves?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This reframes the operating model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;From policy documents to platform primitives.&lt;/strong&gt; The 50-page security standard becomes a set of platform defaults, service templates, and &lt;a href="https://www.openpolicyagent.org/" title="Open Policy Agent" class="ext"&gt;policy-as-code&lt;/a&gt; rules. Coding agents (usually) do not read PDFs. They consume MCPs, CLIs and constraints.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;From reviewing PRs to designing abstractions.&lt;/strong&gt; The highest-leverage work is not catching a broken IAM policy in review. It is designing the identity service so that broken IAM policies cannot be expressed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;From remediation campaigns to platform upgrades.&lt;/strong&gt; When security lives in the platform, fixing a vulnerability class means upgrading the platform once instead of patching hundreds of services individually. The fleet inherits the fix.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This does not eliminate the need for detection. Edge cases exist. Custom integrations break assumptions. New vulnerability classes appear. But detection becomes the fallback, not the primary mechanism.&lt;/p&gt;
&lt;h2 id="the-paradox-less-freedom-more-productivity"&gt;The Paradox: Less Freedom, More Productivity &lt;a class="heading-anchor" href="#the-paradox-less-freedom-more-productivity" aria-label="Link to section: The Paradox: Less Freedom, More Productivity"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Engineers often interpret constraints as a lack of trust. The evidence points the other direction.&lt;/p&gt;
&lt;p&gt;Modern cloud engineers have far less infrastructure freedom than system administrators twenty years ago. They cannot choose their hypervisor, their network stack, or their storage firmware. Yet they are dramatically more productive. Few miss managing physical servers. The same applies to security constraints. Every hour spent on container configuration or pipeline maintenance is an hour not spent on the problem the product engineering team exists to solve. Constraints do not limit productivity. They redirect it toward differentiation.&lt;/p&gt;
&lt;h2 id="where-this-leaves-appsec-teams"&gt;Where This Leaves AppSec Teams &lt;a class="heading-anchor" href="#where-this-leaves-appsec-teams" aria-label="Link to section: Where This Leaves AppSec Teams"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Earlier this year, I argued that &lt;a href="https://www.janbrennenstuhl.eu/appsec-agentic-engineering/" title="AppSec in the Age of Agentic Engineering"&gt;AppSec must become an engineering discipline&lt;/a&gt;: building tooling, shipping remediation at scale, treating risk quantitatively. Shift-down refines the target. The tooling AppSec builds is not primarily scanners and gates. It is platform primitives, secure defaults, and opinionated abstractions that make insecure choices structurally difficult.&lt;/p&gt;
&lt;p&gt;This requires a different skill set. AppSec engineers become platform engineers who specialize in security properties. They design APIs and MCPs, build service templates, contribute to infrastructure abstractions, and maintain (or support) the paved roads that the rest of engineering (and their agents) follow.&lt;/p&gt;
&lt;p&gt;The organizations that will thrive in an agentic world are not those that allow infinite flexibility. They are those that carefully decide where flexibility should exist and where it should not. Shift-left taught us that everyone owns security. Shift-down teaches us that not everything should remain a choice. The future belongs to teams that understand the difference.&lt;/p&gt;</description></item><item><title>AppSec in the Age of Agentic Engineering</title><link>https://www.janbrennenstuhl.eu/appsec-agentic-engineering/</link><guid isPermaLink="true">https://www.janbrennenstuhl.eu/appsec-agentic-engineering/</guid><pubDate>Thu, 14 May 2026 00:00:00 +0200</pubDate><description>&lt;p&gt;In agentic engineering, engineers hand tasks to coding agents that write code, run it, and fix their own mistakes in fast loops. Bartosz Ocytko recently mapped &lt;a href="https://ocytko.net/posts/quo-vadis-agentic-engineering/" title="Quo Vadis, Agentic Engineering?" class="ext"&gt;where agentic engineering is heading&lt;/a&gt;, from a surge of commits on GitHub to bottlenecks in verification, open source, and compute. Most security tooling and processes weren&amp;rsquo;t built for that volume of change. While reading his piece, I kept coming back to 1 question: what does this shift mean for application security (AppSec)?&lt;/p&gt;
&lt;p&gt;Ocytko argues that agentic engineering &lt;a href="https://www.linkedin.com/posts/bartoszocytko_agentic-engineering-relocates-engineering-share-7455367680225677313-04IU" title="Bartosz Ocytko via LinkedIn" class="ext"&gt;will reward organizations with strong engineering foundations&lt;/a&gt;: those that can verify, coordinate, and safely absorb machine-generated change. I think AppSec is part of that foundation. AppSec teams that already build tooling, run large-scale remediation, and treat risk quantitatively are well placed to make agentic engineering safe at scale. Attackers raise the stakes for strong security engineering, too: &lt;a href="https://cloud.google.com/blog/topics/threat-intelligence/ai-vulnerability-exploitation-initial-access" title="Adversaries Leverage AI for Vulnerability Exploitation, Augmented Operations, and Initial Access" class="ext"&gt;Google&amp;rsquo;s Threat Intelligence Group reports&lt;/a&gt; that AI models lower the barrier for adversaries to develop exploits. In May 2026, the group reported the first threat actor it believes used a zero-day exploit developed with AI.&lt;/p&gt;
&lt;p&gt;The same agents that create the volume can also help with problems that AppSec teams couldn&amp;rsquo;t solve at human scale: too many findings, too few security engineers, and feedback that arrived long after the code was written. I see 3 shifts that decide which AppSec teams keep up:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;From detection to mitigation: prevent findings inside the agent&amp;rsquo;s loop and fix the backlog at fleet scale.&lt;/li&gt;
&lt;li&gt;From writing policies to building tools: ship security tooling into the context that coding agents work in.&lt;/li&gt;
&lt;li&gt;From gatekeeping to partnership: manage security risk together with site reliability engineering (SRE), platform, and cloud engineering teams, the way they already manage reliability.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="findings-pile-up-faster-than-teams-fix-them"&gt;Findings Pile Up Faster Than Teams Fix Them &lt;a class="heading-anchor" href="#findings-pile-up-faster-than-teams-fix-them" aria-label="Link to section: Findings Pile Up Faster Than Teams Fix Them"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most mature organizations already have good visibility into known vulnerability classes. Their scanners cover infrastructure, cloud platforms, application code, and continuous integration and delivery (CI/CD) pipelines. AI adds even more findings: HackerOne argues that &lt;a href="https://www.hackerone.com/blog/ai-vulnerability-discovery-remediation-gap" title="Finding Fast, Fixing Slow: The Crisis of Asymmetric Remediation" class="ext"&gt;AI-powered vulnerability discovery has improved by an order of magnitude&lt;/a&gt;, while remediation hasn&amp;rsquo;t kept up.&lt;/p&gt;
&lt;p&gt;Backlog data shows how far remediation lags behind. Edgescan, a vulnerability management vendor, analyzed its 2024 scanning and penetration testing results in its &lt;a href="https://info.edgescan.com/hubfs/23DOWNLOADABLE%20CONTENT/Vulnerability%20Statistics%20Reports/Edgescan_VulnerabilityStatsReport_2025.pdf" title="Edgescan Vulnerability Statistics Report 2025" class="ext"&gt;Vulnerability Statistics Report 2025&lt;/a&gt;. At enterprises with more than 1,000 employees, 45.4% of the vulnerabilities discovered within 12 months were still open. High and critical findings with the highest predicted exploit probability (an Exploit Prediction Scoring System score above 0.7) took 115.7 days on average to fix, slightly longer than the 109.4 days for those least likely to be exploited. Every finding that nobody fixes grows the backlog and extends the exposure window, the time during which an attacker can exploit the vulnerability in production.&lt;/p&gt;
&lt;p&gt;Coding agents make this worse. They generate code at machine speed, so new findings appear faster. Lars Janssen calls the growing gap between how fast teams generate code and how fast they can check it &lt;a href="https://fazy.medium.com/agentic-coding-ais-adolescence-b0d13452f981" title="Verification debt: the hidden cost of AI-generated code" class="ext"&gt;verification debt&lt;/a&gt;. If remediation still depends on engineers picking up tickets between feature work, the backlog keeps growing. Risk only goes down when teams fix findings faster than scanners discover new ones.&lt;/p&gt;
&lt;p&gt;That requires AppSec teams to move from &lt;em&gt;&amp;ldquo;we found it, you fix it&amp;rdquo;&lt;/em&gt; to &lt;em&gt;&amp;ldquo;we prevent it, and we fix what slips through&amp;rdquo;&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="move-security-feedback-into-the-agent-loop"&gt;Move Security Feedback Into the Agent Loop &lt;a class="heading-anchor" href="#move-security-feedback-into-the-agent-loop" aria-label="Link to section: Move Security Feedback Into the Agent Loop"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the traditional loop, a scanner reports an issue in the pipeline, someone files a ticket, and an engineer fixes it when there&amp;rsquo;s time. In the agentic loop, the scan results go straight back to the coding agent, which rewrites the code in the same session until the checks pass. Many findings never reach a ticket because the agent fixes them before anyone commits the code. GitHub&amp;rsquo;s &lt;a href="https://github.blog/news-insights/product-news/secure-code-more-than-three-times-faster-with-copilot-autofix/" title="Secure code more than three times faster with Copilot Autofix" class="ext"&gt;Copilot Autofix&lt;/a&gt; suggests fixes directly in the pull request, which comes close to this loop. During its 2024 public beta, developers fixed new code scanning alerts in pull requests in a median of 28 minutes, compared with 1.5 hours without Autofix.&lt;/p&gt;
&lt;p&gt;Today&amp;rsquo;s security gates weren&amp;rsquo;t built for this loop. When a coding agent opens a pull request (PR) in seconds, a security gate that takes minutes becomes the slowest step. Binary gates also break down at this volume: &lt;em&gt;&amp;ldquo;block on medium severity&amp;rdquo;&lt;/em&gt; blocks everything, and &lt;em&gt;&amp;ldquo;ignore everything below critical&amp;rdquo;&lt;/em&gt; leaves real risks open. The risk budgets I describe further down give teams a better decision rule.&lt;/p&gt;
&lt;p&gt;Some findings will still slip through, and most organizations already carry a large backlog. Fixing them 1 ticket at a time doesn&amp;rsquo;t scale. In campaign-based remediation, AppSec targets a whole vulnerability class at once, such as an outdated dependency, an infrastructure as code (IaC) misconfiguration, or an insecure pattern repeated across hundreds of services.&lt;/p&gt;
&lt;p&gt;Spotify&amp;rsquo;s &lt;a href="https://engineering.atspotify.com/2023/05/fleet-management-at-spotify-part-3-fleet-wide-refactoring/" title="Fleet Management at Spotify (Part 3): Fleet-wide Refactoring" class="ext"&gt;fleetshift&lt;/a&gt; is a good mental model: it makes fleet-wide code changes by running a Docker image against each repository. Spotify reports that fleetshift created more than 270,000 PRs in 2022 and merged 77% of them automatically, and that it patched 80% of its production backend services within 9 hours of the Log4j disclosure.&lt;/p&gt;
&lt;p&gt;With coding agents, the AppSec team designs the campaign, and agents open, test, and verify the remediation PRs across the fleet. GitHub already supports part of this: in &lt;a href="https://docs.github.com/en/code-security/securing-your-organization/fixing-security-alerts-at-scale/about-security-campaigns" title="About security campaigns" class="ext"&gt;security campaigns&lt;/a&gt;, teams can assign alerts to the Copilot cloud agent, which opens pull requests with fixes.&lt;/p&gt;
&lt;h2 id="build-and-ship-security-tooling"&gt;Build and Ship Security Tooling &lt;a class="heading-anchor" href="#build-and-ship-security-tooling" aria-label="Link to section: Build and Ship Security Tooling"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this model, AppSec engineers build and ship security tooling and contribute remediation code directly. Their goal is infrastructure that makes coding agents produce secure code by default.&lt;/p&gt;
&lt;h3 id="security-skills-and-machine-readable-policy"&gt;Security Skills and Machine-Readable Policy &lt;a class="heading-anchor" href="#security-skills-and-machine-readable-policy" aria-label="Link to section: Security Skills and Machine-Readable Policy"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Skills are packaged instructions that coding agents load when a task needs them, and they follow an &lt;a href="https://agentskills.io/specification" title="Agent Skills Specification" class="ext"&gt;open specification&lt;/a&gt;. &lt;a href="https://github.com/cosai-oasis/project-codeguard" class="ext"&gt;Project CodeGuard&lt;/a&gt; from the Coalition for Secure AI (CoSAI) publishes general security skills for cryptography, input validation, authentication and authorization, and supply chain security. Organization-specific skills go further and encode internal policies (&lt;em&gt;&amp;ldquo;use the central auth SDK, not raw JWT handling&amp;rdquo;&lt;/em&gt;), approved libraries, and deployment constraints. If the organization distributes skills centrally, AppSec can publish a skill update when a new vulnerability class appears, and every agent in the organization has it the same day.&lt;/p&gt;
&lt;p&gt;The security policy itself needs the same treatment, because a coding agent can&amp;rsquo;t do much with a 50-page PDF. AppSec teams can turn it into agent instructions, a searchable vector database, or &lt;a href="https://www.openpolicyagent.org/" class="ext"&gt;policy-as-code&lt;/a&gt; rules that agents check while they work. The agent then verifies compliance mid-task without waiting for a human reviewer, and AppSec&amp;rsquo;s work moves from reviewing individual changes to maintaining the policies and risk models that agents enforce.&lt;/p&gt;
&lt;h3 id="local-scanners-and-review-agents"&gt;Local Scanners and Review Agents &lt;a class="heading-anchor" href="#local-scanners-and-review-agents" aria-label="Link to section: Local Scanners and Review Agents"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Security scanning can&amp;rsquo;t live only in version control platforms and CI pipelines anymore. Coding agents need static application security testing (SAST), dynamic application security testing (DAST), and reviewers based on large language models (LLMs) on the engineer&amp;rsquo;s machine, so they can check their own output before they push. AppSec teams package these tools as command-line interfaces (CLIs) or &lt;a href="https://modelcontextprotocol.io/" class="ext"&gt;Model Context Protocol (MCP)&lt;/a&gt; servers and manage their configuration and policies centrally. MCP gives agents a standard way to call tools. Engineering teams then get scanning that works without setup.&lt;/p&gt;
&lt;p&gt;Dedicated review agents combine security skills with local tooling. They check code against organization-specific policies and report issues in a form the coding agent can act on directly. &lt;a href="https://www.roborev.io/" class="ext"&gt;roborev&lt;/a&gt; points in this direction: it&amp;rsquo;s a local daemon that reviews each commit in the background through a git hook and &lt;a href="https://www.roborev.io/docs/guides/reviewing-code/" title="roborev: Reviewing code" class="ext"&gt;reports every finding&lt;/a&gt; with a severity and a file and line location before the code reaches a PR.&lt;/p&gt;
&lt;p&gt;A shared review ledger ties these checks together. Every source, whether static analyzer, dynamic scanner, or LLM-based reviewer, writes to the same structured log, typically in the &lt;a href="https://sarifweb.azurewebsites.net/" class="ext"&gt;Static Analysis Results Interchange Format (SARIF)&lt;/a&gt;. The coding agent reads the ledger after each iteration and knows which checks passed, which failed, and what to fix next. LLM-based reviewers can catch context-dependent issues that rule-based scanners miss, but they don&amp;rsquo;t return the same result on every run, so the ledger needs both.&lt;/p&gt;
&lt;h3 id="sandboxes-and-short-lived-credentials"&gt;Sandboxes and Short-Lived Credentials &lt;a class="heading-anchor" href="#sandboxes-and-short-lived-credentials" aria-label="Link to section: Sandboxes and Short-Lived Credentials"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Coding agents are most useful when they can run the code they write: they implement a change, run the tests, read the failure, and try again. That makes every agent task an untrusted workload running arbitrary code, often on an engineer&amp;rsquo;s laptop. For AppSec, this adds up to a large internal remote code execution (RCE) surface, and securing it touches workstation setup as well as engineering practice.&lt;/p&gt;
&lt;p&gt;Sandboxing and prompt injection defense go together. A coding agent reads external input such as dependency metadata, issue descriptions, PR comments, and documentation, and each of these can carry a &lt;a href="https://genai.owasp.org/llmrisk/llm01-prompt-injection/" title="OWASP LLM01:2025 Prompt Injection" class="ext"&gt;prompt injection&lt;/a&gt; that tells the agent to do something else. A sandbox limits the damage when that happens, and the common options differ in isolation strength and cost:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lightweight virtual machines (micro-VMs) such as &lt;a href="https://firecracker-microvm.github.io/" class="ext"&gt;Firecracker&lt;/a&gt; and &lt;a href="https://docs.docker.com/ai/sandboxes/get-started/" title="Docker Sandboxes" class="ext"&gt;Docker Sandboxes&lt;/a&gt; give each task a disposable environment with its own kernel.&lt;/li&gt;
&lt;li&gt;OS-level sandboxes are lighter. &lt;a href="https://nono.sh/os-sandbox" class="ext"&gt;nono&lt;/a&gt; applies irrevocable, kernel-enforced filesystem allow-lists through Landlock on Linux and Seatbelt on macOS, and &lt;a href="https://github.com/webcoyote/sandvault" class="ext"&gt;Sandvault&lt;/a&gt; runs agents as a separate macOS user inside &lt;code&gt;sandbox-exec&lt;/code&gt;. The nono authors point out that OS-level sandboxing doesn&amp;rsquo;t give the memory isolation of a virtual machine.&lt;/li&gt;
&lt;li&gt;Containers share the host kernel, so &lt;a href="https://mrinal.com/articles/agent-sandboxes/" title="Agent Sandboxes: how to create millions of them" class="ext"&gt;escaping 1 container puts the attacker on the host&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AppSec picks the isolation boundary that fits each workload&amp;rsquo;s trust level and, together with platform teams, ships the sandbox setup as the default configuration engineers get out of the box.&lt;/p&gt;
&lt;p&gt;Credentials need the same care. Coding agents should never hold persistent identity and access management (IAM) roles or long-lived API keys. An identity broker issues short-lived, task-scoped credentials on demand and revokes them when the task completes. AppSec can build the broker together with platform and IAM teams and hide it behind the agent&amp;rsquo;s tooling, so agents exchange tokens automatically and never fall back on whatever credential is at hand.&lt;/p&gt;
&lt;p&gt;Beyond internal credentials, agents increasingly act on behalf of users in third-party services. That needs &lt;a href="https://oauth.net/2.1/" class="ext"&gt;delegation and consent&lt;/a&gt; infrastructure with narrow, time-limited permissions the user can revoke at any moment. Without it, teams end up storing tokens in agent contexts or hard-coding service accounts, and both fail as soon as an attacker compromises an agent or the agent misreads a prompt.&lt;/p&gt;
&lt;h3 id="threat-modeling-and-offensive-testing"&gt;Threat Modeling and Offensive Testing &lt;a class="heading-anchor" href="#threat-modeling-and-offensive-testing" aria-label="Link to section: Threat Modeling and Offensive Testing"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Traditional scanners catch known vulnerabilities listed as Common Vulnerabilities and Exposures (CVEs), common misconfigurations, and obvious injection points. They miss logic flaws such as broken access control across multi-step workflows, business logic bypasses, and race conditions. To catch design-level flaws, AppSec teams have to encode their domain knowledge into agents.&lt;/p&gt;
&lt;p&gt;Threat modeling, where a team maps how an attacker could abuse a system&amp;rsquo;s design, usually happens in periodic workshops. Jack Naglieri &lt;a href="https://www.detectionatscale.com/p/threat-modeling-ai-agents-mcp" title="Building Threat Models with MCP and AI Agents" class="ext"&gt;built threat models with AI agents and MCP&lt;/a&gt; and argues that agents remove the weeks of meetings and documentation review that kept threat modeling a once-a-year exercise. Naglieri&amp;rsquo;s example comes from detection engineering, but the approach carries over to applications. AppSec teams can build agent setups that regularly review applications and repositories, analyze access control patterns, data flow boundaries, and trust assumptions, and report drift from the organization&amp;rsquo;s security posture.&lt;/p&gt;
&lt;p&gt;Agentic penetration testing (pentesting) complements this, and AppSec can offer it to engineering teams as an internal service. These agents explore the application&amp;rsquo;s business logic and look for the flaws a human pentester would target: authorization boundaries, multi-step attack paths, and privilege escalation. To build them, AppSec teams turn their offensive expertise into repeatable attack strategies. Public setups today still keep a human in the loop. In &lt;a href="https://labs.secengai.com/p/ai-assisted-web-pentesting-using-claude-code-burp-mcp" title="AI-assisted Web Pentesting Using Claude Code &amp;#43; Burp MCP" class="ext"&gt;AI-assisted web pentesting with Claude Code and Burp MCP&lt;/a&gt;, for example, the agent suggests the next test and the pentester decides whether to run it.&lt;/p&gt;
&lt;h2 id="partner-with-sre-and-platform-teams"&gt;Partner With SRE and Platform Teams &lt;a class="heading-anchor" href="#partner-with-sre-and-platform-teams" aria-label="Link to section: Partner With SRE and Platform Teams"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote class="quote"&gt;Can a system ever truly be considered reliable if it isn&amp;rsquo;t fundamentally secure? Or can it be considered secure if it&amp;rsquo;s unreliable?&lt;footer&gt;&lt;a href="https://google.github.io/building-secure-and-reliable-systems/raw/pr01.html"&gt;&lt;cite&gt;Building Secure and Reliable Systems&lt;/cite&gt;&lt;/a&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;p&gt;In SRE, the product owner sets a &lt;a href="https://sre.google/sre-book/service-level-objectives/" title="Google SRE Book: Service Level Objectives" class="ext"&gt;service level objective (SLO)&lt;/a&gt; such as 99.9% availability, and the remaining 0.1% becomes the service&amp;rsquo;s &lt;a href="https://sre.google/sre-book/embracing-risk/" title="Google SRE Book: Embracing Risk" class="ext"&gt;error budget&lt;/a&gt;, which the team can spend on outages and risky releases. AppSec can join that model with a &lt;strong&gt;risk budget&lt;/strong&gt;. The risk budget sets how long a high-risk, reachable vulnerability may stay open in production before it burns error budget, just like downtime does. AppSec provides the framework and the tooling, and the product owner sets the target, just as for the SLO.&lt;/p&gt;
&lt;p&gt;A risk budget helps with a problem that agentic engineering makes worse. Coding agents generate change faster than people can triage the findings, and without a quantitative target every finding competes for the same attention. With a risk budget, teams fix what burns the budget and defer what doesn&amp;rsquo;t. The conversation moves from &lt;em&gt;&amp;ldquo;fix all the bugs&amp;rdquo;&lt;/em&gt; to &lt;em&gt;&amp;ldquo;manage the exposure window&amp;rdquo;&lt;/em&gt;, and security becomes an operational concern that AppSec shares with the teams running the service.&lt;/p&gt;
&lt;p&gt;Teams can only use a risk budget if they can tell real exposure from noise, and that requires &lt;strong&gt;reachability analysis&lt;/strong&gt;: tracing the call graph from the vulnerable code to the application&amp;rsquo;s entry points. A CVE in dead code doesn&amp;rsquo;t burn budget, but the same CVE behind a public API does. At the CI gate, teams then block only changes that introduce &lt;em&gt;reachable&lt;/em&gt; risk and stop failing builds on raw finding counts. In production, a monitoring layer tracks how long reachable findings stay open and burns error budget accordingly.&lt;/p&gt;
&lt;p&gt;Platform and cloud engineering teams already ship the paved roads that engineering teams build on: base images, service templates, IaC modules, identity primitives, and networking defaults. AppSec teams get the most reach by building security into those &lt;a href="https://www.redhat.com/en/topics/platform-engineering/golden-paths" title="What is a Golden Path for software development?" class="ext"&gt;golden paths&lt;/a&gt;. A hardened base image or a secure-by-default service template then carries security to every service that uses it, including the code that agents write. Platform engineering owns the templates and modules, and AppSec owns the security defaults inside them. I cover this model in more detail in &lt;a href="https://www.janbrennenstuhl.eu/shift-down-appsec/" title="Shift Down: Why Agentic Engineering Demands Platform-Level Security"&gt;Shift Down&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="where-to-start"&gt;Where to Start &lt;a class="heading-anchor" href="#where-to-start" aria-label="Link to section: Where to Start"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;None of this has to happen at once. A team that wants to start can work through these steps in order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sandbox the coding agents that engineers already run, and replace their long-lived credentials with short-lived, task-scoped ones.&lt;/li&gt;
&lt;li&gt;Package the existing scanners as CLIs or MCP servers with central configuration, and make them write SARIF.&lt;/li&gt;
&lt;li&gt;Publish an organization-specific security skill that encodes the internal policies that matter most.&lt;/li&gt;
&lt;li&gt;Pick 1 vulnerability class from the backlog and fix it across the fleet as a campaign.&lt;/li&gt;
&lt;li&gt;Agree on a risk budget for reachable vulnerabilities with 1 service owner and their SRE team.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The sandbox comes first because the exposure exists as soon as an engineer runs an agent with access to their machine.&lt;/p&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></channel></rss>