Skip to main content

How AuthSec protects your MCP server

This page is the mental model. If you just want to ship, jump to Protect your first Application.

Your MCP server (or API, or AI agent) sits at some URL. AI clients — Claude Desktop, Codex, your own — want to call tools on it. You need to know:

  • Who's making this call?
  • Are they allowed to call this specific tool?
  • If not, what should the AI client do next?

AuthSec answers all three, automatically, every request.

The shape of the flow

Once your Application is registered and the SDK is mounted, every tool call looks like this:

  1. The AI client calls your tool. First call has no token — that's fine.
  2. AuthSec replies "you need to authenticate" with a pointer to where the AI client should send the user (the OAuth login page).
  3. The user logs in through whatever identity provider you've configured (your own login, Google, GitHub, SAML — set under Identity Providers).
  4. The user sees a consent screen listing what the AI client is asking for, in plain English. They approve.
  5. The AI client retries the tool call with a token. The SDK validates it, checks whether the requested tool is allowed for that user's scopes, and either runs the tool or returns a structured denial.

That's it. Steps 1–4 happen once per user per AI client. Step 5 happens every request.

What the SDK actually checks

When a tool call lands with a bearer token, the wrapper does five checks. The first one that fails returns a denial — with a code the AI client knows how to act on.

#CheckFailure → denial codeWhat the AI client does
1Token signature + expiryinvalid_tokenRe-authenticate the user
2Token matches your Application (audience)invalid_audienceRe-authenticate against the right server
3User's scopes include what this tool requiresscope_insufficientAsk the user to re-consent for more scope
4Token isn't revoked (live introspection check)token_revokedRe-authenticate
5Tool-specific policy (MFA, IP, time, etc.)step_up_required / policy_deniedTrigger step-up MFA, or report blocked

The full list of denial codes is in the Denial taxonomy reference page.

What you configure

You don't write any of the above. What you do configure, in the admin UI:

  • The Application's protected path — which URL prefix the SDK should guard.
  • Scopes — the named permissions your Application offers (e.g. repo.read, repo.write for a GitHub MCP).
  • Tool manifest — which tools require which scopes. Published by the SDK; reviewed in the UI before launch.
  • Roles and bindings — which users get which scopes, under what conditions.
  • Identity providers — where end users log in (your IdP, Google, GitHub, SAML).

All of these surface as a guided checklist on the Application detail page: Protection not verifiedNeeds reviewLive.

Why bother with OAuth at all?

OAuth 2.1 is the protocol AI clients already speak. Claude Desktop, Codex, and every other MCP-aware client know how to do the login flow described above without you teaching them. By exposing standard OAuth endpoints, your MCP server works with everything in the ecosystem, instead of needing a custom auth scheme per client.

AuthSec implements the OAuth machinery — authorization server, JWKS endpoint, introspection, RFC 9728 protected-resource metadata, consent screens — so you don't write or operate any of it. You think in Applications, scopes, and tools; AuthSec speaks OAuth on the wire.

Where things commonly go wrong

In rough order of frequency:

  • Wrong Resource URI in the SDK config. The token's aud claim must match what your SDK validates. The admin UI shows the canonical Resource URI on the Application detail page — copy it from there.
  • Scope on the token doesn't match what the tool requires. Open the Application's Tools tab to see each tool's required scope. Compare to the granted scopes in the user's consent.
  • Token validation always passes. You skipped the SDK and rolled your own. Send Authorization: Bearer garbage — if you get 200, your middleware isn't running.
  • tools/list returns tools the user can't call. The SDK filters this automatically; if you skipped the SDK, you have to filter manually.

See Troubleshoot OAuth tokens for the four-claim debug checklist.

When you need more

The standard flow above handles 90% of cases. AuthSec also supports:

  • Step-up MFA — high-risk tools that require fresh MFA, per-call.
  • Conditions — bindings that only apply from specific IPs, repos, or times.
  • Quotas — per-user or per-plan rate limits, enforced at the policy layer.
  • Token exchange — chaining MCP servers (agent calls server A, server A calls server B with a downscoped token).
  • Dynamic Client Registration — letting any AI client register without an admin step.

These ship in later phases. Track Phase E in the roadmap for ETA.