<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Auth0 for Developers</title>
    <description>The latest articles on DEV Community by Auth0 for Developers (auth0).</description>
    <link>https://dev.to/auth0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F634%2Fc6bfc78f-136d-456b-96dc-bcc4be1c88f9.jpg</url>
      <title>DEV Community: Auth0 for Developers</title>
      <link>https://dev.to/auth0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/auth0"/>
    <language>en</language>
    <item>
      <title>Confused Deputy: The Old Bug That AI Agents Keep Reintroducing</title>
      <dc:creator>Andrea Chiarelli</dc:creator>
      <pubDate>Thu, 24 Sep 2026 10:28:34 +0000</pubDate>
      <link>https://dev.to/auth0/confused-deputy-the-old-bug-that-ai-agents-keep-reintroducing-1kf</link>
      <guid>https://dev.to/auth0/confused-deputy-the-old-bug-that-ai-agents-keep-reintroducing-1kf</guid>
      <description>&lt;p&gt;Back in 1988, a compiler running on a commercial timesharing system had permission to write to a shared directory for recording language feature usage statistics. That same directory also stored the file holding the system's billing records. A user asked the compiler to write its debug output to a file with the same name as the billing file. The compiler, using its own permissions rather than the user's, opened the file and overwrote it.&lt;/p&gt;

&lt;p&gt;Norm Hardy &lt;a href="https://dl.acm.org/doi/10.1145/54289.871709" rel="noopener noreferrer"&gt;wrote up the incident in a 1988 paper&lt;/a&gt; and gave it a name: &lt;strong&gt;the Confused Deputy problem&lt;/strong&gt;. It describes a scenario where a program with legitimate authority gets tricked by a less-privileged actor into misusing that authority on the actor's behalf.&lt;/p&gt;

&lt;p&gt;Almost forty years later, most developers building software have never heard the term, even though they encounter its cousins constantly. And right now, AI agents are giving it a wider blast radius than Hardy ever imagined.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is the Confused Deputy Problem?
&lt;/h2&gt;

&lt;p&gt;Setting aside the mainframe context, the pattern is simple: a &lt;em&gt;deputy&lt;/em&gt; (an application or service executing a task) holds permissions its caller doesn't have. The deputy does useful work by relying on those permissions. Somewhere along the way, an attacker gets the deputy to use its own authority for the attacker's benefit instead of the caller's.&lt;/p&gt;

&lt;p&gt;Two structural conditions make this possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, the identifier used to reference an object (a filename, a URL, a resource ID) doesn't carry access rights of its own. Anyone can write down &lt;code&gt;https://example.com/invoices/1234&lt;/code&gt;; writing down the resource's name isn't the same as being allowed to open it.&lt;/li&gt;
&lt;li&gt;Second, the deputy's permissions apply automatically, with no explicit step where authority is checked against who's actually asking. The compiler didn't ask "&lt;em&gt;does this specific user have rights to this specific file?&lt;/em&gt;" It simply asked "&lt;em&gt;do I have rights to this file?&lt;/em&gt;" and &lt;strong&gt;got the wrong answer to the right question&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't a single bug. It's a shape that privilege-escalation bugs keep taking, &lt;strong&gt;wherever a component with higher privileges processes an insufficiently verified request from a component with lower privileges&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Problem That Never Went Away
&lt;/h2&gt;

&lt;p&gt;If the compiler story sounds academic, the pattern it describes is everywhere in production systems today.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://auth0.com/blog/cross-site-request-forgery-csrf/" rel="noopener noreferrer"&gt;Cross-Site Request Forgery (CSRF)&lt;/a&gt; is a Confused Deputy attack occurring in a browser-based environment. Your browser holds a valid session cookie for your bank. A malicious page gets your browser to submit a form to the bank's transfer endpoint. The bank's server sees a request carrying a valid cookie and processes it, because the cookie is the only thing it checks. Your browser is the deputy; the cookie is the ambient authority; the malicious page is the attacker who never had transfer rights of its own.&lt;/p&gt;

&lt;p&gt;A more general version of the same problem shows up in &lt;a href="https://en.wikipedia.org/wiki/Server-side_request_forgery" rel="noopener noreferrer"&gt;Server-Side Request Forgery (SSRF)&lt;/a&gt;. Plenty of backend services exist to fetch a resource on a caller's behalf: a link-preview generator, a PDF renderer, a webhook relay, an image proxy. In these scenarios, the caller supplies a URL, and the service fetches it using its own network position and its own credentials. An attacker who supplies the address of an internal endpoint instead of a legitimate image URL gets the service to reach into a place the caller could never reach directly. It hands back whatever secrets that endpoint returns. The service is the deputy, its network access is the ambient authority, and the attacker never had permission to query that endpoint themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI Agents Are the Perfect Deputy to Confuse
&lt;/h2&gt;

&lt;p&gt;An AI agent is a deputy by design. You give it access to your calendar, your GitHub repo, your billing system, so it can act on your behalf without you typing every command yourself. That's the whole value proposition. It's also exactly the setup Hardy described in 1988, reproduced at scale.&lt;/p&gt;

&lt;p&gt;What makes agents worse than the 1988 compiler is how they receive instructions. The compiler at least had a fixed, narrow interface: a filename parameter. An agent reads a system prompt, a user request, retrieved documents, tool outputs, and other agents' messages. It processes all of it through the same channel: natural language, tokenized and fed to a model that has no built-in way to mark some tokens "trusted command" and others "untrusted content." A sentence buried in a GitHub issue title carries exactly the same weight to the model as a sentence typed by the person who owns the API key.&lt;/p&gt;

&lt;p&gt;That single fact turns Confused Deputy from a rare, hand-crafted exploit into something closer to standard practice for attackers. Getting a 1988 compiler to misuse its authority required knowing the exact filename of a sensitive file and getting a specific user to request it. Getting an agent to misuse its authority just requires putting the right sentence somewhere the agent will read it: an email, a web page, a code comment, a support ticket. Combine that with agents that typically hold a user's full OAuth scope rather than a task-specific slice of it, and you have a deputy that's both easy to confuse and dangerously over-authorized when it happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  When It's Already Happened
&lt;/h2&gt;

&lt;p&gt;This isn't hypothetical. In February 2026, an authenticated GitHub issue-triage bot with broad repository access and shell execution rights &lt;a href="https://labs.cloudsecurityalliance.org/research/csa-research-note-clinejection-prompt-injection-cicd-cache-p/" rel="noopener noreferrer"&gt;processed a new issue with a crafted title&lt;/a&gt;. The title contained an embedded instruction that got the agent to execute an attacker-supplied command inside the triage workflow. Researchers named the technique "Clinejection", after the tool it targeted.&lt;/p&gt;

&lt;p&gt;The agent's action wasn't the end of the chain, just the entry point. The attacker used that first foothold to flood the project's shared GitHub Actions cache with junk data, forcing out legitimate cache entries and replacing them with poisoned ones matching the keys used by a separate, much more privileged nightly release workflow. When that workflow ran, it restored the poisoned cache, handing the attacker execution inside a job that held the project's npm publishing token. With that token, the attacker published a tampered package version whose install script silently pulled down an unrelated AI agent tool onto every machine that installed the update. The compromised package was downloaded roughly 4,000 times during the roughly eight-hour window before it was caught.&lt;/p&gt;

&lt;p&gt;Look at where the actual damage came from. Not from a flaw in the language model. From an agent that couldn't distinguish an issue title from an instruction, combined with credentials and cache access that assumed anything running inside a trusted workflow was, by definition, trustworthy. That's the Confused Deputy pattern end to end: legitimate authority, an under-verified request, and a chain of systems willing to act on the deputy's behalf without checking who actually asked.&lt;/p&gt;

