MFA has become the answer to almost every authentication review. Password risk? Add MFA. Admin access? Add MFA. AI agent acting for a user? Somehow, add MFA once at the beginning and trust everything afterward. This is giving one control a job it was never designed to do.
MFA proves that more than one factor was present during an authentication event. It does not prove that the current browser is still safe, that the session was not stolen, or that the next action is authorized. It raises assurance at one point in time only.
The attack moves after login
Phishing-resistant MFA can make account takeover much harder. But attackers are adapting by stealing session cookies, abusing recovery flows, convincing users to approve malicious OAuth grants, and operating inside already authenticated devices. None of those attacks need to defeat the second factor again.
The application needs multiple controls with different jobs:
- Secure session cookies, rotation, short idle windows, and revocation reduce the value of stolen sessions.
- Authorization checks limit what the authenticated subject can do on this resource right now.
- Device, network, and behavioral signals can trigger step-up authentication when risk changes.
- Recovery and support flows must preserve the same assurance level instead of becoming a cheaper back door.
NIST SP 800-63B separates authentication assurance from session management for a reason. RFC 9470 also defines an OAuth step-up challenge so a resource can request stronger authentication for a specific action.
Step up for the action, not for the whole day
A user reading their profile and a user changing payout instructions should not consume the same trust decision forever. Represent the authentication context, then let sensitive operations require a recent or stronger method.
function canChangePayout(session: Session, now: number) {
const mfaIsRecent = now - session.mfaVerifiedAt < 5 * 60_000;
return session.authMethods.includes("webauthn") && mfaIsRecent;
}
This is not an invitation to interrupt users constantly. It is a way to spend friction where the consequence is high. Low-risk work can continue with the ordinary session. High-risk work gets a fresh decision.
AI agents make this separation more important also. A human completing MFA should not create an unlimited agent credential. The agent needs a separate, short-lived token scoped to the approved task. If the agent attempts a more sensitive tool, pause for a new authorization decision rather than stretching the original MFA event.
Defense in depth needs independent failure modes
Five controls are not useful if all five trust the same stale session flag. Each layer should reduce risk the others cannot see. The identity provider authenticates. The session layer maintains continuity. The policy engine authorizes each action. The resource validates scope and tenant. Audit and revocation limit damage when something still goes wrong.
MFA is one of the strongest controls in that chain, especially when it is phishing resistant. But making it the whole chain creates a secure front door attached to an open building.
The takeaway is simple. Use MFA to raise confidence, then keep verifying what that confidence is being used for. Authentication starts trust. Defense in depth keeps it bounded.
Akash Devdhar is a Senior Software Engineer specializing in enterprise identity, authentication, authorization, and AI infrastructure. He writes about building secure AI systems using OAuth, OIDC, RBAC, and modern identity architectures.

Top comments (0)