OAuth flows
Use OAuth flows to sign a person or an agent in to Port OS and get an access token for the other APIs.
Port OS requires authorization for calls against its APIs. It uses OAuth to issue the tokens that authorize those calls, and it supports extensions that let agents connect automatically: Dynamic Client Registration, client information metadata documents, PKCE and others.
This section covers discovery metadata, client registration, authorize and consent, and the callback that returns the authorization code. Registration alone grants no access to resources. Operation scopes restrict delegated authority in addition to the permission rules for principals and resources.
/.well-known/oauth-authorization-serverDiscover the canonical issuer and endpoints for the deployed environment. Public REST grants use issuer as resource; MCP grants use issuer/mcp. CIMD client IDs must be public HTTPS metadata URLs. Registration is anonymous; device access requires user consent.
Required scope
Not required
Returns
200
Authorization server metadata.
Fields
/.well-known/jwks.jsonReturns the JSON Web Key Set (JWKS) containing the public keys used to verify JWT signatures. This endpoint is publicly accessible and does not require authentication. Responses are cached for one hour.
Required scope
Not required
/.well-known/oauth-protected-resourceReturns OAuth 2.0 Protected Resource Metadata as defined by RFC 9728. This endpoint is publicly accessible and does not require authentication. Responses are cached for one hour.
Required scope
Not required
/.well-known/oauth-protected-resource/mcpReturns OAuth 2.0 Protected Resource Metadata for the MCP endpoint as defined by RFC 9728. This endpoint is publicly accessible and does not require authentication. Responses are cached for one hour.
Required scope
Not required
/auth/device-authorizationThis API is used by your device to obtain authorization from the resource owner via a device code or QR code that your device can scan.
See the OAuth device authorization docs for more.
Uses the existing managed-client device flow. This endpoint is public, but validates its client and supported device grant; anonymous DCR clients support authorization_code and optional refresh_token, and cannot start the device flow.
Required scope
Not required
Returns
200
Device authorization initiated successfully
Fields
Errors
400Invalid request parameters
Check the request fields and any validation details, then correct the payload.
500Internal server error
Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.
/oauth/registerRFC 7591 anonymous public-client registration. No Google session is required. This registration gives no user or resource permissions. Public clients must use PKCE S256, resource-bound authorization_code flow and explicit user consent. Client name, software_id and client_uri are unverified claims, not proof of Muse or any other product. Untrusted software_statement is rejected. Remote callbacks require HTTPS. HTTP is allowed for localhost or literal loopback IPs only, and local callbacks cannot be mixed with remote callbacks. SHA-256 of canonical client_name, sorted redirect_uris, sorted grant_types, sorted response_types and token_endpoint_auth_method identifies a registration. A repeated fingerprint returns the original client_id and accepted metadata, including its original scopes; it never overwrites metadata or expands scopes. Reused registrations do not consume new-registration quota. Unknown metadata extensions are ignored as required by RFC 7591. The deployment enforces rolling registration and retained-client quotas.
Required scope
Not required
Request body
Fields
- redirect_uris
array<string>Required Exact callbacks must form either an entirely localhost/loopback set or an entirely remote HTTPS set. HTTP is allowed only for localhost or literal loopback IPs. Local and remote callbacks cannot be mixed; user information and fragments are forbidden.
- grant_types
array<string> authorization_code, optionally with refresh_token, each at most once. Omitted, the server registers authorization_code and refresh_token and returns them.
uniqueItems: true
Errors
400Invalid metadata, redirect URI, or unapproved software statement.
Check the request fields and any validation details, then correct the payload.
415Use application/json.
Inspect the returned code and family and follow the error handling guide.
429Registration quota reached. Wait before retrying; do not loop.
Wait for Retry-After or details.retryAfterSeconds when supplied; otherwise use backoff.
Response headers
Retry-After- See the source specification for this header.
503Registration storage unavailable.
Wait for the provider or bridge to recover, then retry safely with backoff.
/oauth/authorizeBrowser entry for registered DCR or CIMD clients. Redirects to the sign-in and consent UI. The client must start its registered callback listener first, generate random state and an S256 challenge, and wait for the user. Validate callback state and iss before exchanging the code. A CIMD client_id is an HTTPS, non-loopback URL of a metadata document that the server fetches (size-limited). The document must repeat the URL as client_id, name the client, list HTTPS redirect_uris that pass the server's redirect rules, and declare either public authentication (none) or private_key_jwt with an RS256 or ES256 signing algorithm and an HTTPS jwks_uri. The redirect_uri you send must be one of the listed redirect_uris. Any other metadata is rejected with invalid_client. There is no per-deployment allowlist of CIMD client URLs.
Required scope
Not required
Query parameters
Returns
302
Navigate to sign-in and pending consent.
No response body.
Response headers
- Location
string format: "uri"
Errors
400Invalid or unsupported OAuth request.
Check the request fields and any validation details, then correct the payload.
/oauth/authorizeThe website uses this endpoint after sign-in. Agents open the authorization URL and wait for the user; they never manufacture the user session.
Requires a signed user/session or the existing authenticated client flow. The anonymous DCR delegated device profile cannot invoke this operation.
Required scope
Any authenticated access token
Errors
400Invalid, expired or consumed request.
Check the request fields and any validation details, then correct the payload.
401User sign-in required.
Obtain a valid access token, then retry.
/oauth/authorization-requestReturns server-stored consent details to the authenticated website. Descriptive client metadata is unverified. Agents use the public authorization endpoint and wait for the user; a delegated device token cannot read this session-only endpoint.
Required scope
Any authenticated access token
Errors
400Invalid, expired or consumed request.
Check the request fields and any validation details, then correct the payload.
401User sign-in required.
Obtain a valid access token, then retry.
/oauth/authorization-request/clientReturns only the registration display identity from an unexpired, unused pending authorization request. The request is not consumed. No account, callback, scopes, state, PKCE or authorization response data is exposed. Client names are unverified registration claims. Full consent details and approval still require account sign-in.
Required scope
Not required
Errors
400Invalid, expired or consumed authorization request.
Check the request fields and any validation details, then correct the payload.
/oauth/authorization-responseNavigate the browser here using the continuation returned by authenticated consent. The opaque reference expires after two minutes and is consumed once. The server chooses the stored callback; caller-supplied redirect destinations are never used. Approval carries code, original state and issuer; denial carries access_denied, original state and issuer. No bearer token is needed.
Required scope
Not required
Returns
302
Navigate with GET to the exact registered callback.
No response body.
Response headers
- Location
string format: "uri"
Response headers
- Cache-Control
string no-store
Response headers
- Referrer-Policy
string no-referrer
Errors
400Missing, wrong-stage, expired or consumed continuation reference.
Check the request fields and any validation details, then correct the payload.