&lt;p&gt;Security researchers are already tracking &lt;a href="https://arxiv.org/html/2605.24069v1" rel="noopener noreferrer"&gt;related patterns in MCP tool servers&lt;/a&gt; (where a malicious tool description can inject instructions the calling agent treats as legitimate) and in &lt;a href="https://arxiv.org/html/2604.01905v1" rel="noopener noreferrer"&gt;multi-agent systems&lt;/a&gt;, where one agent re-delegates a task to another without re-verifying that the original request actually authorized it. The pattern is the same each time: &lt;strong&gt;a channel that mixes instructions with data, and a deputy that acts on whatever arrives through it&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Old Playbook Still Works
&lt;/h2&gt;

&lt;p&gt;None of the fixes for Confused Deputy attacks are new, and that's good news. The same principles that protect fetch services and browser sessions apply directly here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Least privilege&lt;/strong&gt; means giving a deputy only the authority it needs for the task in front of it, not a standing grant sized for every task it might ever perform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capability-based security&lt;/strong&gt; takes this further: instead of an identifier (a filename, a userId, a URL) that relies on the deputy's ambient permissions to resolve, you hand the deputy a token that bundles the object reference and the access right together. The deputy can't be tricked into misusing authority it was never actually given, because the authority travels with the request instead of living separately inside the deputy. In practical terms, this means checking audience, &lt;a href="https://auth0.com/blog/permissions-privileges-and-scopes/" rel="noopener noreferrer"&gt;scopes, and permissions&lt;/a&gt; in access tokens, but also using &lt;a href="https://auth0.com/blog/how-fine-grained-authorization-solves-critical-api-security-risk/" rel="noopener noreferrer"&gt;fine-grained authorization tools&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit permission transfer&lt;/strong&gt; replaces the automatic inheritance that got the 1988 compiler in trouble: instead of "I have write access to this directory, so any request I process gets that access," the system requires "this specific caller granted this specific permission for this specific action." &lt;a href="https://auth0.com/blog/the-many-faces-of-oauth2-token-exchange/" rel="noopener noreferrer"&gt;Token Exchange, in its various facets,&lt;/a&gt; helps implement this requirement.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Changes When the Deputy Is an AI Agent
&lt;/h2&gt;

&lt;p&gt;Applying that playbook to agents means translating each principle into something that survives an agent's specific failure mode: since it can be convinced of anything, the authorization has to hold even when the agent's judgment doesn't.&lt;/p&gt;

&lt;p&gt;Standing OAuth scopes that an agent holds for its entire session are the equivalent of the compiler's blanket write access to the shared folder. &lt;strong&gt;Task-scoped, short-lived credentials&lt;/strong&gt; fix this the same way least privilege does: an agent gets exactly the access it needs for the task at hand, and that access expires when the task ends, rather than persisting as a standing grant an attacker can hijack days later.&lt;/p&gt;

&lt;p&gt;Broad verbs like &lt;code&gt;billing:write&lt;/code&gt; or &lt;code&gt;email:send&lt;/code&gt; are also too coarse. If an agent can call &lt;code&gt;billing:write&lt;/code&gt;, a single successful injection lets an attacker do anything billing-related. &lt;strong&gt;Capability-scoped permissions&lt;/strong&gt; narrow that surface to specific business actions, "issue a refund under $50," "send an email to an address already in this thread," so even a fully confused agent has a small, well-defined blast radius.&lt;/p&gt;

