auth is simply used anonymously.
Advertisement
Two methods are understood; anything else is recorded asunsupported
(ignored) until a setup request needs it, which then fails with 400.
API key (header)
nameis the header Cyrnel will send the key under (trimmed). It is pinned at setup.- Query-parameter API keys are not supported: advertising
"in": "query"(or anything other than"header") marks the method unsupported with the reason'in' must be 'header'; query-param api keys are not supported.
OAuth2 client credentials
grantTypemay only beclient_credentials(or omitted); anything else is unsupported.tokenEndpointmust be an absolutehttp(s)URL.scopesis an optional list of{ id, description? }. It describes the scopes the registry offers; see Scope selection.
Credential scope
Credentials are attached only to requests within the registry’s origin and, if the base URL has a path, that path prefix. On cross-origin redirects they are stripped - Cyrnel re-evaluates scope at every hop.Transport rules
Credentials are only sent over:https, orhttpwhere the resolved address is loopback, orhttpwhere the resolved address matches a CIDR inCYRNEL_REGISTRY_AUTH_INSECURE_CIDRS.
502 Registry authentication requires https; refusing to send credentials over plaintext http.
Setup-time violations are 400 safety refusals (nothing stored). Local
development over plaintext on loopback works out of the box.
Setup
Auth is configured either at add time (POST /registries with auth) or
later via POST /registries/:id/auth: both validated against the live
advertisement (fetched fresh, never from the stored snapshot):
Safety refusals (400, nothing stored)
Failure persistence (two paths)
Success returns
auth: { type, status: "configured", tokenExpiresAt }.
Pinning & drift
headerName (apiKey) and tokenEndpoint (oauth2) are pinned from the
advertisement at setup time. If the registry later changes what it
advertises, Cyrnel keeps using the pinned values and logs a warning
(prompting reconfiguration): it never silently adopts the drift. Drift
log events: registry-auth-unsupported, registry-auth-unconfigured,
registry-auth-type-drift, registry-auth-token-endpoint-drift (“pinned
endpoint retained (reconfigure to adopt)”), registry-auth-header-drift
(“pinned header retained (reconfigure to adopt)”).
Token lifecycle
- Tokens are persisted encrypted in the
registry_authtable and reused until theirexpiresAtis within 30 seconds of expiry (skew), then a fresh exchange happens. - The exchange is single-flight: concurrent first requests share one request.
- Token requests are
POST <tokenEndpoint>with aapplication/x-www-form-urlencodedbody:grant_type=client_credentials,client_id,client_secret, andscope(space-joined selected scopes). - The response must include
access_token(string);expires_in(seconds) defaults to 1 hour when absent;refresh_tokenis stored but never used: refresh is always a fresh client-credentials exchange. - A single
401from the upstream after using an oauth2 token triggers one retry with a freshly exchanged token. apiKey auth never retries. - Signature for well-formed failures: non-2xx token response →
502 Registry oauth2 token endpoint responded with status N.; malformed →502with the parse reason.
Scope selection
- Setting
scopesto a subset of the advertised list is allowed and attached to the token request. - Omitting
scopesrequests the full advertised set (Cyrnel sends the space-joined advertised scope ids). - Any scope not advertised is a
400safety refusal - a registry that doesn’t advertisescopesgets noscopeparameter at all. - The current state is readable via
GET /registries/:id/auth:
availableScopes is fetched live from the registry’s current
advertisement on every read (never cached); configuredScopes is
decrypted from stored config. authType may be null (nothing
configured); tokenExpiresAt is null for apiKey.
Testing drift & scopes
The dev fixture can advertise values it does not enforce (CYRNEL_DEV_REGISTRY_DRIFT_AUTH=1) to exercise the pinning behavior,
and it enforces its advertised scopes on the token endpoint
(invalid_scope for unknown requested scopes). See
Building a registry.