<?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: Fathin Dosunmu</title>
    <description>The latest articles on DEV Community by Fathin Dosunmu (@fathin_dosunmu).</description>
    <link>https://dev.to/fathin_dosunmu</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%2Fuser%2Fprofile_image%2F3841424%2F292fa61c-53e4-4f93-baae-9ef0672779c1.jpg</url>
      <title>DEV Community: Fathin Dosunmu</title>
      <link>https://dev.to/fathin_dosunmu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fathin_dosunmu"/>
    <language>en</language>
    <item>
      <title>Why AI Agents Fail at Login Walls: SMS, OTP, Passkeys, CAPTCHA</title>
      <dc:creator>Fathin Dosunmu</dc:creator>
      <pubDate>Mon, 05 Oct 2026 20:59:53 +0000</pubDate>
      <link>https://dev.to/fathin_dosunmu/why-ai-agents-fail-at-login-walls-sms-otp-passkeys-captcha-22d4</link>
      <guid>https://dev.to/fathin_dosunmu/why-ai-agents-fail-at-login-walls-sms-otp-passkeys-captcha-22d4</guid>
      <description>&lt;p&gt;Agents can open a browser, click through a form, and call APIs. Then they hit a login wall and the run becomes weird.&lt;/p&gt;

&lt;p&gt;The browser waits for a code. A phone receives an SMS. A link lands in an inbox. A passkey prompt asks for a device. A CAPTCHA asks for proof that the actor is not automation.&lt;/p&gt;

&lt;p&gt;The agent keeps waiting because the challenge moved outside the page it can see.&lt;/p&gt;

&lt;p&gt;That is the real failure: the system treats authentication as a local browser step, but the proof lives across channels, people, devices, policies, and time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Login is not one step
&lt;/h2&gt;

&lt;p&gt;A human login flow hides a lot of state.&lt;/p&gt;

&lt;p&gt;The person knows which account they are using. They can reach the phone or inbox. They understand whether a prompt belongs to the current attempt. They know when to stop. They can decide that a CAPTCHA or passkey prompt means "I need to take over."&lt;/p&gt;

&lt;p&gt;An agent does not automatically have that context. Without a control layer, it only sees:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A form.&lt;/li&gt;
&lt;li&gt;A challenge.&lt;/li&gt;
&lt;li&gt;A timeout.&lt;/li&gt;
&lt;li&gt;Maybe a pasted secret.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is not enough for a reliable run.&lt;/p&gt;

&lt;h2&gt;
  
  
  The login wall map
&lt;/h2&gt;

&lt;p&gt;Different walls fail agents in different ways:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Wall&lt;/th&gt;
&lt;th&gt;Where the browser loses context&lt;/th&gt;
&lt;th&gt;Safe product behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SMS&lt;/td&gt;
&lt;td&gt;The code arrives outside the browser.&lt;/td&gt;
&lt;td&gt;Wait under policy, consume once, return a verdict.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Email OTP&lt;/td&gt;
&lt;td&gt;The proof moves to an inbox.&lt;/td&gt;
&lt;td&gt;Resolve whether this inbox is approved for this run.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Magic link&lt;/td&gt;
&lt;td&gt;Opening the link may be the login action.&lt;/td&gt;
&lt;td&gt;Bind the link to the right authority and target.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Passkey&lt;/td&gt;
&lt;td&gt;The service wants device and origin proof.&lt;/td&gt;
&lt;td&gt;Ask for takeover or fail closed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CAPTCHA&lt;/td&gt;
&lt;td&gt;Automation is being challenged.&lt;/td&gt;
&lt;td&gt;Stop or use an approved test path.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important thing is not "can the browser keep clicking?" It is whether the agent has a governed branch when the proof channel leaves the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  SMS and OTP are state problems
&lt;/h2&gt;

&lt;p&gt;SMS looks simple because the payload is small. Enter number. Wait for code. Submit code.&lt;/p&gt;

&lt;p&gt;In practice, the useful state is larger:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Is this an app you own or are authorized to test?&lt;/td&gt;
&lt;td&gt;Otherwise the agent is trying to automate someone else's account boundary.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Which run requested this code?&lt;/td&gt;
&lt;td&gt;Old or parallel messages can be consumed by the wrong attempt.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is the number allowed by the target app?&lt;/td&gt;
&lt;td&gt;The app can reject a number before any carrier delivery happens.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Did the message arrive inside the wait window?&lt;/td&gt;
&lt;td&gt;Late codes can be unsafe to reuse.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Was the code consumed once?&lt;/td&gt;
&lt;td&gt;Two agents should not race the same credential.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What happens if access is revoked while the agent waits?&lt;/td&gt;
&lt;td&gt;The safe answer is a stopped branch, not a leaked result.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important part is not just delivery. It is associating the code with the right authority, the right target, the right session, and the right outcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Email OTP and magic links move the wall
&lt;/h2&gt;

&lt;p&gt;Email challenges move the proof to another inbox.&lt;/p&gt;

&lt;p&gt;For test environments, injected email OTPs and magic links can prove your parser and run logic. For production-like flows, the inbox is part of the identity boundary.&lt;/p&gt;

