identity & security

Everybody Thinks Login Is Easy. Until It Is Not

A login form can be small. The identity system behind it rarely stays that way.

The ticket says, “Add login.”

It sounds like a small feature because the first version often is. A developer adds an email and password form, hashes the password, writes a session cookie, protects a few routes, and creates two test accounts. Both users can sign in and out. The demo works. The ticket moves to done.

That first implementation is not fake or naïve. Under narrow enough conditions, it may be exactly right. The mistake is assuming that the happy path describes the size of the problem.

The system begins to reveal itself when anything happens twice. A user returns on another device. They forget a password. They sign in with Google after creating an account with email. They change jobs. A company asks for single sign-on. A security review asks how sessions are revoked. Support needs to restore access without handing the account to an attacker. None of these are exotic edge cases. They are ordinary life arriving in the application.

That accumulation can now begin before a human reaches the login page. An AI agent may need to call an API, inspect data, or update another system while acting for a person or organization. It does not forget a password in the ordinary sense, but it still needs an identity, a credential, a bounded grant, and a way to lose access. In February 2026, NIST published a concept paper on software and AI agent identity and authorization that explicitly raises identification, authorization, auditing, non-repudiation, and prompt-injection controls. This is not a reason to make every authentication design about AI. It is evidence that the familiar assumption—one human presents one credential to one application—no longer describes every actor a system may have to trust.

Authentication rarely becomes difficult because of one spectacular cryptographic problem. The complexity accumulates through reasonable questions about continuity, risk, ownership, and recovery. Eventually, “login” no longer means checking a credential. It means deciding which person, organization, or piece of software is acting; what evidence is sufficient; what it can access; how long that trust should last; and how to unwind the decision when an assumption fails.

How Login Becomes An Identity System

Every normal requirement adds a decision the first form could not make. First, the Login Screen serves as the visible feature, addressing whether a credential proves enough. Next, the Identity Model handles linking and continuity by establishing which person and account the credential belongs to. For access restoration, Recovery provides fallbacks and support without weakening proof. The Session Lifecycle then manages time, devices, and risk to determine how long trust lasts and how it gets revoked. At an enterprise scale, the Organization Lifecycle governs SSO, provisioning, and policy to clarify which tenant and role a person is acting in. Finally, Delegation & Agents oversees actors, limits, and audits to determine whose authority the software is using.

The First Version Really Can Be Easy

It is tempting to correct anyone who calls login easy. That goes too far. A low-risk internal tool for five known users does not need every control required by a bank or a global business-to-business platform. Building for every future authentication method, enterprise connection, and recovery scenario would be its own engineering failure.

It is not about simple versus complex. It is explicit versus accidental.

A deliberately small implementation might support one login method, short-lived sessions, verified-email recovery, and no organization model. The team knows what it is not trying to solve. An accidentally small implementation looks similar in code, but its assumptions live nowhere. It quietly treats an email address as a permanent identity, a successful sign-in as sufficient authorization, and a password reset as a support detail. Growth does not break those assumptions all at once. It exposes them, one customer request at a time.

This is why authentication complexity feels surprising. The first pull request was scoped around a screen. The product eventually needs a model.

The User in the Table Is Not the Whole User

The first crack often appears in the user table.

Suppose someone creates an account with an email address and password. Months later, they choose “Continue with Google” using the same address. Is that the same person returning with a new credential, or a different identity that happens to present the same string?

Automatically merge the accounts and the experience is smooth—unless the email claim was not strong enough to justify the merge. Keep them separate and the security boundary is cleaner—unless the customer now has two profiles, two purchase histories, and no idea where their data went.

The standards are careful here for a reason. OpenID Connect says an email claim must not be treated as a unique identifier and can change or be reassigned. The stable identifier is the combination of issuer and subject, not whichever human-readable field happens to look familiar (OpenID Connect Core, section 5.7).

That technical rule does not finish the product decision. The application still needs an account-linking policy. It needs to decide when to ask for fresh proof, how to handle an address change, whether one person may have several credentials, and what should happen when two existing accounts genuinely belong to the same person.

At this point, “user” has started to carry too much weight. There is the person, the application account, the credential used to authenticate, the external identity provider, and perhaps several memberships in different organizations. They overlap, but they are not interchangeable. A schema that collapses them into one row will eventually force security decisions through data migrations and support exceptions.

An agent makes that overload easier to see. The person whose authority is being used may not be the software performing the action. The client application, the agent runtime, the external identity, and the organization’s policy can all be distinct. If the data model has room only for “the user,” the agent tends to become either an invisible impersonator or a generic service account. Both shortcuts discard context the product may later need to explain, limit, or revoke the action.

Recovery Is Another Way Into the Account

The next support ticket is predictable: the user can no longer use the credential that was supposed to prove who they are.

