Skip to content

Native JIT Authorization for Agents via OAuth Challenge/Response and MCP Elicitation #21

@embesozzi

Description

@embesozzi

Author: @embesozzi
Status: Draft
Classification: Discussion / Feature Proposal
Date: 2026-03-19


Abstract

This proposal explores a pattern for enabling Just-In-Time (JIT) authorization in MCP agents without browser redirects, by combining:

  1. OAuth 2.0 First-Party Apps (FiPA): an IETF draft defining a challenge/response authorization protocol for applications trusted by the authorization server operator.
  2. Structured Elicitation: an agent-readable metadata format (following the MCP elicitation/create structure) that binds FiPA challenge steps directly to MCP Elicitation JSON-RPC calls.

The core idea is a binding where OAuth authorization challenges are expressed as MCP elicitation/create calls. This allows MCP clients (agents) to collect user input inline and complete multi-step authentication flows entirely within the agent runtime.

In this model, the MCP Server acts as a trusted first-party client, mediating the authorization flow with the Authorization Server, while the agent serves only as a UI surface for Human-to-Agent (H2A) interaction.


Motivation

Current MCP OAuth 2.1 flows rely on browser redirects for token acquisition. This creates limitations in native agent environments (e.g., CLI, IDE):

  1. No native JIT authorization primitive: Step-up or JIT auth forces users out to a browser, breaking CLI/IDE continuity.
  2. No agent-readable challenge metadata: FiPA defines the wire protocol but not a structured format agent runtimes can map to user prompts.
  3. No binding to MCP Elicitation: There is no defined mapping between OAuth challenge responses and elicitation/create calls.

Core Concepts

First-Party MCP Server

A First-Party MCP Server is an MCP Server that is explicitly registered as a first-party client with the Authorization Server.

  • The Authorization Server trusts the MCP Server to mediate authentication challenges.
  • The agent is not trusted and only acts as a user interaction surface.
  • The trust boundary is therefore between the MCP Server and the Authorization Server, not the agent.

This constraint is required for safely enabling inline authentication flows.


Proposed Binding

Note: The following describes the author's draft proposal (draft-embesozzi-oauth-fipa-agent-elicitation), not a standardized specification. It is presented here to illustrate the concept and invite feedback.

The binding is triggered when the MCP Server, based on its authorization policies, determines that a Just-In-Time (JIT) authorization step is required before executing a sensitive tool. At that point, the MCP Server — acting as the registered first-party FiPA client — initiates an Authorization Challenge Request to the AS on behalf of the current operation.

When an Authorization Server returns an insufficient_authorization error (per FiPA), the proposed extension adds an elicitations array to the response. Each entry maps directly to an MCP elicitation/create call:

AS Challenge Response:

{
  "error": "insufficient_authorization",
  "auth_session": "sess_abc123",
  "elicitations": [
    {
      "mode": "form",
      "message": "Enter the 6-digit code from your Authenticator App.",
      "requestedSchema": {
        "type": "object",
        "properties": {
          "otp": { "type": "string", "minLength": 6, "maxLength": 6 }
        },
        "required": ["otp"]
      }
    }
  ]
}

MCP Server issues elicitation/create to the MCP Client with the same params, collects user input, then responds to the AS:

{ "auth_session": "sess_abc123", "response": { "otp": "847291" } }

Two elicitation modes are supported: form (inline JSON Schema-driven input) and url (out-of-band browser/webview, used as fallback for third-party agents).

H2A Flow

sequenceDiagram
    participant Human
    participant Agent as MCP Client (Agent)
    participant MCP as MCP Server (First-Party FiPA Client)
    participant AS as Authorization Server

    Human->>Agent: Invokes tool request
    Agent->>MCP: tools/call
    MCP->>AS: Authorization Challenge Request
    AS-->>MCP: insufficient_authorization + auth_session + elicitations[]

    loop Each challenge step
        MCP->>Agent: elicitation/create
        Agent->>Human: Native prompt
        Human-->>Agent: Input
        Agent-->>MCP: elicitation result
        MCP->>AS: Challenge response (auth_session + response)
        AS-->>MCP: Next challenge OR authorization_code
    end

    MCP->>AS: Token Request
    AS-->>MCP: Access Token
    MCP->>MCP: Execute tool (Bearer token held by MCP Server)
    MCP-->>Agent: Tool response
    Agent-->>Human: Result
Loading

Security Considerations

  • First-party boundary: These flows MUST only be used by first-party MCP Servers. The AS MUST enforce this via client registration metadata, the first-party trust boundary is at the MCP Server, not the agent.
  • Phishing resistance: First-party MCP Servers may invoke native WebAuthn APIs.
  • H2A scope only: This pattern requires a human present to respond. It does not apply to A2A or autonomous agent scenarios.

Working Implementation

A proof-of-concept has been validated with Claude Code and GitHub Copilot CLI.

In the demo:

  • An agent attempts a protected operation
  • The MCP Server triggers a JIT authorization challenge
  • The user completes authentication inline in the CLI
  • The Authorization Server issues an updated token
  • The operation proceeds
claude-jit-authz.mp4

Open Questions

  1. Is native JIT authorization for first-party MCP servers in scope for ext-auth, or should it live in the modelcontextprotocol repo? Please let me know where this is best discussed.

  2. Extending MCP Elicitation beyond input collection:
    The current elicitation/create method is designed for collecting user-provided input, either via JSON Schema-driven forms or URL-based flows.
    This proposal raises the question of whether elicitation should also support invoking user authentication actions, not just collecting values.

Specifically, should the elicitation format be extended to include execution hints — read-only metadata that instructs the MCP client to trigger a native platform capability, instead of prompting for typed input?
Examples include:

  • Triggering a passkey / WebAuthn authentication flow
  • Invoking OS-level biometric authentication
  • Using hardware-backed credentials (e.g., security keys)

Here is an example of device-bound passkey (security key) authentication, where Claude Code triggers JIT authorization via client-side hooks.

passkeys-jit-v2.mp4

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions