Identitet er ikke autorisation
En verificeret e-mail fortæller, hvilken person der er logget ind. Et medlemskab fortæller, om personen må administrere et udviklerarbejdsrum. Et appreview fastlægger den maksimale adgang for en konkret apprevision. Et kundegrant fastlægger, hvad appen må gøre for en bestemt organisation. Et access-token er et tidsbegrænset bevis, der henviser til dette grant.
Alle disse kontroller er nødvendige. Et korrekt formateret token er ikke tilstrækkeligt, og et kundenavn i requestbody bestemmer ikke organisationen. Produktionsgatewayen udleder organisationen fra det serverregistrerede grant og kontrollerer, at app, revision, grant, ejeradgang, miljø og scope stadig er gyldige.
Supabases offentlige OAuth-dokumentation præciserer, at OIDC-scopes som openid, email og profile ikke i sig selv begrænser adgang til tabeller eller API'er. Partner-tokens med præfikserne hat_ og hsk_ er derfor ikke Supabase-JWT'er. Det fritager ikke installationen for at teste sine eksisterende RLS- og RPC-politikker; det undgår at give partneren en almindelig databaseidentitet som standard. Kilde: Supabase token security.
Understøttet klientprofil
Partner-API'et implementerer Authorization Code med obligatorisk S256-PKCE. En confidential klient autentificerer tokenkaldet med client_secret_post. En public klient har ingen fælles klienthemmelighed, bruger godkendelsesmetoden none og er beskyttet af PKCE med S256. Implicit flow, password grant, wildcardredirects, dynamisk klientregistrering og vilkårlig klientvalgt resource understøttes ikke.
Et client-id er appens UUID. Det er en identifikator, ikke en hemmelighed. hcs_-værdien er en klienthemmelighed til tokenudveksling og kan ikke bruges som Bearer-token til at hente regnskabsdata. hat_ bruges til produktions-API'et; hrt_ bruges kun ved refresh; hsk_ bruges kun til sandbox. Brug forskellige variable og secret manager-poster, så typerne ikke forveksles.
Implementeringen er en snæver OAuth-implementering, ikke et certificeret OAuth/OIDC-produkt. RFC 9700 er grundlag for bl.a. PKCE, præcis redirectbinding og replaybeskyttelse ved refresh; den er ikke dokumentation for, at implementeringen består en konformitetstest. Kilde: RFC 9700.
Adresser og metadata
| Formål | Adresse |
|---|---|
| Autorisationsside | /console/authorize |
| Token | /api/partner/oauth/token |
| Tilbagekaldelse | /api/partner/oauth/revoke |
| Metadata | /.well-known/oauth-authorization-server/api/partner |
Issuer er <origin>/api/partner og returneres som iss ved omdirigeringen tilbage til klienten. Kontrollér iss og state, før koden veksles.
Byg en autorisationsanmodning
Generér en ny tilfældig state og en ny PKCE-verifier for hvert loginforløb. Gem dem server-side eller i klientens beskyttede, kortlivede loginstate. Del dem ikke mellem alle brugere. Verifier skal være 43–128 tegn fra det publicerede tegnsæt; challenge er base64url af SHA-256(verifier), uden padding.
Send brugeren til /console/authorize med response_type=code, client_id, en præcis registreret redirect_uri, et mellemrumsepareret scope, state, code_challenge, code_challenge_method=S256 og resource. Resource skal være installationens præcise origin efterfulgt af /api/partner/v1. Der må ikke tilføjes en vilkårlig intern Supabase-URL.
Parametre må ikke gentages. Ukendte scopes afvises. Redirectadressen matches som den registrerede adresse, ikke som "samme domæne" eller "starter med". En forskel i path, query eller afsluttende skråstreg kan derfor være en reel fejl. Ret registreringen og få den nye revision vurderet; gør ikke kontrollen løsere for at få eksemplet til at virke.
Kundens beslutning
Hours viser appens registrerede navn, udgiver, formål og privatlivspolitik. Kunden vælger en organisation, som vedkommende aktuelt ejer, og derefter de tilladte scopes, kontoreferencer og grantets udløb. Godkendelsen kræver ejerens tofaktorbekræftede session (aal2), og et grant gælder højst 90 dage. Profilen er begrænset til ejerautorisation; der er ingen generel delegeret administratorfunktion til at godkende integrationer.
journal:post kræver et særskilt markeret bogføringsmandat. Et generelt "accepter integration" må ikke skjule denne handling. Kunden kan vælge færre rettigheder end anmodet, og appen skal kunne forklare, hvilke funktioner der så ikke er tilgængelige.
Ved afvisning returneres kunden til den servergemte redirectadresse med error=access_denied, state og iss. Ved godkendelse returneres en kortlivet hac_-engangskode. Konsollen accepterer ikke en ny klientvalgt redirectadresse i godkendelsesrequesten. Anmodningen udløber efter ti minutter; koden efter højst 60 sekunder.
Udveksl engangskoden
Brug POST /api/partner/oauth/token med application/x-www-form-urlencoded, aldrig et JSON-body, der tilfældigvis ligner et OAuth-request. For authorization code medsendes grant_type=authorization_code, client_id, code, redirect_uri, code_verifier og den samme resource. En confidential klient medsender også sin klienthemmelighed.
Tokenendpointet hasher kode og credential og sammenligner med serverens registrering. Koden er bundet til app, redirect, PKCE-challenge og resource. Genbrug, udløb eller uoverensstemmelse afvises. Et vellykket svar indeholder access_token, refresh_token, token_type=Bearer, expires_in og de tildelte scopes. Opbevar begge tokens som hemmelige værdier.
Koden gælder 60 sekunder. Access-token lever 15 minutter og aldrig længere end grantet. Refresh-token lever 30 dage og aldrig længere end grantet, og det roteres ved hver brug. Gatewayen kontrollerer også serverstate ved hvert nyt kald, så en tilbagekaldelse ikke blot skal afvente access-tokenets nominelle udløb.
Refresh og tabte svar
Ved refresh sendes grant_type=refresh_token, det aktuelle refresh_token, client-id, resource og eventuel klienthemmelighed. Et vellykket svar erstatter både access- og refresh-token. Gem det nye par atomisk i integrationens egen credentiallagring.
Kør kun én refresh ad gangen for samme forbindelse. Et genbrugt, gammelt refresh-token udløser tilbagekaldelse af hele tokenfamilien. Det beskytter mod replay, men betyder også, at to samtidige legitime refreshrequests kan afbryde forbindelsen. Brug en distribueret lås eller tilsvarende single-flight-mekanisme, hvis integrationen kører på flere workers.
Hvis refresh-svaret forsvinder efter serverens commit, kan det gamle token ikke sikkert prøves igen som en almindelig idempotent skrivning. Genautorisation kan blive nødvendig. Idempotensreglen for journalposteringer gælder ikke automatisk OAuth-tokenudveksling. Denne forskel skal fremgå af driftsproceduren.
Tilbagekaldelse og fejlsøgning
Et token kan tilbagekaldes via /api/partner/oauth/revoke; kundens grant kan tilbagekaldes i Hours. Appens suspension lukker dens adgang på tværs af grants. Fjernelse af en udvikler lukker vedkommendes arbejdsrumsadgang; allerede kopierede, app-ejede klienthemmeligheder kræver rotation.
Ved afvist klientautentificering kontrolleres klienttype, client-id, hemmelighedens udløb (90 dage) og rotation. Ved invalid_grant kontrolleres kodelevetid, PKCE, redirectbinding, tokenreplay og grantstatus. Ved en afvist resource kontrolleres, at den er installationens præcise adresse. Et afvist API-kald med et ugyldigt token giver invalid_token. Log fejltype, tidspunkt og requestreference, men ikke token, kode, verifier eller hele callback-URL'en.
Sæt ikke CORS til * som en hurtig rettelse. Der er ikke dokumenteret en direkte browserbaseret tokenklient på vilkårlig origin. Den relevante klientprofil, redirecttransport og modtagerens egen state-/issuerkontrol skal testes samlet, før en sådan klient bruges i produktion.