Ga naar inhoud

OAuth 2.1

CloudPress draait een standaard OAuth 2.1-autorisatieserver. Gebruik die voor apps van derden die namens een gebruiker handelen; gebruik API-sleutels voor first-party- / server-to-server-integraties.

OAuth-accesstokens zijn nooit admin en zijn fail-closed: een endpoint dat geen scope declareert, is niet beschikbaar via OAuth, en een token waaraan een vereiste scope ontbreekt, wordt geweigerd. Session- en API-sleutel-credentials omzeilen scope- controles volledig.


Authorization Server Metadata

De metadata is per merk, afgeleid van de request-host.

GET /.well-known/oauth-authorization-server

Teruggegeven params
  • issuer: String
  • authorization_endpoint: String | https://<host>/oauth/authorize
  • token_endpoint: String | https://<host>/oauth/token
  • revocation_endpoint: String | https://<host>/oauth/revoke
  • introspection_endpoint: String | https://<host>/oauth/introspect
  • registration_endpoint: String | https://<host>/oauth/registration
  • response_types_supported: Array | ["code"]
  • grant_types_supported: Array | ["authorization_code", "refresh_token"]
  • code_challenge_methods_supported: Array | ["S256"]
  • token_endpoint_auth_methods_supported: Array | ["none"]
  • scopes_supported: Array | zie Scopes
  • service_documentation: String

Alleen none wordt geadverteerd

Deze server geeft uitsluitend publieke PKCE-clients uit, dus token_endpoint_auth_methods_supported adverteert alleen ["none"] — de confidential-methoden ontbreken bewust. Ze stonden er ooit wel in, en spec-conforme clients registreerden zich daarop met client_secret_post en kregen een 400; alleen adverteren wat daadwerkelijk wordt geaccepteerd, heeft dat opgelost.


Flows

  • Grant types: alleen authorization_code en refresh_token.
  • PKCE is verplicht (alleen S256).
  • Refresh tokens roteren — het vorige refresh token wordt bij gebruik ingetrokken. De rotatie gaat pas door zodra het nieuwe access token is gevalideerd tegen de merk-, proef- en rolcontroles.
  • Geen OpenID Connect — er is geen /.well-known/openid-configuration, geen userinfo, geen ID-tokens. De OIDC-gem is alleen aangesloten voor Dynamic Client Registration.
  • Merkisolatie — een token is gebonden aan het merk (hostnaam) waaronder het is uitgegeven en wordt op elk ander merk geweigerd. Het autorisatiescherm toont alleen de niet-proefaccounts van de gebruiker op het huidige merk.

Tokenintrekking bij rolwijziging

Het verwijderen van de rol van een gebruiker op een account trekt diens OAuth-tokens (en sessies) voor dat account in.


Dynamic Client Registration (DCR)

POST /oauth/registration (RFC 7591)

Er worden alleen publieke PKCE-clients uitgegeven. Een token_endpoint_auth_method die niet "none" is, laat de registratie niet mislukken — de waarde wordt stilzwijgend omgezet naar "none", en de reactie geeft "none" terug zonder client_secret. Registreer je dus als publieke client en vertrouw op PKCE (S256); een via DCR uitgegeven secret voegt daar niets aan toe.

Fouten
  • 429 {"error":"too_many_requests", ...} | per-IP-limiet van 50 registraties / uur overschreden

Scopes

Er zijn geen standaardscopes — de aanwezigheid van een token is identiteit, en elke resource-scope is opt-in.