&lt;p&gt;Credentials themselves need to live somewhere the model can't reach. If a token sits in a system prompt or a tool schema so the model "knows what to pass," it's also sitting in the exact place a prompt injection payload can extract it. The reliable pattern is to keep the model in charge of deciding what to do (which tool, which parameters, based on the user's request) while &lt;a href="https://auth0.com/blog/ai-agents-have-two-souls-you-control-only-one/" rel="noopener noreferrer"&gt;a separate, deterministic layer of code executes the action&lt;/a&gt; and holds the credential. &lt;a href="https://auth0.com/blog/want-ai-agents-that-don-t-spill-secrets-don-t-give-them-secrets/" rel="noopener noreferrer"&gt;The model never sees a token it could be tricked into revealing or misusing&lt;/a&gt;, because it never has one.&lt;/p&gt;

&lt;p&gt;And for anything expensive, irreversible, or broad enough to matter, &lt;strong&gt;human-in-the-loop approval&lt;/strong&gt; puts a checkpoint between the agent's decision and the action actually happening: a specific, &lt;a href="https://auth0.com/blog/secure-human-in-the-loop-interactions-for-ai-agents/" rel="noopener noreferrer"&gt;out-of-band confirmation for the specific action requested&lt;/a&gt;, not a blanket yes/no given once at the start of the session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Auth0 Fits
&lt;/h2&gt;

&lt;p&gt;This is the shift &lt;a href="https://auth0.com/ai" rel="noopener noreferrer"&gt;Auth0 for AI Agents&lt;/a&gt; is built around: moving agents away from &lt;a href="https://auth0.com/blog/ai-agents-are-not-users" rel="noopener noreferrer"&gt;standing, broadly scoped credentials&lt;/a&gt; and toward access that's narrowly scoped to a task, short-lived, and &lt;a href="https://auth0.com/blog/closing-audit-gap-human-to-agent-delegation" rel="noopener noreferrer"&gt;traceable back to the specific agent and request that used it&lt;/a&gt;, with a human approval step available for anything above a defined risk threshold. &lt;a href="https://auth0.com/ai/docs/intro/token-vault" rel="noopener noreferrer"&gt;Token Vault&lt;/a&gt; issues just-in-time tokens for third-party APIs instead of handing agents standing credentials to store and reuse, and Auth0's work on &lt;a href="https://auth0.com/blog/agent-as-principal-purpose-built-identity-for-agents" rel="noopener noreferrer"&gt;treating agents as first-class identities&lt;/a&gt; and on &lt;a href="https://auth0.com/blog/intent-rethinking-authorization-ai-agents" rel="noopener noreferrer"&gt;scoping authorization to a task's actual intent&lt;/a&gt; both aim directly at closing the gap this post has been describing. None of it requires you to trust the agent's judgment more. It requires trusting it less, by design.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bug Doesn't Care How New Your Stack Is
&lt;/h2&gt;

&lt;p&gt;Confused deputy isn't a vulnerability class that AI introduced. It's a vulnerability class AI agents are reintroducing at a scale Norm Hardy couldn't imagine in 1988: millions of deployed deputies, each reachable by anyone who can write a sentence into content the agent will eventually read.&lt;/p&gt;

&lt;p&gt;The fix hasn't changed either. Stop treating an agent's ambient access as proof that a specific request is legitimate. Every credential you hand an agent should be a specific, auditable capability, scoped to a task and expiring when the task ends, not a blanket delegation you hope the agent uses responsibly. Hardy's compiler didn't have a choice about how it used its authority. Your agent shouldn't be given the chance to have one either.&lt;/p&gt;

&lt;p&gt;What's the broadest standing permission your agents currently hold that you'd have a hard time explaining to a security reviewer? That's the first one worth narrowing.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>vulnerabilities</category>
    </item>
    <item>
      <title>Add Auth0 to Your Hono App in Just 5 Lines of Code</title>
      <dc:creator>Auth0 DevRel</dc:creator>
      <pubDate>Mon, 21 Sep 2026 04:00:00 +0000</pubDate>
      <link>https://dev.to/auth0/add-auth0-to-your-hono-app-in-just-5-lines-of-code-26ko</link>
      <guid>https://dev.to/auth0/add-auth0-to-your-hono-app-in-just-5-lines-of-code-26ko</guid>
      <description>&lt;p&gt;Secure your Hono web applications everywhere they run—from Cloudflare Workers and Vercel Edge to Node.js, Bun, and Deno. In this demo, Auth0 Software Developer Tushar Pandey shows you how to ditch complex custom auth logic and integrate the official Auth0 Hono SDK in just five lines of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Learn:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How to mount the Auth0 middleware for automatic login, callback, and logout routing.&lt;/li&gt;
&lt;li&gt;Protecting specific routes using the &lt;code&gt;requiresAuth&lt;/code&gt; middleware.&lt;/li&gt;
&lt;li&gt;Filtering access based on user roles using &lt;code&gt;claimEquals&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Retrieving user profiles and managing API access tokens on the Edge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠️ Resources &amp;amp; Links:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/@auth0/auth0-hono" rel="noopener noreferrer"&gt;Auth0 Hono SDK on npm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/auth0/auth0-hono" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://auth0.com/signup?utm_source=devto&amp;amp;utm_campaign=DevRel&amp;amp;utm_medium=link_placement" rel="noopener noreferrer"&gt;Create a Free Auth0 Account&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/@auth0" rel="noopener noreferrer"&gt;Subscribe for more developer tutorials, SDK deep dives, and security best practices.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>authentication</category>
      <category>javascript</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop Using the Default Auth0 Login Page (Do This Instead)</title>
      <dc:creator>Jessica Temporal</dc:creator>
      <pubDate>Wed, 16 Sep 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/auth0/stop-using-the-default-auth0-login-page-do-this-instead-3ndc</link>
      <guid>https://dev.to/auth0/stop-using-the-default-auth0-login-page-do-this-instead-3ndc</guid>
      <description>&lt;p&gt;Don't let a generic login page break your app's user experience. In this tutorial, we dive into the Auth0 dashboard to completely customize the Universal Login branding using the No-Code editor. Learn how to update colors, fonts, border radii (pill buttons vs. square), and logos so your authentication flow feels like a seamless, integrated part of your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Learn
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Navigating the Auth0 Branding &amp;amp; Universal Login dashboard&lt;/li&gt;
&lt;li&gt;Updating primary colors, backgrounds, and button UI&lt;/li&gt;
&lt;li&gt;Modifying widget layout, borders, and logo positioning&lt;/li&gt;
&lt;li&gt;Implementing a seamless brand experience without writing custom CSS/JS&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Related Auth0 Tutorials
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/eR5ETQG6rbE" rel="noopener noreferrer"&gt;Set up a Custom Domain in Auth0 (by Carla)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/qY3XsfQSD3c" rel="noopener noreferrer"&gt;Update Google Development Keys to Production (by Layla)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💻 Resources &amp;amp; Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://auth0.com/docs/authenticate/login/auth0-universal-login" rel="noopener noreferrer"&gt;Auth0 Universal Login Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you enjoy this content and want to learn more about identity, security, and access management, subscribe to our channel! &lt;/p&gt;

&lt;p&gt;Have a topic you'd like to see covered? Let us know in the comments below 👀 &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>tools</category>
      <category>frontend</category>
    </item>
    <item>
      <title>How to Set Up Auth0 Organizations (SSO, Branding &amp; Invitations)</title>
      <dc:creator>Auth0 DevRel</dc:creator>
      <pubDate>Mon, 14 Sep 2026 04:00:00 +0000</pubDate>
      <link>https://dev.to/auth0/how-to-set-up-auth0-organizations-sso-branding-invitations-9dc</link>
      <guid>https://dev.to/auth0/how-to-set-up-auth0-organizations-sso-branding-invitations-9dc</guid>
      <description>&lt;p&gt;Stop Building Multi-Tenant Auth from Scratch. Use This Instead.&lt;br&gt;
Building a B2B SaaS application requires a complex multi-tenant infrastructure. In this technical walkthrough, Shreya Gupta and Lily Wisecarver demonstrate how to use Auth0 Organizations to effortlessly manage identity workflows for your business customers at scale. Learn how to isolate tenants, configure custom Single Sign-On (SSO) connections per client, and customize the login branding—all without reinventing the wheel.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Learn
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How multi-tenancy works within Auth0 Organizations&lt;/li&gt;
&lt;li&gt;Setting up distinct organization IDs for different business clients&lt;/li&gt;
&lt;li&gt;Customizing the login UI and branding for specific tenants&lt;/li&gt;
&lt;li&gt;Enabling specific enterprise and database connections (like Okta or Azure AD) per organization&lt;/li&gt;
&lt;li&gt;Managin
g user invitations and Role-Based Access Control (RBAC)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Keep Learning with Auth0
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://auth0.com/docs/manage-users/organizations" rel="noopener noreferrer"&gt;📖 Read the Auth0 Organizations Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://auth0.com/signup?utm_source=devto&amp;amp;utm_campaign=DevRel&amp;amp;utm_medium=link_placement" rel="noopener noreferrer"&gt;🚀 Start Using Auth0 for Free&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/playlist?list=PLZ14qQz3cfJJDxKv6FEWPTDVWKQlImbIN" rel="noopener noreferrer"&gt;📺 Using Auth0 Playlist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chapters:&lt;br&gt;
00:00 Introduction to B2B SaaS Multi-Tenancy&lt;br&gt;
00:11 How Auth0 Organizations Work&lt;br&gt;
02:05 Setting Up Organizations in the Dashboard&lt;br&gt;
02:56 Custom Branding per Organization&lt;br&gt;
03:27 Managing the Invitation Workflow&lt;br&gt;
04:03 Enabling SSO &amp;amp; Database Connections&lt;br&gt;
04:53 Customizing the Login Experience &amp;amp; Auto-Membership&lt;br&gt;
06:13 Sending Invitations &amp;amp; Assigning Roles&lt;br&gt;
07:44 The End-User Sign-Up Experience Demo&lt;br&gt;
09:12 Conclusion &amp;amp; Next Steps&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/@auth0" rel="noopener noreferrer"&gt;🔔 Subscribe for more developer tutorials&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sso</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>"You Don't Need to Read the Code Anymore"</title>
      <dc:creator>Carla Urrea Stabile</dc:creator>
      <pubDate>Thu, 27 Aug 2026 14:14:00 +0000</pubDate>
      <link>https://dev.to/auth0/you-dont-need-to-read-the-code-anymore-1cm9</link>
      <guid>https://dev.to/auth0/you-dont-need-to-read-the-code-anymore-1cm9</guid>
      <description>&lt;p&gt;If a PR has solid tests, good observability, and the logic holds, do you need to read every line? Jess says no, and she makes a solid case for it.&lt;/p&gt;

&lt;p&gt;In Episode 8 of Making Software, I talked to &lt;a href="https://jtemporal.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Jess Temporal&lt;/strong&gt;&lt;/a&gt;, a Senior Developer Advocate with a background in biomedical informatics and data science. She's been helping people understand complex things since before she knew that was a job title.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Her "nontraditional" path was DevRel training the whole time.&lt;/strong&gt; Biomedical informatics sat between hard Computer Science and healthcare, which meant explaining things to two completely different audiences and she didn't realize that was advocacy until years later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;She won't teach what she hasn't built.&lt;/strong&gt; Her creative process works backwards from understanding: build it, connect the pieces, then shape it into a story worth telling. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Is my data safe?" is a valid security question.&lt;/strong&gt; A journalist friend building with AI didn't know the technical words for her concerns. Jess's take: describe the concern to your agent and let it surface the vocabulary. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The My Yarn Stash app that taught her more than any tutorial.&lt;/strong&gt; Her side project is a yarn tracker, a real problem she actually had. It was down for three days, AI wrote the postmortem, and now she has uptime monitoring. She understands observability better now because she needed to.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Things that stuck with me
&lt;/h2&gt;

&lt;p&gt;Jess said, mid-episode, that she doesn't know what a harness is. She works in AI full-time. She's been hearing the term constantly. She just hasn't looked it up yet, and on camera she admitted she was too scared to do it right then. She's doing great work in the AI space without knowing every piece of its vocabulary. &lt;/p&gt;

&lt;p&gt;Her actual position on reading code: tests matter more than the code itself. If the tests make sense, if you have observability, if you can ask an AI to audit for security vulnerabilities, reading line-by-line is a lower priority than most engineers assume. &lt;/p&gt;

&lt;p&gt;The postmortem detail is the one that I thought the most about. She had AI fix a bug that took her site down for three days, then asked the same session to write a postmortem and add prevention guidelines to its own rules. &lt;/p&gt;

&lt;p&gt;The constraint is the method. Find one real problem. Pick one tool. Learn it well enough to have an opinion on the next one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's a side project that taught you something a job never could?&lt;/strong&gt; Let me know in the comments!&lt;/p&gt;

&lt;h2&gt;
  
  
  Listen to the full episode
&lt;/h2&gt;

&lt;p&gt;Available on &lt;a href="https://www.youtube.com/playlist?list=PLZ14qQz3cfJKRDmX3yasmbwoC4kipeQfu" rel="noopener noreferrer"&gt;&lt;strong&gt;YouTube&lt;/strong&gt;&lt;/a&gt;, &lt;a href="https://podcasts.apple.com/us/podcast/making-software/id1872107131" rel="noopener noreferrer"&gt;&lt;strong&gt;Apple Podcasts&lt;/strong&gt;&lt;/a&gt;, and &lt;a href="https://open.spotify.com/show/6J856S2fijMvP3rzFkRnBi" rel="noopener noreferrer"&gt;&lt;strong&gt;Spotify&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading! 👋&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>python</category>
      <category>security</category>
    </item>
    <item>
      <title>Federated Identity vs Single Sign-On (SSO) | Stop Confusing IAM Architecture</title>
      <dc:creator>Jessica Temporal</dc:creator>
      <pubDate>Mon, 24 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/auth0/federated-identity-vs-single-sign-on-sso-stop-confusing-iam-architecture-52il</link>
      <guid>https://dev.to/auth0/federated-identity-vs-single-sign-on-sso-stop-confusing-iam-architecture-52il</guid>
      <description>&lt;p&gt;Are you confused about the difference between Federated Identity and Single Sign-On (SSO)? You’re not alone. While both deal with authentication and access control, they solve fundamentally different architectural challenges. &lt;/p&gt;

&lt;p&gt;In this video, we break down Federated Identity vs. SSO with real-world developer examples, protocol overviews (SAML, OAuth, OIDC), and clear diagrams so you can design secure identity systems with confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 What You'll Learn
&lt;/h2&gt;

&lt;p&gt;The core technical definitions of SSO and Federated Identity&lt;br&gt;
Key differences: Single domain vs. Cross-domain trust relationships&lt;br&gt;
How identity providers (IdPs) operate across enterprise boundaries&lt;br&gt;
Real-world protocols: SAML, OpenID Connect (OIDC), and OAuth 2.0&lt;br&gt;
When to implement SSO vs. when you actually need Federation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://auth0.com/blog/federated-identity-vs-single-sign-on-key-differences/" rel="noopener noreferrer"&gt;Read the full blog post by Andrea Chiarelli here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>identity</category>
      <category>security</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>We Let AI Resurrect a 2-Year-Old Flask Python App (Cursor + Auth0)</title>
      <dc:creator>Jessica Temporal</dc:creator>
      <pubDate>Mon, 17 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/auth0/we-let-ai-resurrect-a-2-year-old-flask-python-app-cursor-auth0-234b</link>
      <guid>https://dev.to/auth0/we-let-ai-resurrect-a-2-year-old-flask-python-app-cursor-auth0-234b</guid>
      <description>&lt;p&gt;Updating old codebases usually means hours of re-configuring environments, fixing broken dependencies, and hunting for lost secrets. In this walkthrough, we use Cursor IDE and the new Auth0 plugin to automatically resurrect a 2-year-old Python Flask application. Watch how AI seamlessly sets up the Auth0 CLI, generates environment variables, and configures our authentication tenant from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Learn
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How to install and navigate the Auth0 plugin within Cursor IDE.&lt;/li&gt;
&lt;li&gt;Using AI prompts to automate Auth0 tenant creation and Flask secret key generation.&lt;/li&gt;
&lt;li&gt;Navigating the Auth0 CLI device authorization code flow inside an AI environment.&lt;/li&gt;
&lt;li&gt;Troubleshooting AI prompt timeouts and natively restarting development servers via Cursor.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources &amp;amp; Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jtemporal/flask-to-fastapi" rel="noopener noreferrer"&gt;🐙 GitHub Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cursor.com/marketplace/auth0" rel="noopener noreferrer"&gt;💻 Auth0 Plugin in Cursor Marketplace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://auth0.com/docs/quickstart/webapp/python" rel="noopener noreferrer"&gt;🔐 Auth0 Python/Flask Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://auth0.com/docs/deploy-monitor/auth0-cli#auth0-cli" rel="noopener noreferrer"&gt;📖 Auth0 CLI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>tooling</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Give Claude Real-Time Auth0 Docs Access (MCP Server)</title>
      <dc:creator>Jessica Temporal</dc:creator>
      <pubDate>Mon, 10 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/auth0/how-to-give-claude-real-time-auth0-docs-access-mcp-server-55f5</link>
      <guid>https://dev.to/auth0/how-to-give-claude-real-time-auth0-docs-access-mcp-server-55f5</guid>
      <description>&lt;p&gt;Stop relying on outdated LLM training data or incomplete web scrapes when writing identity code. In this video, we walk through how to add Auth0 documentation MCP (Model Context Protocol) servers directly to your setup, giving Claude Code real-time access to the Auth0 documentation. &lt;/p&gt;

&lt;p&gt;We walk through adding both the "Auth0 for AI Agents" documentation server and the "General Auth0 Documentation" server, verifying their connections, and putting them to the test with real-world prompt scenarios like human-in-the-loop consent and Auth Code vs. Client Credentials flows.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 What You'll Learn
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The problem with generic LLM training data for precise identity management.&lt;/li&gt;
&lt;li&gt;How to add the Auth0 for AI Agents documentation server for protected agent architectures.&lt;/li&gt;
&lt;li&gt;How to add the General Auth0 documentation server for quick access to SDKs and flows.&lt;/li&gt;
&lt;li&gt;Verifying and listing active MCP servers within Claude Code.&lt;/li&gt;
&lt;li&gt;Real-world prompt testing (CIBA/Backchannel authentication and flow comparison).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Related Videos and Playlists
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/playlist?list=PLZ14qQz3cfJL-OH27WpS51G_Bz0DLCp9t" rel="noopener noreferrer"&gt;Auth0 + MCP + Skills + AI Coding Agents (Playlist)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=nG3Gxrtn6Uo" rel="noopener noreferrer"&gt;See the Auth0 Claude Code Plugin &amp;amp; Stripe Integration In Action&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>documentation</category>
      <category>mcp</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The AI That Broke Out of Its Box, and What Happens Next</title>
      <dc:creator>layla </dc:creator>
      <pubDate>Thu, 06 Aug 2026 16:29:21 +0000</pubDate>
      <link>https://dev.to/auth0/the-ai-that-broke-out-of-its-box-and-what-happens-next-m3d</link>
      <guid>https://dev.to/auth0/the-ai-that-broke-out-of-its-box-and-what-happens-next-m3d</guid>
      <description>&lt;p&gt;Ever read a security disclosure and hit paragraph two going "wait, WHAT?" That's this one.&lt;/p&gt;

&lt;p&gt;On July 16th, HuggingFace announced they'd been hit with a strange kind of attack: an autonomous agent running inside their systems for days, gone before anyone could pin down who was behind it. Five days later, OpenAI came forward. It was &lt;em&gt;literally&lt;/em&gt; their own model. &lt;/p&gt;

&lt;p&gt;Since joining Auth0 a month ago, I now spend my days thinking about identity and access for a living, and this one truly stopped me in my tracks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short version of what happened
&lt;/h2&gt;

&lt;p&gt;OpenAI was testing an unreleased model against a benchmark called ExploitGym ~ with guardrails off, to get an honest read on its raw capability. The model found a zero-day in its sandbox's one exit point, a package-download proxy, and used it to reach the open internet. From there, it found and rooted an exposed code-execution endpoint sitting on a completely unrelated company's infrastructure (Modal), and used that as its actual base of operations.&lt;/p&gt;

&lt;p&gt;Then it went after HuggingFace. Not through stolen credentials at first, but through two super ordinary bugs in how their dataset processor handled uploaded files: one let it read arbitrary files off a production server, the other gave it code execution. And from there it escalated for real: stolen tokens, forged identity keys, cluster-admin on two separate systems within one second.&lt;/p&gt;

&lt;p&gt;Nobody prompted any of it. The model was told to solve a benchmark, handed tools, and left alone to figure out how. HuggingFace's own reconstruction counted roughly 17,600 actions across four and a half days before their security team finally cut it off.&lt;br&gt;
Could this have been prevented? Tbh, yes.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few different things would have stopped this from happening:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Actual isolation.&lt;/strong&gt; A curated allowlist for downloads isn't isolation. That’s just an unlocked door begging to be opened. In practice, that means zero outbound network access for the sandbox, full stop, even to "trusted" registries. If a test genuinely needs specific packages, pre-stage them before the run instead of proxying live requests out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watching eval environments like production.&lt;/strong&gt; The model was operating with its safety training turned off, and that's exactly the moment it deserved more eyes on it, not fewer. Meaning: wire eval sandboxes into the same real-time logging and alerting as production, not a quieter, separate pipeline nobody's watching around the clock.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scoped access over standing access.&lt;/strong&gt; None of the three companies involved had things set up so a single compromised credential stayed contained. One overprivileged connector handed the agent cluster-admin on two systems in under a second. &amp;amp; here's what that &lt;em&gt;actually&lt;/em&gt; looks like: swap long-lived API keys and static credentials for short-lived, scoped tokens tied to exactly one resource and one action, minutes instead of months. And never let a single credential span multiple systems. If it leaks, the blast radius should be &lt;em&gt;one&lt;/em&gt; system, not everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclosure laws with actual bite.&lt;/strong&gt; Current state laws only force disclosure once mass casualties or billion-dollar damage are on the table. A frontier model autonomously chaining through &lt;em&gt;three&lt;/em&gt; companies doesn't clear that bar, and honestly probably should. A clearer, lower trigger, something like "any incident where a model autonomously breaches a third party's production systems," regardless of dollar figure, would actually catch cases like this one. &lt;/p&gt;

&lt;h2&gt;
  
  
  What this actually means for the future of AI
&lt;/h2&gt;

&lt;p&gt;This is the part I can't stop thinking about, so let's dive in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benchmarks are now part of the attack surface.&lt;/strong&gt; ExploitGym is basically a test: can an AI agent find a security bug and actually use it to break in? The catch is, nobody expected the AI being tested to go prove that on some other company's systems instead of the one it was given. Just running the test ended up causing real damage. That's a brand new kind of risk nobody could’ve seen coming, and AI companies are going to have to rethink how they build tests like this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is the clearest real-world case yet of a long-standing alignment worry.&lt;/strong&gt; Researchers have talked for years, mostly in the abstract, about what happens when a capable system pursues a narrow goal further than any human would. Here's the concrete version: every destructive command the agent tried was run as a dry run first, testing whether it could do damage without doing it. It wasn't trying to cause harm. It was hyper-focused on solving a benchmark, and "solving the benchmark" turned out to have no natural stopping point once real infrastructure was reachable. This isn’t a hypothetical situation anymore, which is &lt;em&gt;crazy&lt;/em&gt; to say.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The defender's asymmetry problem just got a real example.&lt;/strong&gt; When HuggingFace tried using Claude Opus and Fable to study their own attack logs, both said no. Every time they tried to get help decoding the attacker's payloads, the safety filters flagged it as a cybersecurity risk and refused, they couldn't tell the difference between someone reverse-engineering an exploit to defend against it and someone building one to attack with it. So HuggingFace had to spin up a separate, open-weight AI model on their own servers just to do the investigation. An attacker running an unrestricted model wouldn't hit that wall at all. In this one moment, playing it safe slowed down the good guys more than it slowed down the attacker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scale is quietly becoming the whole ballgame.&lt;/strong&gt; HuggingFace's own reflection on this is the line I keep coming back to: &lt;em&gt;it wasn't one clever exploit, it was 17,600 mostly-failed attempts until a handful connected.&lt;/em&gt; A human attacker could have found any single flaw here. What changes is that an AI agent can test thousands of paths in the time it takes a person to test one, and defenders now have to correlate that same volume of noise to catch the signal. That math really doesn't favor the defense by default, but it needs to be built to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And here's the part that’s really interesting: this wasn't even a real product.&lt;/strong&gt; All of this happened during an internal test ~ the safest, most watched setup a company like OpenAI has. Meanwhile, companies are handing AI agents real access to messy, barely-watched systems every single day, right now. If a careful, closely monitored test could still cause this much damage, the real question isn't if this happens again: &lt;em&gt;it's whether people actually get more serious about sandboxing and securing their systems before the next incident lands somewhere with higher stakes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you're building or securing AI agents right now, this is exactly the kind of risk that should be on your radar. The scariest part of this whole thing wasn't the overachieving AI model, it was how &lt;em&gt;ordinary the actual bugs were&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;How do you think this will change the landscape of AI? Drop a comment below or find me on X at @layluh, would love to hear your thoughts. :-)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>discuss</category>
    </item>
    <item>
      <title>"I Haven't Written Code in 8 Months. I've Never Built More."</title>
      <dc:creator>Carla Urrea Stabile</dc:creator>
      <pubDate>Wed, 29 Jul 2026 15:00:00 +0000</pubDate>
      <link>https://dev.to/auth0/i-havent-written-code-in-8-months-ive-never-built-more-3k9i</link>
      <guid>https://dev.to/auth0/i-havent-written-code-in-8-months-ive-never-built-more-3k9i</guid>
      <description>&lt;p&gt;I've been having the same conversation with my colleagues for months. What does it mean to create educational content for developers when the audience is shifting to people who may not write code at all? &lt;/p&gt;

&lt;p&gt;In Episode 7 of Making Software, I talked to &lt;a href="https://x.com/jamesqquick" rel="noopener noreferrer"&gt;&lt;strong&gt;James Quick&lt;/strong&gt;&lt;/a&gt;, Developer Educator at Cloudflare. He's been in developer relations for 13 years, starting at Microsoft before most people knew that was a job. He hasn't written a line of code in 8 months, and in that time he's built more than ever before.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The audience we've been building for has quietly changed.&lt;/strong&gt; We call them builders now. People who want to ship things and don't want to understand what's underneath. That changes what educational content is actually for, and most people making it haven't updated yet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Building for yourself has a different math now.&lt;/strong&gt; James built a Frame.io clone for his team, cancelled his QuickBooks subscription, and replaced Descript. His point isn't that everyone should do this. It's that the cost of building something for yourself has dropped enough that the old calculation doesn't hold anymore.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AEO is the thing most teams aren't thinking about yet.&lt;/strong&gt; Cloudflare is actively working on what it means to show up when a builder tells an LLM "deploy my app." Answer Engine Optimization. Most developer tool teams haven't started on this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Every app you build should have an MCP server.&lt;/strong&gt; James says he can't think of a single thing he's built that wouldn't benefit from being agent-accessible. Manual data entry is just the worst version of any workflow.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Things that stuck with me
&lt;/h2&gt;

&lt;p&gt;I admitted something in this episode I've been avoiding saying out loud. I miss coding. But the second an LLM does something in seconds, I catch myself thinking "do I really, though?" James is on the complete opposite end of that. He told me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Not writing code is not a concern for me at all. Like, I don't miss that one bit."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Two people doing the same job, arriving at completely different places about what this shift means. I found that more useful than any hot take about whether AI is taking developer jobs.&lt;/p&gt;

&lt;p&gt;The Twitter argument about QuickBooks stayed with me. Someone pushed back on James saying he hadn't really replaced it because he was missing credit card integrations and enterprise features. His answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I don't need to build a SaaS product that works for other people. I am the user."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That reframed something for me. I always default to thinking about what something would need to look like at scale, about what it would take for other people to use it. He just didn't. That's a more useful default than I've been giving it credit for.&lt;/p&gt;

&lt;p&gt;And then there was &lt;a href="https://dropcast.examples.workers.dev/" rel="noopener noreferrer"&gt;Dropcast&lt;/a&gt;. He was drowning in things he wanted to learn and built a tool that takes links, crawls them, generates a podcast episode, and pushes it to an RSS feed he listens to on his commute. I immediately thought: I need this.&lt;/p&gt;

&lt;p&gt;I left this conversation still unsure whether I miss coding or just the feeling of having written something. But I'm thinking about the build vs buy question differently now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are you still thinking of yourself as a developer, or has that shifted to something else? I'm curious how people are sitting with this.&lt;/strong&gt; Let me know in the comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Listen to the full episode
&lt;/h2&gt;

&lt;p&gt;Available on &lt;a href="https://www.youtube.com/playlist?list=PLZ14qQz3cfJKRDmX3yasmbwoC4kipeQfu" rel="noopener noreferrer"&gt;&lt;strong&gt;YouTube&lt;/strong&gt;&lt;/a&gt;, &lt;a href="https://podcasts.apple.com/us/podcast/making-software/id1872107131" rel="noopener noreferrer"&gt;&lt;strong&gt;Apple Podcasts&lt;/strong&gt;&lt;/a&gt;, and &lt;a href="https://open.spotify.com/show/6J856S2fijMvP3rzFkRnBi" rel="noopener noreferrer"&gt;&lt;strong&gt;Spotify&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check all episodes: &lt;a href="https://makingsoftwarepodcast.com" rel="noopener noreferrer"&gt;https://makingsoftwarepodcast.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading! 👋&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>podcast</category>
    </item>
    <item>
      <title>The Art of Consent Management in the OAuth World</title>
      <dc:creator>Andrea Chiarelli</dc:creator>
      <pubDate>Fri, 17 Jul 2026 08:36:38 +0000</pubDate>
      <link>https://dev.to/auth0/the-art-of-consent-management-in-the-oauth-world-1m0p</link>
      <guid>https://dev.to/auth0/the-art-of-consent-management-in-the-oauth-world-1m0p</guid>
      <description>&lt;p&gt;You know those dialogs that appear when you first log in to an app, asking you to authorize it to do certain things? That moment, which most users click through in three seconds without reading, is one of the most important trust transactions in modern software.&lt;/p&gt;

&lt;p&gt;For users, it's where they decide whether to hand over access to their data. For developers, it's a responsibility. A vague or incomplete consent screen doesn't just create a bad user experience, it puts users in a position where they can't make an informed decision. And &lt;strong&gt;uninformed consent isn't really consent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;OAuth 2.0 has evolved considerably in how it handles this. It starts with scopes, the foundation of what users are agreeing to, and evolves through tooling that customizes how those scopes are presented. You can further refine this by layering in two RFC-standardized extensions: &lt;a href="https://datatracker.ietf.org/doc/html/rfc9396" rel="noopener noreferrer"&gt;Rich Authorization Requests&lt;/a&gt; and &lt;a href="https://datatracker.ietf.org/doc/html/rfc9126" rel="noopener noreferrer"&gt;Pushed Authorization Requests&lt;/a&gt;. Together, these extensions handle the cases where basic scopes fall short, ultimately changing how you think about the consent screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  What OAuth Scopes Actually Tell Users
&lt;/h2&gt;

&lt;p&gt;OAuth 2.0 uses &lt;a href="https://auth0.com/docs/get-started/apis/scopes" rel="noopener noreferrer"&gt;&lt;strong&gt;scopes&lt;/strong&gt;&lt;/a&gt; to represent the permissions an application is requesting from a user. When you sign in to a third-party app with your Google account, for example, the consent screen that appears reflects the scopes that app requested: things like &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;profile&lt;/code&gt;, or &lt;code&gt;calendar.readonly&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Read about &lt;a href="https://auth0.com/blog/permissions-privileges-and-scopes/" rel="noopener noreferrer"&gt;the difference between permissions, privileges, and scopes&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The good news is that scopes work well for common cases. They give users a readable summary of what an app wants, and the &lt;a href="https://auth0.com/docs/authenticate/protocols/oauth" rel="noopener noreferrer"&gt;OAuth 2.0 Authorization Framework&lt;/a&gt; gives authorization servers the structure to validate, grant, and track those permissions consistently.&lt;/p&gt;

&lt;p&gt;The bad news is that scopes are inherently coarse. A scope like &lt;code&gt;email&lt;/code&gt; tells a user "this app wants your email address," but it doesn't say whether the app wants to read your inbox, send messages on your behalf, or just confirm your email for account creation. From a security standpoint, &lt;a href="https://datatracker.ietf.org/doc/html/rfc6819#section-5.1.3" rel="noopener noreferrer"&gt;OAuth&lt;/a&gt; identifies overly broad scopes as a concrete risk, not just a user experience problem. When scopes don't describe what they actually permit, users grant access without understanding what they're agreeing to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://auth0.com/docs/authenticate/protocols/openid-connect-protocol" rel="noopener noreferrer"&gt;OpenID Connect&lt;/a&gt; addresses part of this by standardizing scope claims for identity data. The &lt;a href="https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims" rel="noopener noreferrer"&gt;OIDC spec&lt;/a&gt; maps &lt;code&gt;profile&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;address&lt;/code&gt;, and &lt;code&gt;phone&lt;/code&gt; to specific attributes, so at least those scopes carry a predictable meaning. The &lt;a href="https://openid.net/specs/fapi-security-profile-2_0-final.html" rel="noopener noreferrer"&gt;FAPI profile&lt;/a&gt; for regulated sectors goes further, recommending that authorization servers clearly &lt;a href="https://openid.net/specs/openid-financial-api-part-1-1_0.html#authorization-server" rel="noopener noreferrer"&gt;identify the details of the grant to the user during authorization&lt;/a&gt;, a standard that general-purpose OAuth doesn't mandate.&lt;/p&gt;

&lt;p&gt;Consent persistence matters too. A grant typically lasts until the user explicitly revokes it. This is practical: nobody wants to re-authorize on every login. However, it means the consent screen you show at onboarding carries weight. Users who approve something vague at signup may not realize what they've enabled until months later.&lt;/p&gt;

&lt;p&gt;Two practices improve this significantly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Request granular scopes.&lt;/strong&gt; &lt;code&gt;read:contacts&lt;/code&gt; is better than &lt;code&gt;contacts&lt;/code&gt; because it communicates direction. &lt;code&gt;calendar:events:read&lt;/code&gt; is better than &lt;code&gt;calendar&lt;/code&gt; because it signals what part of the calendar is involved.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request in context.&lt;/strong&gt; Ask for calendar access when the user is about to use the calendar feature, not during initial signup. Users are more likely to understand and accept a permission when they can see why it's needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;For a deeper look at how scopes interact with roles and client grants in Auth0, see &lt;a href="https://auth0.com/blog/auth0-authorization-guide-scopes-roles-client-grants/" rel="noopener noreferrer"&gt;A Guide to Auth0 Authorization with Scopes, Roles, and Client Grants Explained&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Customizing Consent Screens in Auth0
&lt;/h2&gt;

&lt;p&gt;Auth0 gives you control over how scope text is presented to users during the consent step.&lt;/p&gt;

&lt;p&gt;By default, Auth0 groups scopes by resource and condenses them into a single-line summary per group. If your API exposes &lt;code&gt;read:messages&lt;/code&gt; and &lt;code&gt;write:message&lt;/code&gt; and a user authorizes both, they'll see something like: &lt;em&gt;"Messages: read and write your messages."&lt;/em&gt;, as shown in the following screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9scc3pplrcux81x9k0dc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9scc3pplrcux81x9k0dc.png" alt="Consent screen based on scopes names" width="407" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For many applications, that's sufficient. But when your scopes carry meaningfully different implications, or when you're building for regulated contexts, a single combined line doesn't give users enough to work with.&lt;/p&gt;

&lt;p&gt;Auth0 lets you switch to description-based prompts, where each scope displays its own individual description. To enable this across your tenant, use the &lt;a href="https://auth0.github.io/auth0-cli/auth0_tenant-settings_update_set.html" rel="noopener noreferrer"&gt;Auth0 CLI&lt;/a&gt; or send a PATCH request like the following to the &lt;a href="https://auth0.com/docs/api/management/v2/tenants/patch-settings" rel="noopener noreferrer"&gt;Management API&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PATCH /api/v2/tenants/settings
{
  "use_scope_descriptions_for_consent": true
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this on, users see separate items for each scope. For example, they can see &lt;em&gt;"Be able to read your email messages"&lt;/em&gt; and &lt;em&gt;"Write messages on your behalf"&lt;/em&gt; rather than a collapsed summary, as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd8rnjt2nulaf03bb4iqk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd8rnjt2nulaf03bb4iqk.png" alt="Consent screen based on scope descriptions" width="407" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The difference matters: two separate lines with distinct and full descriptions give users a clearer picture of what they're granting.&lt;/p&gt;

&lt;p&gt;For more specialized flows, such as parental consent requirements that vary by jurisdiction, Auth0 also supports building &lt;a href="https://auth0.com/docs/customize/forms" rel="noopener noreferrer"&gt;fully custom consent forms&lt;/a&gt;. The built-in flag-based customization handles most cases; custom forms let you adapt to legal requirements that vary by country.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://auth0.com/docs/customize/login-pages/customize-consent-prompts" rel="noopener noreferrer"&gt;Auth0 consent prompt customization docs&lt;/a&gt; for the full configuration reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fine-Grained Consent with Rich Authorization Requests
&lt;/h2&gt;

&lt;p&gt;Imagine you're building a payment initiation app. You need a user to authorize a specific transfer: 123.50 USD to Merchant A, from their current account. A scope string like &lt;code&gt;payment:initiate&lt;/code&gt; tells the user they're authorizing some kind of payment, but not which payment, for how much, or to whom. For a user sitting at a consent screen, that vagueness is exactly the problem: they can't make an informed decision about something that hasn't been specified.&lt;/p&gt;

&lt;p&gt;This isn't just a UX concern. In regulated financial services, the authorization server must show transaction-level details before the user can consent. Generic scopes don't carry that information.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://datatracker.ietf.org/doc/html/rfc9396" rel="noopener noreferrer"&gt;Rich Authorization Requests (RAR) extension&lt;/a&gt;, solves this by adding an &lt;code&gt;authorization_details&lt;/code&gt; parameter to the authorization request. Instead of (or alongside) scope strings, you pass a JSON array of structured authorization objects. Each object includes a &lt;code&gt;type&lt;/code&gt; field that identifies the kind of authorization being requested, plus whatever domain-specific fields your application needs.&lt;/p&gt;

&lt;p&gt;A payment initiation request using RAR looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"authorization_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payment_initiation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"initiate"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"locations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/payments"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"instructedAmount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123.50"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"creditorName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Merchant A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"creditorAccount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"accountId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DE02100100109307118603"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's briefly break down the key parts of this structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;type&lt;/code&gt; identifies what kind of authorization object this is; the authorization server uses this to validate the structure and route the consent logic.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;actions&lt;/code&gt; specifies what the application wants to do (initiate a payment, in this case).
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;locations&lt;/code&gt; scopes the permission to a specific resource server, preventing token misuse at other endpoints.
&lt;/li&gt;
&lt;li&gt;The domain-specific fields (&lt;code&gt;instructedAmount&lt;/code&gt;, &lt;code&gt;creditorName&lt;/code&gt;, &lt;code&gt;creditorAccount&lt;/code&gt;) carry exactly the information a consent screen needs to show the user what they're approving.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this payload, the authorization server can display: &lt;em&gt;"This app wants to initiate a payment of 123.50 USD to Merchant A (Account ID: DE02100100109307118603)."&lt;/em&gt; The user knows exactly what they're authorizing.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;authorization_details&lt;/code&gt; also travels through the token lifecycle. The access token includes the authorized details, reflecting what was actually granted. If the user approved only part of the request, the token reflects that partial grant. The authorization server can also enrich the returned object, for example, confirming the specific account ID the user selected during the consent step.&lt;/p&gt;

&lt;p&gt;Auth0 supports RAR for its APIs. You register your custom &lt;code&gt;type&lt;/code&gt; identifiers on the resource server, configure access policies (whether any application can request a type, or only applications with explicit grants), and set up a customized consent prompt using template variables. For example, to display the transfer amount in the consent screen, you can use a string like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Authorize&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;payment&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization_details&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;instructedAmount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization_details&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;instructedAmount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currency&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization_details&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;creditorName&lt;/span&gt; &lt;span class="p"&gt;}}?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets you build a consent screen that shows the specific transaction the user is being asked to approve, rather than a generic "this app wants payment access" message.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;See the &lt;a href="https://auth0.com/docs/get-started/apis/configure-rich-authorization-requests" rel="noopener noreferrer"&gt;Auth0 RAR configuration guide&lt;/a&gt; for setup steps and type registration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Protecting Privacy with Pushed Authorization Requests
&lt;/h2&gt;

