Autentiseringsmønstre for MCP: OAuth, tokens og når du bruker hva
MCP definerer en OAuth-autorisasjonsprofil for HTTP-transporter. Offentlige servere med bare lesing kan være anonyme. Beskyttede verktøy trenger autentisering, autorisasjon og en verifisert principal. Egne partnertokens trenger også en eksplisitt kompatibilitetsavtale med MCP-klienten.
Artikkelen hører til pilarsiden om utvikling av MCP-servere.
TL;DR
- Skrivebeskyttet tilgang til offentlige data med rate limiting er det eneste legitime tilfellet for anonym tilgang.
- Scoped API-tokens med hashing og kort TTL dekker B2B og headless.
- OAuth 2.1 med PKCE dekker forbrukerassistenter som handler på vegne av en innlogget bruker.
- Rate limiting knyttes til principal; verktøy som endrer tilstand, får en smalere bucket.
- Hver autentiseringshendelse logges: utstedt, brukt, tilbakekalt, avvist.
Slik velger du autentiseringsmetode for MCP
Før jeg velger et autentiseringsmønster, går jeg gjennom de samme fem spørsmålene:
- Endrer noe verktøy tilstand? Hvis ja, er anonym tilgang utelukket.
- Handler agenten på vegne av en bestemt menneskelig bruker? Hvis ja, OAuth.
- Handler agenten som en B2B-integrasjon uten menneskelig bruker? Hvis ja, scoped API-token.
- Er dataflaten tilgjengelig fra det offentlige Internett? Hvis ja, er rate limiting obligatorisk.
- Blandes verktøy som endrer tilstand og skrivebeskyttede verktøy i samme server? Hvis ja, autentiseringsscope per verktøy, ikke per server.
Treet gir tre mønstre:
| Mønster | Når det brukes | Implementering |
|---|---|---|
| Anonym + rate limit per IP | Offentlig katalog, skrivebeskyttet, begrenset belastning | Workeren sjekker bare IP-bucketen |
| Scoped API-token | B2B-integrasjon, headless agentkjøring, ingen menneskelig bruker | Tilfeldig opaque token, hashet lagring, utløp og rotasjon |
| OAuth 2.1 + PKCE | Forbrukeragent for en innlogget bruker | Standard authorization code flow |
Mønstrene utelukker ikke hverandre. En ekte produksjonsserver kjører som regel alle tre, og hvert verktøy er merket med scopet det krever.
Anonym, skrivebeskyttet MCP-tilgang med rate limiting
Eksponer bare godkjente offentlige katalogfelt. WooCommerce-administrasjons-API-et wc/v3 trenger legitimasjon på serversiden og er ikke en anonym offentlig kilde. Bruk et vurdert offentlig endepunkt eller en adapter som utelukker private felt.
Implementering:
async function checkAnonymousRateLimit(request: Request, env: Env): Promise<boolean> {
const ip = request.headers.get("CF-Connecting-IP") ?? "unknown";
const { success } = await env.AUTH_RATE_LIMIT.limit({ key: `anonymous:${ip}` });
return success;
}60 forespørsler per minutt per IP er standardverdien min. En teller basert på KV er omtrentlig (KV-skriving er eventually consistent); for strenge grenser er Durable Objects eller Cloudflares innebygde Rate Limiting binding riktig verktøy.
Hva mønsteret ikke dekker: verktøy som returnerer brukerspesifikke data, verktøy som endrer tilstand, eller verktøy som avslører lagerstatus for ikke-offentlige produkter. De krever en ekte principal.
API-tokens med scopes for B2B-integrasjoner med MCP
B2B-tilfellet: en partnerintegrasjon leverer en agent som kaller MCP-serveren din på vegne av partnerens organisasjon, ikke på vegne av en bestemt menneskelig bruker. Eksempler er en agent for lagersynkronisering hos en grossist, en markedsplassintegrasjon hos en aggregator, eller en analyseagent som rapporterer ordretrender til BI.
Flyten:
- En administrator i WordPress-backend oppretter et token med navn, et sett scopes (
catalogue:read,inventory:read,orders:write) og en utløpstid (standard 90 dager). - Tokenet vises for administratoren én gang og lagres deretter som SHA-256-hash pluss scope-sett pluss utløpstid.
- Partneren konfigurerer MCP-klienten sin med tokenet i headeren
Authorization: Bearer <token>. - Workeren hasher det innkommende tokenet og slår opp hashen i KV. Hvis hashen stemmer, utløpstiden ligger i fremtiden og verktøyets påkrevde scope finnes i tokenets sett, går kallet videre.
async function verifyApiToken(authHeader: string | null, env: Env): Promise<TokenContext | null> {
if (!authHeader?.startsWith("Bearer ")) return null;
const token = authHeader.slice(7);
const hash = await sha256(token);
const record = await env.TOKENS.get(`tok:${hash}`, "json") as TokenRecord | null;
if (!record) return null;
if (record.expiresAt < Date.now()) return null;
return { tokenId: record.id, scopes: record.scopes, principal: record.principal };
}
function requireScope(ctx: TokenContext, scope: string): void {
if (!ctx.scopes.includes(scope)) throw new Error("Insufficient scope");
}To driftsvaner holder mønsteret ærlig:
Rotasjon, ikke evighet. Et token som aldri utløper, er et token som om seks måneder havner i et offentlig repo på GitHub. 90 dager som standard, med en fornyelsesflyt der gammelt og nytt token overlapper i 7 dager, er mønsteret som overlever ekte partnere.
Hashet lagring, ikke klartekst. Hvis KV-en din lekker, er hasher uten det opprinnelige tokenet ubrukelige. Hvis du lagret tokens i klartekst, må hver partnerintegrasjon roteres umiddelbart. Kostnadsforskjellen ved utstedelse er ett sha256-kall.
OAuth 2.1 med PKCE i en MCP-server
Forbrukertilfellet: brukeren åpner Claude Desktop, kobler kontoen i butikken din via OAuth og ber agenten “vis min siste ordre”. Agenten må nå kalle MCP-serveren din med legitimasjon som sier “jeg handler for bruker 4231”.
OAuth 2.1 (draft-ietf-oauth-v2-1) er den konsoliderte profilen. PKCE (RFC 7636) er obligatorisk for offentlige klienter (her hører skrivebordsassistenter uten en konfidensiell serverdel hjemme).
Flyten i fem trinn:
- MCP-verten åpner nettleseren på autorisasjonsendepunktet ditt med
response_type=code,code_challenge=<S256-hash av verifieren>og de ønskede scopene. - Brukeren logger inn på WordPress-nettstedet ditt (eller hos autentiseringsleverandøren din) og godtar scopene.
- Autorisasjonsendepunktet ditt omdirigerer verten med en engangs autorisasjonskode.
- Verten bytter koden pluss den opprinnelige
code_verifierpå tokenendepunktet ditt mot et access token (kort TTL, 1 time) og et refresh token (lengre TTL, 30 dager). - Verten kaller MCP-serveren med
Authorization: Bearer <access_token>. Workeren verifiserer tokenets signatur, utløpstid og scope mot verktøyet som kalles.
Et OAuth-token kan være opaque eller JWT. Eksemplet bruker en konfigurert utsteder og det vedlikeholdte jose-biblioteket til å validere signatur og claims:
import { createRemoteJWKSet, jwtVerify } from "jose";
const issuer = "https://identity.example.org";
const audience = "https://mcp.example.org/mcp";
const jwks = createRemoteJWKSet(new URL(issuer + "/.well-known/jwks.json"));
async function verifyJwt(token: string) {
const { payload } = await jwtVerify(token, jwks, {
issuer,
audience,
algorithms: ["RS256"],
requiredClaims: ["sub", "exp"],
});
if (typeof payload.sub !== "string" || typeof payload.scope !== "string") {
throw new Error("Invalid identity or scope claims");
}
return { subject: payload.sub, scopes: payload.scope.split(" ").filter(Boolean) };
}Scopene i JWT-en speiler scopene fra scoped token-mønsteret: catalogue:read, orders:read, orders:write. WordPress-brukerens ID ligger i claimet sub, så et orders:read-kall returnerer bare ordrene til denne brukeren.
Slik kombinerer du OAuth, tokens og anonym tilgang i én MCP-server
En ekte MCP-server for WooCommerce eksponerer som regel:
catalogue.listogproduct.detail: anonym + rate limit per IP.inventory.check(for partnere): scoped token medinventory:read.order.status(for innlogget bruker): OAuth medorders:read.order.intent(for innlogget bruker): OAuth medorders:write, pluss smalere rate limit.
Pre-dispatch-logikken i Workeren går gjennom mønstrene:
Autentiser HTTP før MCP-dispatch. Kontroller deretter verktøyets scopes og eierskap til ressursen. Avvis ukjente verktøy og manglende policy. Autentiseringsfeil trenger HTTP bearer-challenges fremfor oppdiktede JSON-RPC-feilkoder som tekst.
Mappingen TOOL_AUTH_REQUIREMENTS er den eneste sannhetskilden for hvilket verktøy som trenger hvilken autentiseringsmodus. Ingen verktøy legges til uten en eksplisitt oppføring.
MCP-forespørselsgrenser per IP, token og bruker
Anonym trafikk får en bucket per IP. Tokentrafikk får en bucket per token. OAuth-trafikk får en bucket per bruker. Verktøy som endrer tilstand, får et lavere tak uansett principal.
Tallene nedenfor er konfigurasjonseksempler, ikke målinger eller produksjonsstandarder. Fastsett reelle grenser fra kapasiteten ved opprinnelsen og observert trafikk.
| Verktøykategori | Anonym | Token | OAuth |
|---|---|---|---|
catalogue.* (lesing) | 60 / minutt / IP | 600 / minutt / token | 120 / minutt / bruker |
inventory.* (lesing) | ikke tillatt | 300 / minutt / token | ikke tillatt |
order.status (lesing) | ikke tillatt | 60 / minutt / token | 60 / minutt / bruker |
order.intent (skriving) | ikke tillatt | 30 / minutt / token | 10 / minutt / bruker |
Tallene er et utgangspunkt; de riktige verdiene kommer fra å observere ekte trafikk i to uker og justere. Det er strukturen som teller.
Hvilke MCP-autentiseringshendelser du bør logge
Hver hendelse som er relevant for autentisering, havner i loggen:
- Token utstedt. Administrator, målprincipal, scopes, utløpstid.
- Token brukt. Token-ID, verktøynavn, principal, forsinkelse, suksess/feil.
- Token tilbakekalt. Token-ID, hvem som tilbakekalte, hvorfor.
- Token avvist. Årsak (utløpt, manglende scope, hash stemmer ikke), IP, user agent.
- OAuth-kodeutveksling. Bruker-ID, tildelte scopes, utstedt refresh token.
- OAuth-fornyelse. Bruker-ID, nytt access token, gammelt token erstattet.
Loggene sendes via Cloudflare Logpush til langtidslagring. En dashbordspørring som sporer “tokens brukt de siste 24 timene som ikke var brukt de foregående 90 dagene”, fanger sannsynlig tokentyveri. En spørring på “mislykkede tokenverifiseringer per IP” fanger forsøk på credential stuffing.
Discovery og identiteten til den beskyttede ressursen
MCP-spesifikasjonen for autorisasjon fra 2025-11-25 definerer en OAuth-flyt for HTTP-transporter. Autorisasjon er valgfritt, men en beskyttet HTTP-server som skal fungere med ulike verter trenger discovery og validering fra denne profilen. Stdio har en annen driftsgrense og henter legitimasjon fra miljøet. Egne partnertokens kan fungere i en kontrollert integrasjon. Ikke anta at en vilkårlig MCP-vert kan oppdage eller skaffe slike tokens. Test den konkrete verten og transporten.
Skill rollen som MCP-ressursserver fra rollen som autorisasjonsserver, selv når begge kjører i samme applikasjon. Ressursserveren utfører verktøy og kontrollerer adgang. Autorisasjonsserveren håndterer innlogging, samtykke og utstedelse av tokens. Publiser metadata for den beskyttede ressursen med dens kanoniske identitet og autorisasjonsservere. Et HTTP 401-svar kan vise til metadata gjennom WWW-Authenticate. Adressene må fungere bak reverse proxy og med et eventuelt stiforfiks. At nettleseren viser en innloggingsside beviser ikke at MCP-verten fant riktig utsteder.
Klienten ber om et access token for MCP-ressursen med resource-parameteren. Serveren kontrollerer at tokenet er utstedt for denne ressursen. Et token beregnet på et annet API er ikke gyldig her bare fordi en kjent utsteder har signert det. Avvis feil audience og issuer før et verktøy kjøres. Bruk samme kanoniske ressurs-URI i metadata, autorisasjonsforespørsel og validering. Ikke la forventet audience bestemmes av en upålitelig Host-header eller en parameter fra klienten.
Full tokenvalidering og legitimasjon mot andre tjenester
OAuth access tokens kan være opaque eller JWT. Protokollen krever ikke at alle utstedere bruker JWT. Et opaque token trenger verifikasjonsmetoden utstederen støtter. En JWT-verifikator kontrollerer signatur, tillatt algoritme, issuer, audience og tidskrav. Deretter valideres applikasjonsfeltene som faktisk brukes. En TypeScript-typeassertion gjør ingen runtime-kontroll. Ugyldig JSON, manglende subject eller scope med feil datatype må føre til kontrollert avvisning. Bruk et vedlikeholdt bibliotek og en konfigurert tillitskilde fremfor en delvis Web Crypto-verifikator.
Hent signeringsnøkler fra utstederens konfigurerte JWKS-adresse, ikke fra en vilkårlig URL inne i tokenet. Planlegg for nøkkelrotasjon og utilgjengelig utsteder. En feil ved nøkkelhenting skal ikke slippe gjennom et ukontrollert token. En tidligere cachet og betrodd nøkkel kan brukes innenfor den dokumenterte policyen, men en ukjent nøkkel krever fortsatt en klar beslutning. Test utløpte tokens, tokens som ikke er gyldige ennå, endret algoritme og tokens for et annet miljø. Staging-legitimasjon skal ikke virke i produksjon ved et uhell.
MCP-veiledningen om sikkerhet forbyr token passthrough. Et bearer-token adressert til MCP-serveren må ikke videresendes som WooCommerce- eller ERP-legitimasjon. Hold tjenestenes egne nøkler på serversiden og autoriser handlingen før de brukes. Dersom en nedstrømstjeneste trenger delegert identitet, bruk dens støttede delegasjon eller token exchange. Å kopiere den innkommende Authorization-headeren er ikke et delegasjonsdesign.
Scopes og eierskap til bestillinger
Autentiser HTTP-forespørselen og håndhev deretter scopene for operasjonen som skal kjøres. En vellykket tokenkontroll må ikke hoppe over verktøyets adgangskontroll. Verktøyregisteret skal ha rettighetskrav for hver operasjon. Ukjente oppføringer avvises. Endringer i registeret trenger tester for både tillatte og nektede kall. Discovery-listen trenger også en policy for sensitive beskrivelser og parametre. Kjennskap til et verktøynavn gir ingen rett til å kjøre det.
orders:read angir en kategori handlinger, ikke hvilken kundes bestillinger som er tilgjengelige. Koble verifisert subject til en intern konto gjennom en betrodd mapping, og kontroller eierskap når ordren leses. En kunde-ID sendt av agenten er ikke bevis for rettigheter. Partnere som får tilgang til hele organisasjonen trenger en separat tildeling og en definert tenant-grense. En norsk lagerpartner som oppdaterer beholdning og en kunde som sjekker levering har forskjellige principals selv om de bruker samme MCP-server.
Håndter feil i bearer-autentisering på riktig HTTP-lag. Manglende eller ugyldig token gir avslag på autentisering. Manglende scopes krever en relevant scope-challenge. Et utløpt token skal ikke vises som et verktøyresultat om tomt lager. Ved å skille feiltypene kan verten fornye tilgang eller be om samtykke. Gjentatt kjøring av forretningsoperasjonen med uendrede credentials løser ikke et autentiseringsproblem.
Tilbakekalling, kvoter og utrullingstester
Generer opaque partnertokens med tilstrekkelig kryptografisk tilfeldighet. Hashet lagring hjelper bare når hemmeligheten er vanskelig å gjette. Skill den offentlige tokenidentifikatoren fra hemmeligheten og bruk en gjennomgått kontroll. Definer forsinkelsen ved tilbakekalling. Workers KV er eventually consistent. Sletting av en post gir ikke umiddelbar global tilbakekalling. Sensitive operasjoner kan kreve kontroll mot en autoritativ kilde eller en annen konsistensgrense. Kort gyldighet reduserer eksponering, men erstatter ikke tilbakekalling.
Rate limiting har også en konsistensmodell. Workers-bindingen for rate limiting begrenser forespørselsvolum, men er ikke et globalt transaksjonelt budsjett for ordre eller betalte operasjoner. Bruk en egnet autoritativ koordinator for forretningskvoter. En KV-lesing etterfulgt av skriving er ikke en atomisk økning og kan miste samtidige oppdateringer. Agentens retries må ikke opprette flere handlinger enn den opprinnelige operasjonen.
Test discovery fra produksjonens vertsnavn, samtykke, utløp, refresh, tilbakekalling og manglende scopes med den tiltenkte MCP-verten før utrulling. Ta med tilgang til en annen kundes bestilling og en annen tenant. Kontroller at private verktøyresultater ikke havner i delt cache. Registrer token-ID, principal, verktøy og utfall uten hemmeligheter og kundepayloads. Hold sikkerhetshendelser atskilt fra detaljerte debug-spor og fastsett lagringstiden. En vellykket innlogging er bare starten på testen av tilgangskontroll.
Relaterte temaer
Denne artikkelen handler om autentisering. Bredere herding av WordPress beskrives i veiledningen om WordPress-sikkerhet. Tjenestesiden er utvikling av MCP-servere.
Prisen er individuell, fordi autentiseringsomfanget avhenger av hvilke mønstre miljøet ditt krever; en skrivebeskyttet server i anonym modus er et annet prosjekt enn en full flate som utsteder OAuth.