&lt;p&gt;A magic link is especially sensitive because clicking it can be the login action, not just a way to retrieve a code.&lt;/p&gt;

&lt;p&gt;The agent needs an answer to: "Am I allowed to use this mailbox for this target, right now?" If the answer is not explicit, the run should pause or stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passkeys are not passwords with nicer UI
&lt;/h2&gt;

&lt;p&gt;A passkey prompt usually means the service wants proof tied to a device, origin, and credential holder. It is not just asking for text.&lt;/p&gt;

&lt;p&gt;For an agent, a passkey prompt should usually become a branch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ask for human takeover,&lt;/li&gt;
&lt;li&gt;switch to a supported test path,&lt;/li&gt;
&lt;li&gt;or fail closed with a clear reason.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Treating passkeys as something to bypass misses the point. They are designed to bind the login to a trusted device and origin. A safe agent workflow should respect that boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  CAPTCHA is a stop sign, not a missing solver
&lt;/h2&gt;

&lt;p&gt;CAPTCHA exists to challenge automation. That means the honest product behavior is not "silently solve it and keep going."&lt;/p&gt;

&lt;p&gt;For owned tests, you can use staging controls, test bypasses, allowlisted origins, or app-level policy.&lt;/p&gt;

&lt;p&gt;For third-party destinations, a CAPTCHA is often the moment to stop. The agent should report a clear result rather than spin, scrape, or pretend the run is still healthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The agent needs a branch, not just a browser
&lt;/h2&gt;

&lt;p&gt;The better model is a state machine around the login wall:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent reaches login wall
        |
        v
challenge detected
        |
        v
policy checks actor, owner, target, channel, allowance, revocation
        |
        v
structured verdict
        |
        +--&amp;gt; code received: continue the authorized run
        +--&amp;gt; timeout: retry only if policy allows
        +--&amp;gt; access revoked: stop safely
        +--&amp;gt; passkey required: request takeover or stop
        +--&amp;gt; CAPTCHA: stop or use an approved test path
        +--&amp;gt; target refused: report the refusal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where "operational identity" becomes concrete.&lt;/p&gt;

&lt;p&gt;The agent is not merely holding a token or watching a browser. It is acting under a named authority, against an approved target, with a lifecycle that can be revoked and audited.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AgentSIM fits
&lt;/h2&gt;

&lt;p&gt;AgentSIM is the control plane for agents hitting auth walls in services you own or are authorized to automate.&lt;/p&gt;

&lt;p&gt;Today, live SMS is the supported challenge path for verified owned apps. AgentSIM opens a challenge, applies policy, waits for a verdict, and returns a structured outcome to the agent.&lt;/p&gt;

&lt;p&gt;Email OTP and magic links can be exercised with injected test messages. Passkeys and CAPTCHA are treated as stopping conditions unless your environment has an approved test path.&lt;/p&gt;

&lt;p&gt;The narrowness is deliberate. A safe product should not claim universal access to every login wall. It should make authority explicit, return clear outcomes, and fail closed when the wall means "do not continue."&lt;/p&gt;

&lt;h2&gt;
  
  
  The practical test
&lt;/h2&gt;

&lt;p&gt;If your agent hits a login wall, ask five questions before adding another browser trick:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Who is the agent acting for?&lt;/li&gt;
&lt;li&gt;Is the target service owned or authorized?&lt;/li&gt;
&lt;li&gt;Which channel carries the proof?&lt;/li&gt;
&lt;li&gt;What exact outcomes can the agent receive?&lt;/li&gt;
&lt;li&gt;What happens if authority changes mid-run?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If those answers live only in a prompt, the run is fragile. If they live in a state machine with policy and evidence, the agent can make progress without pretending to be a human.&lt;/p&gt;

&lt;p&gt;The future is not agents that bypass every wall. It is agents that understand which wall they hit, which authority they hold, and which branch is safe next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agentsim.dev/blog/why-ai-agents-fail-at-login-walls?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=login_wall_agents" rel="noopener noreferrer"&gt;Read the canonical AgentSIM article&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.agentsim.dev/quickstart?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=login_wall_agents" rel="noopener noreferrer"&gt;Try the AgentSIM quickstart&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>devtools</category>
      <category>automation</category>
      <category>security</category>
    </item>
    <item>
      <title>Your AI Agent Has an OAuth Token. Does It Have an Identity?</title>
      <dc:creator>Fathin Dosunmu</dc:creator>
      <pubDate>Mon, 07 Sep 2026 21:38:42 +0000</pubDate>
      <link>https://dev.to/fathin_dosunmu/your-ai-agent-has-an-oauth-token-does-it-have-an-identity-a9h</link>
      <guid>https://dev.to/fathin_dosunmu/your-ai-agent-has-an-oauth-token-does-it-have-an-identity-a9h</guid>
      <description>&lt;p&gt;OAuth can prove that a request may reach a resource. It does not, by itself, tell an operator the full story of the actor holding the token.&lt;/p&gt;