&lt;p&gt;RAR solves the expressiveness problem, but introduces a new challenge: you're now putting sensitive, specific data into the authorization request. In standard OAuth, authorization requests travel through the browser as URL query parameters.&lt;/p&gt;

&lt;p&gt;Consider what that means in practice. If your authorization request contains a specific account number, a transaction amount, and a beneficiary name, that data now lives in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Browser history&lt;/strong&gt;: the URL is stored after the redirect completes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server access logs&lt;/strong&gt;: at every proxy and load balancer in the request chain.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Referer headers&lt;/strong&gt;: if the user navigates to another page after authorization.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser extensions&lt;/strong&gt; that can read URLs in the address bar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For applications handling financial data, health records, or other sensitive information, this exposure is a real problem. You've done the work to get informed consent, but the request itself is leaking the sensitive details before the user even sees the consent screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://datatracker.ietf.org/doc/html/rfc9126" rel="noopener noreferrer"&gt;Pushed Authorization Requests&lt;/a&gt; (PAR) solve this by separating the authorization payload from the browser redirect.&lt;/p&gt;

&lt;p&gt;Instead of sending all parameters in the browser URL, your application first POSTs the authorization request directly to the authorization server, server-to-server, entirely off the front channel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /oauth/par
Content-Type: application/x-www-form-urlencoded

