Hvordan gir jeg AI-agenten min en egen avgrenset API-nøkkel?
Av Antony Richard Grov, gründer av Apier
Lag en undernøkkel under en av kontonøklene dine, fra dashbordet eller med ett kall til POST /api/v1/account/keys/{id}/subkeys. En undernøkkel har et utvalg av foreldrenøkkelens scope, et obligatorisk utløp (30 dager som standard, høyst 365) og egne daglige og månedlige forbruksgrenser, og hvert betalte kall den gjør belastes foreldrenøkkelens saldo. Agenten ser aldri kontonøkkelen din. Trekk undernøkkelen tilbake, eller la den utløpe, og agenten avvises fra neste forespørsel.
Hvorfor ikke bare dele kontonøkkelen min med agenten?
Fordi en kontonøkkel er hele kontoens API-tilgang. Den har alle scopene kontoen har, når kontorutene og faktureringsrutene og kan be om påfyll, og en agent som har den kan gjøre alt det samme, enten etter planen, etter en instruks den ble matet med, eller på grunn av en feil. (Å lage, liste og trekke tilbake nøkler gjør du innlogget i dashbordet, aldri med en bærernøkkel.) En lekket kontonøkkel er en lekket konto. En undernøkkel avvises på hver kontorute, nøkkelhåndteringsrute og faktureringsrute med 403 SUBKEY_ROUTE_FORBIDDEN før noen behandler kjører. En lekket undernøkkel kan fortsatt bruke scopene den fikk, opp til grensen sin, fram til utløpet eller til du trekker den tilbake. En undernøkkel kan aldri få subscribe:webhooks eller admin:keys, så den kan ikke registrere abonnementer på webhooks. Gi en agent bare de lesescopene jobben trenger.
Grensene jobber for deg også. En konto har høyst tre aktive kontonøkler, som er én per miljø og ikke én per agent. Undernøkler står utenfor den tellingen: hver kontonøkkel kan ha opptil ti aktive undernøkler, så én nøkkel kan bære en hel flåte av agenter, hver med sitt eget navn i revisjonsloggen, sitt eget utløp og sitt eget budsjett. Hastighetsgrenser og tilbakeholdet for unike organisasjonsnumre telles på rotnøkkelen over foreldrenøkkelen og alle undernøklene, så å dele en agent opp i ti undernøkler øker aldri foreldrenøkkelens kvote og skjuler aldri et skrapemønster.
Det finnes også en regel om ett nivå. En undernøkkel kan ikke lage undernøkler, så tillitskjeden er alltid nøyaktig to ledd lang: du, og agenten du ga en nøkkel til. Det er det som holder dashbordet ærlig om hvem som kan handle: hver legitimasjon i kontoen din er enten en av de tre nøklene dine eller et barn av en av dem som du selv har laget. Flyten med utstedelsestoken for agenter som må hente sin første nøkkel selv finnes fortsatt; en undernøkkel er valget når du som eier vil bestemme scope og budsjett på forhånd.
Hva kan jeg begrense på en undernøkkel?
Tre ting, og tjeneren håndhever alle tre inne i én databasefunksjon under en lås per foreldrenøkkel, så et kappløp mellom to forsøk kan ikke snike seg forbi en regel. Scope må være et utvalg av foreldrenøkkelens. En foreldrenøkkel med read:* kan gi fra seg et hvilket som helst lesescope, en foreldrenøkkel med bare read:brreg kan gi fra seg bare det, og admin:keys utstedes aldri til en undernøkkel, uansett hva foreldrenøkkelen har. Det gjeldende scopet beregnes ved hvert kall som snittet av undernøkkelens lagrede scope og foreldrenøkkelens nåværende scope, så snevrer du inn foreldrenøkkelen senere, snevres hver undernøkkel inn ved neste forespørsel.
Utløp er obligatorisk. Utelater du expires_at, lever undernøkkelen 30 dager; oppgir du et, kan det ligge høyst 365 dager fram, beregnet i UTC-millisekunder slik at ingen tidssoneregning kan strekke det. Når tidspunktet passerer, svarer agentens neste kall 401 AUTH_SUBKEY_EXPIRED. En agent som skal leve lenger får en ny undernøkkel, ikke en forlengelse: rotasjon er den normale veien, og dashbordet beholder den utløpte raden som historikk, så du kan se hva den gamle nøkkelen fikk lov til.
Grenser er agentens egne daglige og månedlige forbruksgrenser i øre. Der foreldrenøkkelen ikke har en grense av en type, må undernøkkelen oppgi en, så en kontonøkkel uten grense kan aldri gi en agent uten grense; der foreldrenøkkelen har en, kan undernøkkelens ikke overstige den. Undernøkkelen har ingen egen saldo. Hvert betalte kall sjekkes mot undernøkkelens grenser og mot foreldrenøkkelens grenser, telt over foreldrenøkkelen og alle undernøklene, og først da trekkes det fra foreldrenøkkelens saldo. En avvisning er 402 SPEND_CAP_REACHED med cap_scope satt til own eller parent, så agenten kan se hvem sin grense den traff. Påfyll hever aldri en grense; å heve den er eierens valg.
Hvordan trekker jeg tilbake en undernøkkel, og hva ser agenten?
Klikk Revoke ved siden av undernøkkelen i dashbordet, eller kall DELETE /api/v1/account/keys/{id}/subkeys/{subkeyId}. Tilbaketrekkingen er én betinget oppdatering nøklet på undernøkkelen, foreldrenøkkelen, kontoen din og tilstanden ikke allerede tilbaketrukket, så den skjer nøyaktig én gang: en gjentakelse, en feil eier eller en ukjent id svarer alle én 404 og skriver ingen andre revisjonsrad. Foreldrenøkkelen røres ikke. Å trekke tilbake foreldrenøkkelen krever ingen kall per undernøkkel: fra neste forespørsel svarer hver undernøkkel under den 401 AUTH_PARENT_KEY_REVOKED.
Undernøkkelen i klartekst vises nøyaktig én gang, i 201-svaret fra opprettelsen og i visningen på dashbordet, og Apier beholder bare SHA-256-hashen av den. Opprettelsesruten tar bevisst ingen Idempotency-Key: et svarlager ville holdt klarteksten gjenfinnbar i et døgn, som er det motsatte av hva en engangshemmelighet trenger. En gjentatt opprettelse er ganske enkelt en ny undernøkkel, avgrenset av grensen per foreldrenøkkel. Gi klarteksten til agenten utenfor verktøyet, i hemmelighetslageret dens, og aldri i en instruks eller en logglinje.
Hver opprettelse skriver en revisjonsrad med agentens navn, scope, utløp og grenser ved siden av undernøkkelens id og foreldrenøkkelens id, og hver tilbaketrekking skriver en med undernøkkelens id og foreldrenøkkelens id; ingen av dem holder nøkkelmaterialet, og listeruten returnerer tilbaketrukne og utløpte undernøkler som historikk. Det er den oversikten en revisor spør etter: hvilken agent kunne lese hva, under hvilket budsjett, mellom hvilke datoer, og hvem som slo den av. For det større bildet av hvordan en agent bør holde og vise legitimasjon, se veiledningen om å integrere en agent over MCP.
Gjør det første kallet
Opprettelsen kjører fra den innloggede dashbordsesjonen din, så den enkleste veien er knappen Sub-keys ved siden av en nøkkel på dashbordet. Curl-kallet under er samme forespørsel. TypeScript-biten er agentens side, med bare undernøkkelen.
# Fra den innloggede dashbordsesjonen din (ruten bruker sesjonskake).
# Body: et utvalg av foreldrenøkkelens scope og grensene agenten får. expires_at
# er utelatt her, så undernøkkelen utløper 30 dager fra nå (standard; inntil
# 365 dager når du sender et RFC 3339-tidspunkt).
curl -s -X POST https://www.apier.no/api/v1/account/keys/<din-nokkel-id>/subkeys \
-H "content-type: application/json" \
--cookie "<sesjonskaken fra dashbordet>" \
-d '{
"name": "fakturasjekker",
"scopes": ["read:brreg"],
"daily_cap_ore": 2000,
"monthly_cap_ore": 20000
}'
# 201: data.plaintext_key vises EN gang. Gi den til agenten utenfor verktøyet.// Agentens side. Den har bare undernøkkelen og ser aldri kontonøkkelen din.
const res = await fetch(
"https://www.apier.no/api/v1/company/999999999/context",
{ headers: { Authorization: `Bearer ${process.env.APIER_SUBKEY}` } },
);
if (res.status === 402) {
// To 402-svar deler statuskoden; error_code skiller dem.
const body = await res.json();
if (body.error_code === "SPEND_CAP_REACHED") {
// cap_scope sier om det var agentens egen grense eller foreldrenøkkelens
// felles grense som avviste kallet. Påfyll hjelper ikke; vent til
// resets_at eller be eieren heve grensen.
console.warn(`grense nådd (${body.cap_scope}); nullstilles ${body.resets_at}`);
} else {
// INSUFFICIENT_CREDITS: foreldrenøkkelens saldo er tom. Bare eieren kan
// fylle på, via body.top_up_url; en undernøkkel avvises på alle
// faktureringsruter, så gi lenken til eieren i stedet for å prøve igjen.
console.warn(`saldoen er tom; eieren fyller på via ${body.top_up_url}`);
}
}
if (res.status === 401) {
// AUTH_SUBKEY_EXPIRED eller AUTH_PARENT_KEY_REVOKED: eieren bestemmer
// hva som skjer videre. Agenten kan ikke lage seg en ny nøkkel.
}Ofte stilte spørsmål
- Hva er en undernøkkel, og hvordan skiller den seg fra API-nøkkelen min?
- En undernøkkel er en legitimasjon laget under en av kontonøklene dine, for én agent. Den har et utvalg av foreldrenøkkelens scope, et obligatorisk utløp og egne forbruksgrenser, og den bruker foreldrenøkkelens saldo. Den kan ikke lage, liste eller trekke tilbake nøkler, kan ikke nå fakturering, og teller aldri mot de tre kontonøklene dine.
- Kan en undernøkkel få mer tilgang enn nøkkelen den ble laget fra?
- Nei, ikke i noen retning. Hvert scope som bes om må finnes på foreldrenøkkelen, en grense kan aldri overstige foreldrenøkkelens grense av samme type, og utløpet er høyst 365 dager. Snevrer du inn foreldrenøkkelens scope senere, snevres hver undernøkkel inn ved neste kall, fordi det gjeldende scopet beregnes som snittet ved hvert kall.
- Hva skjer når jeg trekker tilbake en undernøkkel eller lar den utløpe?
- Agenten avvises fra neste forespørsel. En utløpt undernøkkel svarer 401 AUTH_SUBKEY_EXPIRED, en tilbaketrukket er ganske enkelt ikke gyldig lenger, og trekker du tilbake foreldrenøkkelen svarer hver undernøkkel under den 401 AUTH_PARENT_KEY_REVOKED uten noe kall per undernøkkel. Tilbaketrekkingen er et mykt flagg, så historikken kan fortsatt listes.
- Hvem betaler for agentens kall, og hvordan virker grensene?
- Foreldrenøkkelens saldo betaler. Hvert kall sjekkes mot undernøkkelens egne daglige og månedlige grenser og mot foreldrenøkkelens grenser, telt over foreldrenøkkelen og alle undernøklene dens, i én databasefunksjon før noe belastes. En avvisning er 402 SPEND_CAP_REACHED med cap_scope satt til own eller parent.
- Hvor mange undernøkler kan én nøkkel ha?
- Høyst 10 aktive undernøkler per foreldrenøkkel, der aktiv betyr ikke tilbaketrukket og ikke utløpt. Det ellevte forsøket svarer 409 MAX_SUBKEYS_REACHED. Tilbaketrukne og utløpte undernøkler blir stående i listen som historikk, men tar ingen plass, så rotasjon av en agents nøkkel trenger aldri en større grense.