Ga direct naar de documentatie
API

Scopes

Wat een key mag doen.

De woordenlijst

Een gesloten verzameling, resource:action. Klein genoeg om een mens op een aanvinklijst te tonen, en stabiel genoeg dat een opgeslagen toekenning een jaar later nog hetzelfde betekent. Dezelfde woordenlijst is waarin een workspace-ROL geschreven wordt en waarmee MCP-tools worden afgeschermd, zodat een alleen-lezen client een verzendtool niet eens ziet. Eén alfabet, drie oppervlakken.

ScopeGeeft recht op
emails:sendE-mail versturen
emails:readVerzonden berichten en hun afleverstatus lezen
drafts:readConcepten lezen
drafts:writeConcepten aanmaken en bewerken
threads:readThreads en berichten lezen
threads:writeThreads labelen, als gelezen markeren en archiveren
labels:readLabels lezen
labels:writeLabels aanmaken en bewerken
contacts:readContacten lezen
contacts:writeContacten toevoegen, bewerken en verwijderen
audiences:readAudiences lezen en zien wie erin zitten
audiences:writeAudiences aanmaken en bewerken, en wijzigen wie erin zitten
calendar:readAgenda-items en uitnodigingen lezen
calendar:writeAgenda-items aanmaken, wijzigen en erop reageren
templates:readE-mailtemplates lezen en er een preview van bekijken
templates:writeE-mailtemplates aanmaken, bewerken en ermee versturen
domains:readDomeinen en hun DNS-status lezen
domains:writeDomeinen verifiëren en configureren
webhooks:readWebhook-endpoints en -afleveringen lezen
webhooks:writeWebhooks aanmaken, bewerken en testen
rules:readMailregels lezen en testen
rules:writeMailregels aanmaken, bewerken en herordenen
connections:readLezen welke mailboxen verbonden zijn
members:readZien wie er in de workspace zitten en wat ze hebben
members:writeMensen toevoegen en verwijderen, en wijzigen wat ze kunnen bereiken
roles:readDe rollen lezen die deze workspace definieert
roles:writeRollen aanmaken, bewerken en verwijderen
settings:readMailboxinstellingen lezen, inclusief de handtekening
settings:writeMailboxinstellingen en de handtekening wijzigen
keys:writeZijn eigen secret vervangen zonder dat iemand de console opent

Een key die zonder doordachte scopelijst wordt aangemaakt, krijgt emails:send en verder niets. De veilige standaard voor een credential is het smalste wat hem bruikbaar maakt.

Een key wordt begrensd door de rol erachter

Een key kan onder een ROL worden uitgegeven, en een rol is een plafond en geen tweede toekenning. Wat de key werkelijk mag, is zijn eigen scopes DOORSNEDEN met de permissies van die rol (key.scopes ∩ role.permissions), bij elk request één keer aan de rand berekend, voordat er een endpoint bereikt wordt. Stroomafwaarts weet niets dat rollen bestaan: een scope die de rol niet heeft, staat simpelweg niet in de lijst die de scopecontroles lezen.

De twee lijsten worden dus samen gelezen en geen van beide wint op eigen kracht. Een key met emails:send onder een rol die die permissie niet heeft, mag niet versturen; een rol met emails:send geeft niets aan een key die er nooit om gevraagd heeft. Een scope aanvinken is om bevoegdheid vragen, en de rol bepaalt hoeveel je krijgt van wat je gevraagd hebt.

Een key ZONDER rol heeft geen plafond en is daarmee zo breed als de workspace waaronder hij is uitgegeven. Dat is wat elke key die vóór het bestaan van rollen is aangemaakt draagt, en wat een owner nog steeds krijgt door het veld met rust te laten, dus een lege rol is de BREEDSTE staat waarin een key kan verkeren, niet de smalste. Daarom moet je bij het verwijderen van een rol ook zeggen waar zijn keys heen moeten: ze als wees achterlaten zou ze stuk voor stuk stilletjes promoveren.

De doorsnede wordt per request bepaald en niet bij uitgifte op de key gestempeld. Daarmee is een rol versmallen een live intrekking, van kracht bij de eerstvolgende aanroep van de beller en zonder dat de key geroteerd hoeft te worden — en een rol verbreden is op precies dezelfde manier live, en dat is de helft die het onthouden waard is.

GET /ping en GET /keys/self melden scopes naast grantedScopes en roleId met het oog op één specifieke storing. scopes is de effectieve lijst en de enige die iets autoriseert; grantedScopes is waarmee de key is uitgegeven. Alles wat in de tweede staat en in de eerste ontbreekt, is door de rol weggenomen, en dat verschil is het volledige antwoord op "mijn key heeft emails:send en ik krijg insufficient_scope". De oplossing is een rolwijziging en niet nog een key.

Een key die de rol versmald heeft
curl "$OE/ping" -H "$AUTH" {  "ok": true,  "keyId": "4c1b257a66287fd113bd89d0",  "mode": "live",  "scopes": ["emails:read", "threads:read"],  "roleId": "role_c40a95f21cc65d31c2a89e07",  "grantedScopes": ["emails:send", "emails:read", "threads:read"],  "workspaceId": "10417196-e324-4283-af98-66ec62167c47"}

Vijf permissies kunnen een key nooit bereiken: api-keys:read, api-keys:write, billing:read, billing:write en workspace:manage. Het zijn permissies maar geen scopes, dus geen enkele rol kan ze, hoe royaal ook, op een token zetten: nog een key aanmaken, wijzigen wat een andere key mag, of het abonnement veranderen doet alleen een ingelogd persoon. Het enige wat een key met zichzelf mag doen, is zijn eigen secret vervangen, achter de scope keys:write. GET /roles/permissions markeert die vijf met scope: false, en dat laat één component zowel de rollenmatrix als de aanvinklijst bij het aanmaken van een key weergeven.

roles:write is feitelijk de hele woordenlijst, en doen alsof dat niet zo is zou de gevaarlijkere documentatie zijn. Een key die het heeft kan juist de rol die hem begrenst PATCHen en zichzelf al het andere geven, en omdat het plafond per request wordt bepaald geldt het bredere plafond al bij de eerstvolgende aanroep. Dat is geen gat om te dichten, want een rollenbewerker die geen rollen kan bewerken is geen rollenbewerker. Het is een reden om roles:write niet op een key te zetten die alleen ooit de ledenlijst hoefde te lezen.

Verzendbereik

Los van scopes kan een key worden versmald in waaronder hij mag versturen. Hij draagt twee lijsten. domainAllowlist bevat hele domeinen, en een key met een domein mag versturen als elk adres op dat domein, inclusief adressen die na de key zijn aangemaakt. addressAllowlist bevat losse adressen. Laat beide leeg en de key is zo breed als de workspace, nooit breder. GET /keys/self toont beide lijsten en GET /addresses meldt wat een gegeven key werkelijk mag gebruiken, en dat is het antwoord op een onverklaarde from_address_forbidden.

Dezelfde verzameling versmalt wat de key leest. Verzonden mail, tracking en agenda antwoorden alleen voor adressen waaronder de key mag versturen, dus een key die tot één domein beperkt is, verstuurt noch leest namens een ander domein. Een heel domein laat de key ook de trackinghost van dat domein instellen, wat een key die tot losse adressen beperkt is niet kan.

Drie versmallingen dus, en ze stapelen in plaats van elkaar te overschrijven: de scopes op de key, de permissies van de rol erboven, en de domeinen en adressen die hij in een From-header mag zetten. Een verzending heeft alle drie nodig, en een weigering noemt alleen de eerste die hij tegenkwam.