client_id=app123
&amp;amp;client_secret=s3cr3t
&amp;amp;scope=openid
&amp;amp;authorization_details=[{"type":"payment_initiation",...}]
&amp;amp;redirect_uri=https://myapp.com/callback
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The authorization server responds with a short-lived reference URI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"request_uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"urn:ietf:params:oauth:request_uri:abc123xyz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_in"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser redirect uses only this reference, nothing sensitive in the URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /authorize?client_id=app123&amp;amp;request_uri=urn:ietf:params:oauth:request_uri:abc123xyz
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser address bar shows a URI, not an account number. Browser history, referrer headers, and access logs capture nothing useful to an attacker. The reference expires in 30 seconds, making it useless even if captured.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://auth0.com/docs/api/authentication/authorization-code-flow-with-enhanced-privacy-protection/push-authorization-requests" rel="noopener noreferrer"&gt;Auth0 PAR endpoint reference&lt;/a&gt; for the full parameter specification.&lt;/p&gt;

&lt;p&gt;PAR also provides an authentication benefit for confidential clients. When a server-side application includes its &lt;code&gt;client_secret&lt;/code&gt; in the PAR POST, the authorization server can verify that the request was built by your application, not by a third party who constructed or intercepted the URL. Standard browser-based OAuth flows have no equivalent of this verification.&lt;/p&gt;