Scope Verleent
sites:read Site-reads + geneste site-reads (show/index, back-uplijst, cachestatus, CDN-status, variantenlijst, taken, edge-rules-lijst, Shield-reads, logs, metrics, overzicht/verzendlogs/verbruik van transactionele e-mail)
sites:write Site- + geneste site-writes (create/update/destroy, back-ups, cache, restart, restore, edge rules, Shield-writes, certificaten, site-domain-CRUD, variantwijziging, instellingen/blokkade-opheffing/DNS-hercontrole van transactionele e-mail) — plus beide kanten van back-upexport (POST en GET /api/sites/{site-id}/backups/{volume-id}/export; het uitlezen van de status zit bewust achter de write-scope, omdat het een presigned URL naar de volledige back-up teruggeeft)
domains:read Domeinen list/show/query/available; domain-registration index/show/check/suggestions; contacts/hosts/processes reads
domains:write Domain-registration-mutaties; domain-contact create/update/destroy/resend; host/process writes
dns:read DNS-zones index/show/dns_stats; DNS-records index/show
dns:write DNS-zone & -record create/update/destroy
mailspace:read Mailspace list/show, plus elke read binnen een mailomgeving: mailboxen (inclusief de controle op beschikbaarheid van een adres), app-wachtwoorden, mailregels, afwezigheidsberichten, aliassen, groepen, mailinglijsten, verhulde adressen, extra domeinen en hun DNS-records, de status van domeinverificatie, bezorglogs, gearchiveerde berichten (inclusief het downloaden van het ruwe bericht) en de lijst met te herstellen mailboxen
mailspace:write Mailspace aanschaffen, pakket wijzigen en soft-delete, plus elke write binnen een mailomgeving: mailbox-CRUD/herstel/definitief verwijderen, app-wachtwoorden, mailregels, afwezigheidsberichten, aliassen, groepen, mailinglijsten, verhulde adressen, CRUD op extra domeinen en de DNS-hercontrole, domeinverificatie, mailboxherstel — en het onomkeerbaar direct definitief verwijderen van een met soft delete verwijderde mailomgeving en van een mailbox
billing:read Orders index/show; subscriptions index/show; carts show
cpanel:read cPanel-account list/show en de domeinenlijst van het account (GET /api/cpanel_accounts, GET /api/cpanel_accounts/{username}, GET /api/cpanel_accounts/{username}/domains) — alleen reads; elke cPanel-write is met geen enkel OAuth-token bereikbaar (zie hieronder). cPanel wordt per workspace ingeschakeld, dus deze endpoints geven 403 cpanel_not_enabled terug waar dat niet is gebeurd

GET /api/about accepteert elk geldig token, ongeacht scope.

Endpoints die niet beschikbaar zijn via OAuth

Deze declareren geen scope en zijn fail-closed — ze vereisen een session- of API-sleutel-credential en geven 403 endpoint not available via OAuth terug voor elk OAuth-token:

De afwezigheid van een scope is de controle

De scopehandhaving bepaalt per actie op requesttijd welke scope vereist is; is er niets gedeclareerd, dan wordt het request geweigerd in plaats van toegestaan. Er is dus geen enkele scope — ook geen hypothetische billing:write — waarmee je de onderstaande endpoints bereikt. Dat is bewust zo voor de endpoints waar geld mee gemoeid is: een app van derden kan namens jou geen betaalde dienst bestellen, resizen of opzeggen, hoe breed je ook toestemming hebt gegeven.

  • Account-CRUD & account-rollen
  • API-sleutels
  • Gebruikers en user_roles
  • De globale taken-endpoints (GET /api/tasks/:id)
  • SSO (per-site en top-level)
  • Rapporteren van een taakresultaat (POST /api/webhooks/task/{task-id})
  • POST /api/webhooks/cdn_cache — de platform-interne CDN-purge-callback, die authenticeert met een systeem-API-sleutel vanaf een toegestaan IP-adres
  • Elke cPanel-account-write. Er is geen cpanel:write-scope, dus deze zijn allemaal alleen via sessie of API-sleutel bereikbaar:

    cpanel:read dekt alleen de list/show-reads en de domeinenlijst. (Mailspace stelt zijn writes daarentegen wel beschikbaar — onder mailspace:write.) - De domain-order-endpoints: POST /api/orders/domain en POST /api/domain_registrations/:id/registrant_change (beide plaatsen een betaalde order en vereisen een gebruiker-gescopete API-sleutel — registrant_change is bewust uitgesloten van de domains:write-scope) - Alle write-operaties op orders/sites-facturatie (er is bewust geen billing:write-scope)

Scope-handhavingsfouten

Fouten
  • 401 {"error":"invalid_token","error_description":"token audience is not valid for /api"} | het token draagt een resource-audience (RFC 8707) die voor een andere resource is uitgegeven (bijv. de MCP-server) — /api weigert het vóór de scope-controle
  • 403 {"error":"insufficient_scope","error_description":"requires scope: <required>"} | met header WWW-Authenticate: Bearer error="insufficient_scope", scope="<required>"
  • 403 {"error":"insufficient_scope","error_description":"endpoint not available via OAuth"} | endpoint declareert geen scope