Password reset looks like a convenience flow. In security terms, it is a path that allows someone without the password to replace it. Lose a phone or a passkey and the same problem appears with a different interface. Whatever assurance the normal sign-in flow provides can be undercut by a weaker recovery path.

That creates an uncomfortable tradeoff. Recovery has to be usable when a legitimate customer is stressed, locked out, traveling, or missing a device. It also has to resist an attacker who deliberately creates the same story.

The details quickly reach beyond a reset email. Can the response reveal whether an account exists? How long should a recovery token live? Does using it revoke existing sessions? What happens when the attacker also controls the email account? Can an organization administrator reset access for an employee? How does support verify an urgent request without turning personal trivia into an authentication factor?

OWASP’s forgot-password guidance treats enumeration, token handling, rate limiting, and session invalidation as part of the flow. NIST’s current digital identity guidance goes further by treating recovery methods, notifications, and authenticator replacement as a defined lifecycle. The point is not that every application must implement the most demanding version of that guidance. It is that recovery is a security policy, even when part of the policy is carried out by a support team.

Passkeys improve this picture without making it disappear. WebAuthn can remove the shared password and provide authentication ceremonies that resist common phishing attacks; discoverable credentials can also remove the username step (WebAuthn Level 3). Those are meaningful improvements to the authenticator. The application still has to decide how credentials are enrolled, linked, replaced, synchronized across devices, and recovered. A better front door does not answer who is allowed to issue a new key.

A Session Is Login Stretched Across Time

After a user signs in, most applications stop asking for proof on every request. They issue a session identifier or a token and trust it for some period. The login ceremony may last seconds; the decision it creates may last hours, weeks, or months.

Agents stretch that interval in a different way. A human session usually contains long periods when nobody is doing anything. An agent holding a token can continue working, retry a failed operation, or call several tools while the person is elsewhere. A one-hour grant is therefore not only an hour of potential access; it may represent dozens of independent actions. The session policy has to express the maximum autonomous window, who may refresh it, and when a new resource or sensitive action requires fresh human approval.

That shifts the engineering problem. The application must decide where the session lives, how it is protected, when it expires, when it rotates, and how it is revoked. “Log out” might mean ending one browser session, every session on the account, or the session at an upstream identity provider as well. A password change might revoke everything immediately, or it might leave a stolen session active.

OWASP describes a session token as temporarily equivalent to the strongest authentication method the user completed (Session Management Cheat Sheet). That is a useful way to see the risk: a perfect login flow cannot compensate for a session that leaks, never expires, or survives events that should invalidate it.

New clients add more decisions. A mobile app, a single-page application, and a server-rendered web app do not hold credentials in the same way. Redirects, authorization codes, access tokens, refresh tokens, and cross-site request protections create a protocol surface of their own. The OAuth security best-current-practice document is long because implementations have had to adapt to attacks and browser behavior over time; current guidance includes exact redirect matching and PKCE protections that were not part of many early integrations (RFC 9700).

Again, standards reduce risk, but they do not remove judgment. Reading a dashboard may tolerate a long session. Changing a payout destination may require fresh proof. The right boundary depends on what the user is about to do, not only whether they signed in once.

Login Becomes a Production Dependency

Once most requests depend on an identity decision, authentication sits on the application’s critical path. The rest of the product can be healthy while users remain effectively locked out because an identity provider is unavailable, a token-verification key cannot be fetched, or a session store is failing. That creates an operational question as much as a security one: when a dependency is unhealthy, should the application reject every request, trust a recently validated session for a little longer, or preserve only a narrow break-glass path for responders? Failing closed is usually the safer default, but even that choice has consequences when the people needed to repair the system cannot get in.

The public login endpoint also attracts traffic that has nothing to do with legitimate users. Credential stuffing and password spraying turn authentication into an abuse surface with its own capacity, detection, and response needs. A blunt lockout rule can be weaponized to deny access to a known account. A rate limit that is too loose protects the user experience by letting the attack continue. Effective defenses combine controls and signals rather than relying on one IP address or one threshold; OWASP’s credential-stuffing guidance treats this explicitly as a defense-in-depth problem.

Observability is awkward for the same reason. The team needs enough information to distinguish a mistyped password from a distributed attack, investigate an account takeover, and answer which sessions or credentials were affected. But the authentication system handles exactly the values that should not spill into ordinary telemetry. OWASP recommends logging authentication successes and failures while excluding or protecting passwords, access tokens, session identifiers, encryption keys, and sensitive personal data. Good authentication logs describe the event without becoming a second credential store.

Agent activity makes that audit model more demanding. Recording only the customer’s user ID is insufficient when an agent, an orchestration service, or a chain of tools performed the action. An investigation may need to recover the subject whose authority was used, the actor that made the call, the grant in effect, the resource touched, and the outcome—without turning prompts, tokens, or private tool inputs into indiscriminate log data. The subject-versus-actor distinction is not protocol trivia once someone has to explain why a system changed.