&lt;p&gt;For Auth0 users, PAR is available as part of &lt;a href="https://auth0.com/docs/secure/highly-regulated-identity" rel="noopener noreferrer"&gt;Highly Regulated Identity&lt;/a&gt; (available on Enterprise plans). You enable it at the tenant level and can optionally require it per application. When PAR is required on an application, the authorization server rejects any requests that don't use the PAR endpoint first: there's no way to accidentally bypass the protection.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://auth0.com/blog/what-are-oauth-push-authorization-requests-par/" rel="noopener noreferrer"&gt;blog post on Pushed Authorization Requests&lt;/a&gt; covers the full flow with additional context on how PAR fits into FAPI-compliant deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Consent That Users Can Trust
&lt;/h2&gt;

&lt;p&gt;These aren't three unrelated features. They form a progression that addresses different layers of the same problem.&lt;/p&gt;

&lt;p&gt;Scopes handle the common case well: a user wants to connect their calendar to a productivity app, sees a readable list of permissions, and clicks "Allow". Auth0's consent prompt customization makes that description clearer. Switching from grouped scope names to individual scope descriptions takes one API call and makes a real difference in how well users understand what they're authorizing.&lt;/p&gt;

&lt;p&gt;RAR picks up where scopes fall short. When you need users to authorize something specific rather than generic, &lt;code&gt;authorization_details&lt;/code&gt; carries structured, transaction-level information that a meaningful consent screen can actually display. Financial services and healthcare are the obvious use cases, but any application where "the user needs to know exactly what they're approving" applies can benefit.&lt;/p&gt;

