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_codeenrefresh_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:POST /api/cpanel_accounts,PATCH /api/cpanel_accounts/{username}enDELETE /api/cpanel_accounts/{username}— bestellen, resizen en opzeggen brengen geld in beweging.PATCH /api/cpanel_accounts/{username}/password— het wachtwoord instellen geeft volledige controle over het hostingaccount uit handen.POST /api/cpanel_accounts/{username}/purge— onomkeerbare vernietiging van de gegevens van de klant.POST /api/cpanel_accounts/{username}/domainsenDELETE /api/cpanel_accounts/{username}/domains/{domain}.POST /api/cpanel_accounts/{username}/session— een cPanel-sessie is volledige interactieve controle over het account, en hoort dus thuis bij de andere SSO-endpoints hierboven.
cpanel:readdekt alleen de list/show-reads en de domeinenlijst. (Mailspace stelt zijn writes daarentegen wel beschikbaar — ondermailspace:write.) - De domain-order-endpoints:POST /api/orders/domainenPOST /api/domain_registrations/:id/registrant_change(beide plaatsen een betaalde order en vereisen een gebruiker-gescopete API-sleutel —registrant_changeis bewust uitgesloten van dedomains:write-scope) - Alle write-operaties op orders/sites-facturatie (er is bewust geenbilling:write-scope)
Scope-handhavingsfouten
Fouten
- 401
{"error":"invalid_token","error_description":"token audience is not valid for /api"}| het token draagt eenresource-audience (RFC 8707) die voor een andere resource is uitgegeven (bijv. de MCP-server) —/apiweigert het vóór de scope-controle - 403
{"error":"insufficient_scope","error_description":"requires scope: <required>"}| met headerWWW-Authenticate: Bearer error="insufficient_scope", scope="<required>" - 403
{"error":"insufficient_scope","error_description":"endpoint not available via OAuth"}| endpoint declareert geen scope