&lt;p&gt;That distinction matters once software can plan, call tools, retry, and act across several systems. The question is no longer only, "Is this request authenticated?" It is also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which agent is acting?&lt;/li&gt;
&lt;li&gt;Under whose authority?&lt;/li&gt;
&lt;li&gt;For what purpose?&lt;/li&gt;
&lt;li&gt;Against which target?&lt;/li&gt;
&lt;li&gt;What evidence will remain after the action?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your system cannot answer those questions without reading the agent's prompt, it does not yet have an operational identity model. It has a credential.&lt;/p&gt;

&lt;h2&gt;
  
  
  A token is permission, not the whole identity
&lt;/h2&gt;

&lt;p&gt;OAuth remains essential infrastructure for agents. The &lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization" rel="noopener noreferrer"&gt;current Model Context Protocol authorization specification&lt;/a&gt; builds on OAuth 2.1, Protected Resource Metadata, Client ID Metadata Documents, audience binding, and least-privilege scopes. It also hardens issuer validation, defines step-up authorization, and forbids token passthrough.&lt;/p&gt;

&lt;p&gt;Those controls answer important questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this token intended for this resource?&lt;/li&gt;
&lt;li&gt;Which permissions did the user approve?&lt;/li&gt;
&lt;li&gt;Has the credential expired?&lt;/li&gt;
&lt;li&gt;Does the resource server accept its audience?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But a token is still one artifact inside a larger system. It can carry identity claims, but it does not automatically give that identity a lifecycle, an owner, a purpose, or a useful audit trail.&lt;/p&gt;

&lt;p&gt;An operational identity is the continuity around the token. It says this is the same agent before, during, and after a credential is issued, and that its authority can be understood and withdrawn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Borrowing a human identity breaks the record
&lt;/h2&gt;

&lt;p&gt;The fastest way to get an agent moving is often to lend it a human credential. Copy an API key into the environment. Reuse a browser session. Give it an access token created for an employee.&lt;/p&gt;

&lt;p&gt;Now the log says a person acted when an agent did. The credential may carry every permission the person has, even though the task needed two. Revoking the agent means revoking the human. A later reviewer cannot tell whether an action was approved, inferred, retried, or inherited from a long-lived session.&lt;/p&gt;

&lt;p&gt;This is the identity version of shared passwords. &lt;a href="https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/" rel="noopener noreferrer"&gt;OWASP's Agentic Top 10 for 2026&lt;/a&gt; treats identity and privilege abuse as a distinct agentic risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the authorization record small and resolvable
&lt;/h2&gt;

&lt;p&gt;The exact implementation will differ, but the system should preserve a stable agent identifier, a visible authority chain, a bounded purpose and target, short-lived credentials, revocation, and evidence after the action.&lt;/p&gt;

&lt;p&gt;A conceptual record can stay compact:&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;"agent_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qa-runner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"authority"&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;"workspace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"acme-staging"&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;"purpose"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"verify owned checkout flow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"targets"&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;"staging.acme.test"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scopes"&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;"challenge:open"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"verdict:read"&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_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-07T18:30:00Z"&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 goal is not to force every policy decision into the token. The goal is to make sure the token resolves back to a governed record that is small enough to inspect and specific enough to enforce.&lt;/p&gt;

&lt;p&gt;The current &lt;a href="https://datatracker.ietf.org/doc/html/draft-klrc-aiagent-auth" rel="noopener noreferrer"&gt;IETF Internet-Draft on AI agent authentication and authorization&lt;/a&gt; is useful as a direction of travel, not a finished standard. It treats agents as workloads that need identifiers, credentials, provisioning, authentication, authorization, observability, policy, and compliance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AgentSIM starts
&lt;/h2&gt;

&lt;p&gt;AgentSIM starts when an agent reaches an authentication challenge in an app or environment your organization owns or is authorized to automate.&lt;/p&gt;

&lt;p&gt;Today, SMS OTP is connector zero and the live connector. Email OTP and magic links are mock or inject flows. Passkeys and CAPTCHA are detected stopping conditions, not challenges AgentSIM silently completes.&lt;/p&gt;

&lt;p&gt;The broader North Star is authorization continuity. The identity belongs to the agent. Authority stays with the organization. Every boundary should be explicit, scoped, revocable, and able to return evidence.&lt;/p&gt;

&lt;p&gt;That is narrower than "universal agent identity," and deliberately so. Each boundary needs to work in production before it is described as covered.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five-question test
&lt;/h2&gt;

&lt;p&gt;Before giving an agent another credential, ask whether the system can answer these questions from its records:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which agent used it?&lt;/li&gt;
&lt;li&gt;Who or what delegated the authority?&lt;/li&gt;
&lt;li&gt;What task and target were approved?&lt;/li&gt;
&lt;li&gt;When does that authority end, and how is it revoked?&lt;/li&gt;
&lt;li&gt;What evidence connects the grant to the final action?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the answers are clear, the token belongs to an identity system. If they are not, the token is only access with a hopeful story attached.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agentsim.dev/blog/your-agent-has-a-token-does-it-have-an-identity?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=agent_identity" rel="noopener noreferrer"&gt;Read the canonical AgentSIM article and see the authority model&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>mcp</category>
      <category>security</category>
      <category>authentication</category>
    </item>
  </channel>
</rss>