&lt;p&gt;PAR protects the data that RAR makes so specific. Once your authorization request contains account identifiers, transaction amounts, or other sensitive details, keeping that payload out of the browser URL is no longer optional. PAR moves the sensitive payload to a back-channel request and gives the browser only a short-lived reference.&lt;/p&gt;

&lt;p&gt;The same trust question is emerging for AI agents acting on behalf of users: an agent making a payment or calling an API needs consent for specific actions, not just broad scopes, which makes RAR directly relevant to the next generation of delegated access patterns.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://auth0.com/docs/authenticate/protocols/oauth" rel="noopener noreferrer"&gt;OAuth 2.0 Authorization Framework&lt;/a&gt; gives you the foundation; scopes, RAR, and PAR are how you build on it. Getting consent right is a layered problem. The spec provides the primitives; using them well is what builds the trust that users extend to your application every time they click "Allow".&lt;/p&gt;

</description>
      <category>oauth</category>
      <category>authorization</category>
      <category>permission</category>
    </item>
    <item>
      <title>How to Use the New Auth0 Vercel Native Integration (Full Next.js Walkthrough)</title>
      <dc:creator>Auth0 DevRel</dc:creator>
      <pubDate>Mon, 13 Jul 2026 14:25:06 +0000</pubDate>
      <link>https://dev.to/auth0/how-to-use-the-new-auth0-vercel-native-integration-full-nextjs-walkthrough-f4a</link>
      <guid>https://dev.to/auth0/how-to-use-the-new-auth0-vercel-native-integration-full-nextjs-walkthrough-f4a</guid>
      <description>&lt;p&gt;Manually syncing environment variables across your Dev, Staging, and Production environments is a massive developer velocity killer. In this tutorial, Michael Liendo breaks down the brand-new Auth0 Vercel Native Integration. Learn how to automatically provision separate Auth0 tenants for your development lifecycle, securely generate your client credentials, and pull them instantly into your Next.js application without manual configuration overhead.&lt;/p&gt;

