Miten MCP-palvelin kutsuu APIasi käyttäjien puolesta: tuotantotason tunnusstrategia
Selittää MCP-palvelinten ulosmenevän tunnusstrategian: miksi tunnuksen läpivienti ja M2M epäonnistuvat sekä miten tunnuksen vaihto pitää käyttöoikeudet linjassa käyttäjien kanssa.
Miten MCP-palvelin kutsuu APIasi käyttäjien puolesta: tuotantotason tunnusstrategia#
Edellisessä artikkelissamme jaoimme yleiskokemuksiamme Logto-remote MCP-palvelimen rakentamisesta. Tässä artikkelissa käydään yksityiskohtaisesti läpi arkkitehtuurin suunnittelu ja OAuth-virtaus.
MCP-palvelimen toimiessa rajapintana etä-MCP-palvelimen todennuksessa on kaksi jalkaa: sisääntuleva ja ulosmenevä.
Sisääntuleva: MCP-asiakasohjelma (VS Code, Cursor, jne.) kirjautuu sisään OAuthin kautta, saa käyttöoikeustunnuksen ja käyttää sitä päästäkseen MCP-palvelimelle
Ulosmenevä: kun käsitellään työkalukutsuja, MCP-palvelin pyytää oman liiketoiminta-API:si käyttäjän puolesta
Sisääntuleva osuus on hyvin määritelty MCP-spesifikaatiossa ja siitä on runsaasti keskustelua ja toteutuksia yhteisössä. Kirjoitimme myös aiemmin toteutusoppaan. Ulosmenevään osaan kiinnitetään huomattavasti vähemmän huomiota: MCP-palvelimella on vain tunnus MCP-palvelimen käyttöön. Miten se voi kutsua omaa liiketoiminta-API:a käyttäjän puolesta?
Tätä kysymystä pohdimme jatkuvasti rakentaessamme Logto MCP-palvelinta. Logto Cloud on tyypillinen B2B-monivuokralaistuote: käyttäjä voi kuulua useisiin vuokralaisiin ja käyttöoikeudet määräytyvät käyttäjän roolin mukaan kussakin vuokralaisessa. Älykkään agentin on paitsi toimittava käyttäjänä, myös osattava sijoittua oikeaan vuokralaiseen.
Tämä artikkeli seuraa todellista päätöksentekoprosessiamme:
Miksi MCP-palvelin pitäisi ottaa käyttöön itsenäisesti omana suojattuna resurssinaan
Kaksi ulosmenevää lähestymistapaa, jotka hylkäsimme (tunnuksen läpivienti ja M2M-tunnus) ja niiden ongelmat
Lopullinen ratkaisu: tunnuksen vaihto ja subject token, mukaan lukien miten organisaatiotunnukset hallitsevat monivuokralaisuutta
Muutama periaate, joita noudattaa rakentaessasi jotain vastaavaa
OAuthin näkökulmasta etä-MCP-palvelin näyttelee kahta roolia samanaikaisesti:
MCP-asiakasohjelmalle se on resurssipalvelin: asiakkaalla täytyy olla tunnus päästäkseen siihen
Liiketoiminta-API:lle se on asiakas: se tuo oman tunnuksen päästäkseen toisen resurssiin
Toisin sanoen, MCP-palvelin näyttelee eri roolia molemmilla puolilla ja kummallakin puolella käytetään eri tunnusta. MCP-asiakasohjelman OAuthilla hakema tunnus on tarkoitettu MCP-palvelimelle eikä kelpaa liiketoiminta-API:ssa, joka tarkistaa tunnuksen kohteen/audiencen.
Ulosmenevä vaihe on siis pohjimmiltaan valtuutuksen delegointia: miten MCP-palvelin voi kutsua taustapalveluita käyttäjän nimissä ja käyttöoikeuksilla, ilman käyttäjän tunnisteita?
Arkkitehtuuriratkaisu: MCP-palvelin itsenäisenä palveluna#
MCP-päätepisteen rakentaminen liiketoiminta-API-palvelun sisään, jaettu prosessi ja yhteinen todennus, vaikuttaa suoraviivaisimmalta. Arvioituamme vaihtoehdot valitsimme itsenäisen käyttöönoton:
Riskien erottelu: päätöksenteon hetkellä virallista MCP-SDK:ta ei voitu pitää tuotantokelpoisena ja protokollakin kehittyi nopeasti (yksi esimerkki on siirtymä SSE:stä Streamable HTTP:hen). Logto on IAM-palvelu, ja kirjautumisen saatavuus on kriittistä. Itsestään seisova käyttöönotto rajaa riskin, jos MCP-palvelin menee alas – vain tekoälyn reitti lakkaa toimimasta, pääpalvelu jatkaa normaalisti.
Itsenäinen kehitys: MCP-ekosysteemi päivittyy tiuhaan, ja yhteensopivuusongelmiin on reagoitava nopeasti, kun taas ydinpalvelulla on tiukka julkaisuprosessi ja regressiotestaus. Eri käyttöönotot suojaavat molempia hidastumiselta.
Ajonaikainen vapaus: itsenäinen palvelu voi valita parhaan ajoympäristön. Logto MCP-palvelin toimii Cloudflare Workers -ympäristössä: stateless, skaalautuu pyyntökohtaisesti, lähes nolla ylläpitoa. Sisäänrakennettu vaihtoehto ei tätä salli.
MCP-palvelin on otettu käyttöön omalla domainillaan mcp.logto.io ilman mitään piilotettua yhteyttä pääpalveluun. Jos haluamme avata lähdekoodin joskus, mikään ei estä.
Sisäänrakennetussa vaihtoehdossa tunnusongelmaa ei vältetä: MCP-päätepiste ja liiketoiminta-API jakaisivat resurssitunnisteen, joten MCP-asiakasohjelma saisi tunnuksen, jolla on täydet API-oikeudet. Kysymys "kenen oikeuksilla tämä kutsu ajetaan" siirtyy palvelujen välisestä tunnuksen vaihdosta prosessinsisäiseen käyttöoikeuksien siirtoon, ja ongelma pysyy samana. Itsestään seisova toteutus pakottaa rajaamaan käyttöoikeudet eksplisiittisesti, josta loppu artikkelissa kertoo.
MCP-palvelimella täytyy olla oma resurssitunniste#
Ulosmenevä keskustelu alkaa perustavanlaatuisemmasta kysymyksestä: mikä pitäisi olla MCP-asiakasohjelman tunnuksen audience?
Liiketoiminta-API:n resurssitunnisteen käyttö vaikuttaa suorimmalta ratkaisulta: Logton Management API on jo standardin mukainen OAuth-suojattu resurssi, joten MCP-asiakasohjelma voisi pyytää sen tunnusta suoraan ja MCP-palvelin vain välittäisi sen edelleen. Monet MCP-palvelimen varhaiset toteutukset tekivät juuri näin.
Tämän hinta: jos MCP-tunnuksen audience on liiketoiminta-API, käyttöoikeusrajapinta häviää.
Huolellisesti suunnitellut MCP-työkalut muuttuvat kosmeettisiksi: tunnuksella pääsee koko API:in työkalujen ohi
MCP-tapauksiin liittyvät auditoinnit, rajoitukset ja omat käyttöoikeudet jäävät ilman perustaa
Ensimmäinen johtopäätös: MCP-palvelin on oma suojattu resurssi, omalla resurssitunnisteellaan (https://mcp.logto.io) ja omalla scopellaan.
Tämä tekee käyttöoikeusrajasta selkeän ja konkretisoi ulosmenevän kysymyksen: tunnuksella pääsee vain MCP-palvelimelle – mitä MCP-palvelin käyttää kutsuessaan API:a?
Ensimmäinen idea nousi luonnollisesta analogiasta.
Logto Console on SPA. Se kommunikoi Management API:n kanssa yksinkertaisesti: käyttäjä kirjautuu OAuthilla selaimessa, saa tunnuksen jonka audience on Management API, ja frontend kutsuu API:a tunnuksella suoraan.
Voiko MCP-palvelin toimia toisena Consolena? MCP-asiakasohjelma hakisi liiketoiminta-API:n tunnuksen sisäänkirjautuessaan ja MCP-palvelin välittäisi sen sellaisenaan:
Tämän lähestymistavan etu on yksinkertaisuus: MCP-palvelin vain välittää tunnukset. Mutta siinä on ilmiselviä ongelmia:
Se on ristiriidassa aiemmin määritellyn käyttöoikeusrajan kanssa. Tunnuksen läpivienti vaatii MCP-asiakasohjelman hallitsemaan liiketoiminta-API:n tunnusta – juuri sen, mitä halusimme välttää.
Toiseksi, MCP-palvelin ei ole enää oikea suojattu resurssi. Sen vastaanottaman tunnuksen audience ei ole palvelin itse, joten audience-tarkistus muuttuu pelkkään allekirjoituksen ja myöntäjän tarkistukseen. Tämä ei ole spesifikaation mukaista (MCP-palvelimen tulisi toimia resurssipalvelimena ja määritellä itsensä RFC 9728 Protected Resource Metadata -määrityksen mukaan). Käytännössä backend esiintyy yksisivuisena sovelluksena.
Kolmanneksi, MCP-asiakasohjelmat eivät tue tätä. MCP-yhteensopiva asiakasohjelma pyytää tunnusta MCP-palvelimen resurssille. Ei ole standardia tapaa pyytää toisen API:n tunnusta, joten asiakaspuolella tämä ei toimi.
Jos käyttäjän tunnus ei toimi, mitä jos käytetään MCP-palvelimen omaa identiteettiä?
Määritä MCP-palvelimelle M2M-sovellus (machine-to-machine), hae tunnus asiakastunnuksilla ja kutsu liiketoiminta-API:a sillä. Tätä käytetään usein palvelujen välisessä punktioinnissa.
Sisääntuleva todennus toimii nyt: MCP-asiakasohjelman tunnuksessa audience on MCP-palvelin, MCP-palvelin tarkistaa sen normaalisti ja käyttää sitten omaa M2M-tunnusta.
Tämän ratkaiseva ongelma on, että M2M-tunnuksen käyttöoikeudet eivät liity mitenkään käyttäjän oikeuksiin:
Käyttöoikeusylitys: M2M-tunnuksen oikeudet kertovat "mitä MCP-palvelin voi tehdä", eivät "mitä tämä käyttäjä voi tehdä". Lukuoikeuden omaava käyttäjä voi poistaa sovelluksia MCP:n kautta, koska M2M-tunnuksessa on nuo oikeudet
Identiteetin katoaminen: downstream API näkee aina M2M-sovelluksen kutsujana, eikä audit-lokeista voi jäljittää käyttäjäksi
Sekava välittäjä: MCP-palvelimesta tulee korkeaoikeuksinen välikäsi, ja kuka tahansa, joka saa sen tekemään pyynnön, hyödyntää sen oikeuksia
M2M sopii käyttötarkoituksiin ilman käyttäjän kontekstia, kuten ajastetut ajot ja järjestelmien synkronoinnit. MCP-palvelin on erilainen: jokaisen kutsun aloittaa tietty käyttäjä ja tunnus pitäisi rajata tämän käyttäjän identiteettiin ja oikeuksiin.
Lopullinen ratkaisu: tunnuksen vaihto + subject token#
Kun yhdistetään edellisten lähestymistapojen opit, syntyy oikean ratkaisun vaatimukset:
MCP-asiakasohjelman tunnuksella pääsee vain MCP-palvelimeen (oppi vaihtoehdosta 1)
Ulosmenevissä pyynnöissä MCP-palvelimen täytyy toimia käyttäjänä – rajatusti tämän oikeuksilla (oppi vaihtoehdosta 2)
Tähän viittaa vakiintunut mekanismi: tunnuksen vaihto (RFC 8693). MCP-palvelin ottaa käyttäjää kuvaavan todisteen ja vaihtaa sen todennuspalvelimella downstream-API:n tunnukseen, jolloin identiteetti ja oikeudet säilyvät.
Logtossa tämä "käyttäjää edustava todiste" saadaan käyttäjän impersonointi -ominaisuudella: subject token. Se on lyhytikäinen todiste, jonka palvelin pyytää tietylle käyttäjälle: "seuraava tunnuksen vaihto suoritetaan tämän käyttäjän puolesta". Käyttäjän ei tarvitse tehdä mitään; koko flow on automatisoitu. Subject token on lyhytikäinen ja kertakäyttöinen sekä vanhentuu käytön jälkeen.
Arkkitehtuurissa on neljä roolia. MCP-palvelin on otettu käyttöön itsenäisesti osoitteessa mcp.logto.io:
Yhden työkalukutsun koko tunnusvirtaus:
Askel askeleelta:
① Sisääntulon tarkistus. MCP-asiakasohjelma kutsuu työkalua käyttäjätunnuksella. Tunnuksen audience on MCP-palvelimen oma resurssitunniste ja scope mcp:all. MCP-palvelin tarkistaa allekirjoituksen, myöntäjän, audience:n ja scope:n ja poimii käyttäjän identiteetin. Sisääntulo päättyy tähän. Tätä tunnusta ei koskaan välitetä downstream.
② Palvelun identiteetti. MCP-palvelin käyttää omia M2M-tietojaan hakeakseen tunnuksen erityisellä scopella, access:mcp:api. Tällä scopella on vain yksi tarkoitus: seuraavan vaiheen oman päätepisteen kutsuminen.
③ Subject tokenin pyytäminen on koko ketjun avainvaihe. MCP-palvelin kutsuu POST /api/mcp/subject-tokens, päätepistettä jonka Cloud avaa nimenomaan MCP:lle ja esittää kaksi tunnusta samanaikaisesti:
Authorization-otsikko: M2M-tunnus, todistaa "olen virallinen MCP-palvelin"
x-mcp-user-token-otsikko: käyttäjätunnus, todistaa "tämä käyttäjä on valtuuttanut minut, eikä valtuutus ole vanhentunut"
Cloud tarkistaa käyttäjätunnuksen täysin: allekirjoitus, myöntäjä, voimassaoloaika, audience täytyy olla MCP-palvelimen resurssitunniste ja scopessa pitää olla mcp:all. Tämän varmistuksen jälkeen userId otetaan suoraan tunnuksen sub-claimista. Päätepisteessä ei ole parametria käyttäjän valintaan.
Näin M2M-tunnusta ei voi väärinkäyttää. Jos päätepiste ottaisi käyttäjäid-parametrin, kuka tahansa M2M-tunnuksen haltija voisi esiintyä kenä tahansa käyttäjänä. Tällä suunnittelulla MCP-palvelin voi vaihtaa tunnuksia vain presentoidun voimassa olevan käyttäjätunnuksen perusteella.
Subject token myönnetään lyhytikäisenä ja kertakäyttöisenä. Toteutus ei koskaan tallenna sitä, vaan hakee uuden jokaiseen käyttöön.
④ Työtunnusten vaihto. Subject tokenilla tehdään vakiomuotoinen tunnuksen vaihto ja saadaan kahdentyyppisiä tunnuksia tarpeen mukaan:
Cloud API-tunnus: käyttäjätason operaatioihin käyttäjänä, esim. vuokralaisten listaus ja luonti
Organisaatiotunnus: rajattu tiettyyn vuokralaiseen (jokainen Logto Cloud -vuokralainen vastaa organisaatiota). Tunnus myönnetään käyttäjänä ja sen oikeudet ovat täsmälleen käyttäjän rooli kyseisessä vuokralaisessa
⑤ Ulosmenevä kutsu. Kutsu liiketoiminta-API:a vaihdetulla tunnuksella ja palauta tulos MCP-asiakasohjelmalle.
Monivuokralaisuus ratkaistaan vaihdon yhteydessä: vuokralainen määritellään vaihdossa, ei yhteyden luonnissa. list_tenants listaa vaihtoehdot Cloud API -tunnuksella, käyttäjä valitsee jonkin keskustelussa ja MCP-palvelin vaihtaa organisaatiotunnuksen valitulle vuokralaiselle. Yksi päätepiste palvelee kaikkia vuokralaisia; ei tarvita erillisiä käyttöönottoja, ja keskustelun aikana luotu vuokralainen on heti käytettävissä.
Tarkista edellisten mallien ongelmat – jokainen katetaan tässä:
Käyttäjätunnuksen blast radius on rajattu (oppi lähestymistapa 1): audience on vain MCP-palvelin. Vuotaneenakin sillä pääsee vain niihin määriteltyihin työkaluihin
M2M-tunnusta ei voi väärinkäyttää (oppi lähestymistapa 2): se ei enää kutsu liiketoiminta-API:a suoraan vaan osoittaa vain palvelun identiteetin. Subject tokenin myöntäminen vaatii käyttäjän voimassa olevan tunnuksen yhtä aikaa, joten MCP-palvelin voi vaihtaa tunnuksia vain käyttäjille, jotka ovat sen valtuuttaneet. Sekava välittäjä -ongelma on poissa
Ei käyttäjän tunnusten tallentamista: subject tokenit pyydetään hetkellisesti ja hylätään saman tien. MCP-palvelin säilyttää vain oman M2M-tunnuksensa
Revokointi toimii: kun käyttäjä peruuttaa MCP-valtuutuksen, käyttäjätunnus muuttuu kelvottomaksi, x-mcp-user-token tarkastus epäonnistuu ja ketju katkeaa samantien
Oikeudet vastaavat käyttäjää: vaihdetut tunnukset myönnetään käyttäjän puolesta. Lukuoikeudellinen käyttäjä pysyy vain lukuoikeuksissa MCP:nkin kautta ja oikeuksien nosto epäonnistuu jo todennuspalvelimella. Audit-lokit näyttävät todellisen käyttäjän
Jälkikäteen katsottuna M2M-tunnuksella on nyt oikea tehtävä: se osoittaa "kuka olen", kun taas oikeus "toimia käyttäjänä" pitää vaihtaa lennossa käyttäjän voimassa olevan valtuutuksen kanssa.
Katsottaessa koko ketjua, etä-MCP-palvelimen tunnusstrategia tiivistyy muutamaan kohtaan:
Sisään- ja ulosmenevät todennukset ovat erillisiä, ja MCP-tunnuksen audience täytyy olla nimenomaan MCP-palvelin
Ulosmenevä ratkaistaan tunnuksen vaihdolla: jos todennuspalvelimesi tukee sisääntulevan tunnuksen vaihtoa suoraan, pelkkä token exchange riittää; jos ei (esim. Logtossa token exchange vaatii subject tokenin), käytä impersonointiominaisuutta vaihdon käynnistämiseen palvelimen puolelta
Monivuokralaisuus ei muuta mekanismia. Organisaatiokonteksti on vain parametri vaihdossa, yksivuokralaistuotteet ohittavat sen täysin
Tekoäly toimii käyttäjän puolesta, joten downstream-tunnuksen oikeudet täytyy rajata kyseiseen käyttäjään
Yksinkertainen testi: mitä jos MCP-asiakasohjelman tunnus vuotaa? Hyökkääjän pitäisi päästä vain niihin määriteltyihin MCP-työkaluihin, edelleen käyttäjän oikeuksilla. Jos täysi API on käytettävissä suoraan, käyttöoikeusraja on rikottu.
MCP-ekosysteemi kehittyy edelleen nopeasti. Sisääntulon todennus on hyvin määritelty spesifikaatiossa, mutta "miten MCP-palvelin kutsuu downstream-palveluja" on vielä tiimikohtainen ratkaisu. Toivomme, että käytäntömme toimivat hyödyllisenä viitepisteenä.