Third-party OAuth IntegrationReference
Endpoints
All external endpoints with authentication, caching constraints and purpose.
Convention: {issuer} looks like https://id.example.com/v1/oauth, {origin} is its origin, and {consentUi} is the consent UI address (read from the metadata's authorization_endpoint).
Endpoints third parties use
| Method | Address | Auth | Cache | Purpose |
|---|---|---|---|---|
GET | {consentUi}/authorize | None (relies on the user's session) | No cache | Authorization entry point, the browser redirect target |
POST | {issuer}/token | Client authentication | no-store | Exchange, refresh, client credentials |
POST | {issuer}/revoke | Client authentication | no-store | Revoke tokens |
POST | {issuer}/introspect | Confidential clients only | no-store | Query whether a token is active |
GET | {issuer}/jwks | None | 5 minutes | Token signing public keys |
GET | {origin}/v1/auth/userinfo | User access token (auth audience) | No cache | Read user identity |
introspect is not open to public clients: it amounts to "hand the server any token and ask if it is still valid", so opening it up would let anyone holding a leaked token confirm its usability for free.
Internal endpoints (do not call from third parties)
| Method | Address | Notes |
|---|---|---|
POST | {issuer}/preauthorize | Consent UI pre-validation: validates the client and redirect URI, returns display material and a consent_ticket (30-minute lifetime) |
POST | {issuer}/authorize | Consent UI submits the decision: consumes the ticket and the identity assertion, returns the redirect location as JSON (not a 302) |
Both accept POST + JSON only, and exist for MuoCeon's own consent UI. Standard clients following RFC 6749 with GET receive 405 — which is exactly why the metadata's authorization_endpoint points at the consent UI rather than at these endpoints.
Account self-management endpoints (first-party)
| Method | Address | Auth and scope | Notes |
|---|---|---|---|
GET | {issuer}/grants | oauth audience + oauth:grants:read | Paginated list of authorized applications; filter with kind=first_party|third_party |
DELETE | {issuer}/grants/:clientId | oauth audience + oauth:grants:revoke | With did, revokes only that device; without it, all sessions for that client. Requires recent authentication (max_age=300) |
Discovery endpoints
| Address | Specification |
|---|---|
{origin}/.well-known/oauth-authorization-server/v1/oauth | RFC 8414 |
{origin}/.well-known/openid-configuration/v1/oauth | RFC 8414 path form |
{issuer}/.well-known/openid-configuration | OIDC Discovery |
{origin}/.well-known/oauth-protected-resource/v1/auth | RFC 9728 |
{origin}/.well-known/oauth-protected-resource/v1/oauth | RFC 9728 |
{origin}/.well-known/oauth-protected-resource/v1/account | RFC 9728 |
General constraints
- Every endpoint is rate limited independently; exceeding a limit returns
429with aRetry-Afterheader. - Errors from the token-related endpoints (
token/revoke/introspect) follow RFC 6749 §5.2 — see Error codes. - The revocation endpoint returns
200for tokens that do not exist, so it cannot be used as a token oracle.