Incidents expose another hidden lifecycle. Teams may need to revoke sessions, rotate signing keys or client secrets, disable an upstream connection, and identify every dependent service before restoring access. Rotation is not merely generating a new value; consumers have to accept the transition without creating either an outage or an indefinite overlap. OWASP’s secrets-management guidance treats creation, rotation, revocation, expiration, auditing, and break-glass recovery as parts of the same operational discipline.

Using a managed identity service can remove much of this machinery, just as it can remove protocol implementation. It still leaves the application with failure modes to choose and rehearse. Authentication needs owners, monitoring, incident procedures, and tested recovery paths because it is no longer only the code that lets a user in. It is infrastructure that can keep everyone out.

Companies Do Not Fit Inside a Sign-In Form

Then the first enterprise customer arrives and asks for SSO.

The request sounds like another login button. It usually introduces an organization model: which identity provider serves which customer, how a user is routed to it, whether a domain can be trusted, what happens to contractors, how administrator access is recovered, and whether the same person can belong to several organizations with different policies.

Successful authentication also does not answer whether the person should still have an account. Companies hire, transfer, and terminate employees. Groups change. Access needs to be created and removed without waiting for someone to try logging in. SCIM exists specifically to provision and manage identity data such as users and groups across domains (RFC 7644). Its existence is a reminder that sign-in and identity lifecycle are related systems, not the same operation.

Agents create a downstream version of the same lifecycle problem. Disabling an employee’s interactive account may not revoke refresh tokens, scheduled jobs, agent grants, or credentials derived from authority that employee approved earlier. Sometimes the organization should own and reassign that automation. Sometimes continued execution would be exactly the outcome offboarding was meant to prevent. The application needs to know which case it created; a successful login and a disabled user record do not answer it.

Now the application has at least three questions to answer. Who is this person? In which organizational capacity are they acting? What are they allowed to do here? Authentication, tenancy, and authorization meet at the same request, but treating them as one concept creates dangerous shortcuts. A user can authenticate correctly and still arrive in the wrong organization, keep a role they should have lost, or cross a tenant boundary the data model failed to enforce.

Business constraints sharpen every choice. Strict session limits can reduce exposure and increase support volume. Automatic account linking can remove friction and create takeover risk. An administrator-assisted recovery path can keep a customer operating and concentrate dangerous power in one role. The engineering work is not to discover a control with no cost. It is to make the tradeoff visible enough that the team can own it.

The Next User May Not Be Human

AI agents make all of these earlier tensions arrive at once. They do not replace the old identity questions; they separate actors that a human login often allowed the product to treat as one.

Imagine an agent that reads a user’s calendar, drafts email, updates a CRM record, and calls several tools while the user is elsewhere. Saying “the user authorized it” is not enough for an audit trail. The system may need to know both whose authority is being used and which actor performed the action. It also needs limits: which resources, which actions, for how long, under which conditions, and with what revocation path.

This distinction predates the current agent wave. OAuth token exchange separates impersonation, where one principal effectively becomes another within a context, from delegation, where the acting principal keeps its own identity while representing someone else (RFC 8693). Agents make that distinction more urgent because they can act asynchronously, call several systems, and continue operating after the moment when a person clicked “allow.”

Agent-specific identity is still unsettled. Current work includes individual Internet-Drafts proposing dedicated identity and delegation layers, but these are proposals rather than consensus (a draft agent-identity protocol). The durable point is simpler: giving software a user’s long-lived token and calling the result “logged in” erases information the system may later need for consent, least privilege, revocation, and accountability. Agents are not a separate authentication universe. They are another reason the identity model has to represent more than one successful sign-in.

What the Ticket Was Really Asking

Recognizing this complexity does not mean every team should build an identity platform. In many cases, the best engineering decision is to rely on a service or a well-maintained framework for protocol implementation, credential storage, attack defenses, and standards support. That removes a large and dangerous maintenance surface.

It does not outsource the application’s policy.

A provider cannot decide whether two identities should become one customer account, how an administrator should recover access, which actions require fresh proof, how tenants are isolated, or what an agent may do on a person’s behalf. Those choices come from the product’s data model, risk, customers, and operating constraints.

The practical response is not to turn every login ticket into a six-month identity program. It is to state the boundaries of the small version while they are still cheap to see. Name what counts as an identity, which credentials are supported, what recovery promises, how sessions end, whether organizations exist, whether non-human actors are allowed, and how any delegated authority expires. Then decide what the application will deliberately postpone. When the constraints change, revisit the model rather than adding another exception to the form.

The first login can still be easy. The mistake is treating the first successful login as the whole problem. A form authenticates a moment. An identity system has to survive everything that happens next—including actors that never use the form at all.

About the author

Juan Cruz Martinez

Juan Cruz Martinez

Staff Developer Advocate

I stream, blog, and make youtube videos about tech stuff. I love coding, I love AI, and I love building stuff!View profile