Guide 2 af 8
Autentificering og scopes
Bearer-nøglen
Hvert kald bærer nøglen i en standard Authorization-header:
GET /api/v1/invoices?per_page=50 HTTP/1.1
Host: app.levano.io
Authorization: Bearer lev_live_...
Accept: application/jsonDer er ingen alternativ. Nøglen må ikke lægges i en query-parameter: den ender i adgangslogs, i browserhistorik og i referer-headere, og den kan ikke roteres væk fra dem igen.
Mangler headeren, eller er nøglen ukendt, spærret eller udløbet, får du 401 med {"message": "Unauthenticated."}.
Én organisation pr. nøgle
Nøglen bærer organisationen. Du sender aldrig et organisations-id, og der er ingen parameter der kan skifte den.
Det er ikke bare en konvention i controllerne. Tenant-afgrænsningen sidder på modellerne, og uden en gyldig nøgle er der ingen tenant, så en forespørgsel uden autentificering rammer nul rækker frem for alle. Konsekvensen i praksis: et id fra en anden organisation opfører sig præcis som et id der ikke findes.
Scopes
Scopes hedder ressource:handling. Nøglen får dem tildelt ved oprettelsen, og hvert endpoint kræver præcis ét.
| Scope | Åbner |
|---|---|
matters:read |
/matters, /matters/{id} |
clients:read |
/clients, /clients/{id}, /people, /people/{id}, /companies, /companies/{id} |
time:read |
/time-entries |
invoices:read |
/invoices, /invoices/{id} |
documents:read |
/documents, /documents/{id}. Kun metadata, aldrig filens indhold |
reports:read |
/reports/{type} |
webhooks:manage |
Hele /webhooks-familien, både læsning og skrivning |
clients:read dækker både engagementet og parterne bag det, altså personer og virksomheder. Det er ét scope, ikke tre, fordi de tre lister beskriver den samme relation set fra hver sin side.
To navne er reserveret i kataloget, men har ingen endpoints: settings:read og settings:write. Du kan sætte dem på en nøgle i dag, og de åbner ikke noget før de gør. Byg ikke logik på dem endnu.
Den autoritative liste står på hver enkelt operation i referencen. Bliver tabellen her uenig med den, er referencen den der er rigtig.
Giv den mindst mulige nøgle
Et scope kan ikke tilføjes til en nøgle bagefter. Det er med vilje: en nøgle der stille voksede sig større er svær at revidere. Skal integrationen kunne mere, opretter du en ny nøgle med det rigtige sæt og udfaser den gamle.
Så vælg smalt fra start. En rapporteringsintegration skal have invoices:read og reports:read, ikke også clients:read, fordi det var nemmere at klikke alle af.
Rotation sker med overlap
En klient kan have flere aktive hemmeligheder på én gang, og det er hele pointen med rotationsflowet. Under Indstillinger, API-nøgler kan en administrator:
- Rotere: der udstedes en ekstra hemmelighed. Den gamle bliver ved med at virke, indtil nogen spærrer den. Så rækkefølgen er: rotér, udrul den nye nøgle, kontrollér at trafikken er flyttet, spær så den gamle.
- Spærre en hemmelighed: netop den streng holder op med at virke. Klienten og dens øvrige hemmeligheder er upåvirkede.
- Spærre klienten: alle dens hemmeligheder dør sammen med den.
401fra første kald efter.
Spærring slår igennem med det samme, uden nådeperiode. En nøgle kan også have en udløbsdato ved oprettelsen. Efter det tidspunkt svarer den 401 uden yderligere varsel, så sæt en påmindelse hvis du bruger udløb.
Manglende scope svarer 403
Har nøglen ikke det scope endpointet kræver, får du 403 med navnet på det scope der mangler:
{
"message": "Insufficient scope.",
"required_scope": "invoices:read"
}Feltet er der så du kan skrive en brugbar fejl i din egen log frem for "adgang nægtet". Se Fejl og rate limits for de øvrige koder.
KYC-API'en har sine egne tokens
/api/kyc/v1 er en selvstændig kontrakt med sit eget token, oprettet under Indstillinger, KYC API. En åben-API-nøgle virker ikke der, og omvendt. KYC-tokens har ikke scopes: tokenet giver adgang til hele KYC-kontrakten for den ene organisation.