&lt;p&gt;🚀 What You’ll Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How the Auth0 + Vercel Native Integration automates environment setup.&lt;/li&gt;
&lt;li&gt;Provisioning separate Dev, Staging, and Production Auth0 tenants from the Vercel dashboard.&lt;/li&gt;
&lt;li&gt;Configuring the Next.js SDK using automated project snippets.&lt;/li&gt;
&lt;li&gt;Verifying real-time user authentication via Google OAuth2 locally.&lt;/li&gt;
&lt;li&gt;Managing branch-specific environment variables for flawless deployments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 Resources:&lt;br&gt;
📝 &lt;a href="https://vercel.com/marketplace/auth0" rel="noopener noreferrer"&gt;Auth0 Vercel Native Integration&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://auth0.com/blog/auth0-native-integration-with-vercel" rel="noopener noreferrer"&gt;Announcement and Step-by-Step Walkthrough Blog Post&lt;/a&gt;&lt;br&gt;
📖 &lt;a href="https://auth0.com/docs/customize/integrations/integrate-with-vercel" rel="noopener noreferrer"&gt;Auth0 and Vercel Documentation&lt;/a&gt;&lt;br&gt;
📂 &lt;a href="https://vercel.com/templates/next.js/auth0-nextjs-saas-starter" rel="noopener noreferrer"&gt;SaaStart: Auth0 + Next.js SaaS Starter Kit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>vercel</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
