@portpowered/reference-data 0.4.11 → 0.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/generated/guides.json +2 -2
- package/generated/openapi.json +3 -3
- package/generated/public/docs/for-ai/guides/authentication-and-dcr.md +3 -3
- package/generated/public/docs/for-ai/guides/oauth-consent-and-callback.md +3 -3
- package/generated/public/docs/for-ai/operations/beginOAuthAuthorization.md +1 -1
- package/generated/public/docs/for-ai/operations/completeOAuthConsent.md +1 -1
- package/generated/public/docs/for-ai/operations/deliverOAuthAuthorizationResponse.md +1 -1
- package/generated/public/docs/references/manifest.json +12 -12
- package/generated/public/docs/references/openapi.yaml +3 -3
- package/package.json +1 -1
package/generated/guides.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
{
|
|
9
9
|
"id": "authentication-and-dcr",
|
|
10
10
|
"title": "Authentication and dynamic client registration",
|
|
11
|
-
"content": "# Authentication and dynamic client registration\n\nAll supported agents use the same OAuth components. REST and MCP select different protected resources; DCR and CIMD select different registration methods. Neither product branding nor registration grants device access.\n\nChoose one reading path. This complete walkthrough already includes discovery, registration, consent, token lifecycle and authorization rules below; you do not need to fetch those component links again. If your connector already implements some steps, read only the missing components instead. Both paths use the same canonical instructions.\n\nFor REST, use the discovered issuer as the OAuth resource. For MCP, use the MCP protected-resource metadata. Keep that choice through authorization, exchange and refresh. If you chose the wrong transport, start a new authorization flow for the correct resource; refresh does not switch audiences.\n\nWalkthrough steps (the linked components are also included below):\n\n1. [Discover endpoints and choose REST or MCP](/docs/for-ai/guides/oauth-discovery.md).\n2. [Register with DCR or supported CIMD](/docs/for-ai/guides/oauth-client-registration.md). Remote callbacks require HTTPS; local callback registrations contain only localhost/loopback callbacks. Repeated canonical fingerprints reuse the original public client without expanding scopes.\n3. [Obtain user consent and validate the callback](/docs/for-ai/guides/oauth-consent-and-callback.md). PKCE S256 is required. Pause for the user to sign in and approve access.\n4. [Exchange, refresh and revoke tokens](/docs/for-ai/guides/oauth-token-lifecycle.md). Keep the same canonical resource through authorization, exchange and refresh.\n5. [Verify the connection](/docs/for-ai/guides/first-setup.md), then use [the REST quickstart](/docs/for-ai/guides/quickstart.md) or your client's MCP tools.\n\nRead [authorization rules](/docs/for-ai/guides/authorization-rules.md) for scopes, principal/resource policies, sharing and denial diagnosis. Never ask for a Google password, paste credentials into chat, or approve the agent's own grant. Claimed client names such as Muse and Grok remain unverified.\n\n## Discover the OAuth server and choose REST or MCP\n\nThis discovery step is shared by every client. The deployed pilot API is https://api.portoperatingsystem.lol. Fetch its /.well-known/oauth-authorization-server document anonymously. Read issuer, authorization_endpoint, token_endpoint, registration_endpoint, revocation_endpoint and scopes_supported. Use the returned endpoints exactly. An alias can advertise a different canonical Cloud Run issuer; do not substitute the alias into token audiences.\n\n| Interface | API destination | OAuth resource |\n| --- | --- | --- |\n| REST | The returned issuer, plus the documented operation path | The exact returned issuer |\n| MCP | The returned issuer plus /mcp, Streamable HTTP | The resource returned by /.well-known/oauth-protected-resource/mcp, normally issuer plus /mcp |\n\nAn MCP connector can start at https://api.portoperatingsystem.lol/mcp and follow its WWW-Authenticate resource_metadata URL. Fetch that public metadata and the authorization server it names. MCP initialization alone does not prove that the account's devices are accessible. Never use a REST token on MCP or an MCP token on REST.\n\nChoose the transport before authorizing. Omitting resource at authorization selects REST. Supply the discovered resource explicitly to select MCP. Code exchange and refresh may omit resource and inherit the grant audience; an explicit resource must stay unchanged. If a REST request fails because you authorized the MCP resource (or the reverse), obtain a new user authorization for the correct resource. Refresh cannot change the token's audience.\n\nChoose one supported [client registration method](/docs/for-ai/guides/oauth-client-registration.md), then follow the same [consent and callback steps](/docs/for-ai/guides/oauth-consent-and-callback.md). If metadata omits registration_endpoint, new DCR registration is unavailable; do not guess a replacement endpoint or silently switch to another client's credentials.\n\nSee [scopes and resource rules](/docs/for-ai/guides/authorization-rules.md). Authorization-server scopes_supported describes server vocabulary; a particular client's accepted scopes can be narrower.\n\n### Carry discovery values into every request\n\nThis JavaScript fragment initializes a REST connection. Keep `authorizationServer` and `resource` for the consent and token examples; the API alias is only the discovery starting point.\n\n```javascript\nconst response = await fetch('https://api.portoperatingsystem.lol/.well-known/oauth-authorization-server');\nif (!response.ok) throw new Error('OAuth discovery failed');\nconst authorizationServer = await response.json();\nconst resource = authorizationServer.issuer;\nconst apiBase = authorizationServer.issuer;\n```\n\nFor MCP, assign `resource` from the protected-resource metadata's `resource` field instead. Do not replace either value with the hostname you started from. A wrong `resource` can produce an `invalid_target` error callback even when client registration succeeded.\n\nCanonical component: [Discover the OAuth server and choose REST or MCP](/docs/for-ai/guides/oauth-discovery.md).\n\n## Register an OAuth client with DCR or CIMD\n\nStart with [discovery](/docs/for-ai/guides/oauth-discovery.md). DCR and CIMD identify a client; they do not sign in a user or grant device access. Both use the same [PKCE consent and callback flow](/docs/for-ai/guides/oauth-consent-and-callback.md) and [token lifecycle](/docs/for-ai/guides/oauth-token-lifecycle.md).\n\n### DCR: public clients\n\nPOST application/json to the discovered registration_endpoint:\n\n```json\n{\"client_name\":\"My device assistant\",\"redirect_uris\":[\"https://your-client.example/oauth/callback\"],\"token_endpoint_auth_method\":\"none\",\"grant_types\":[\"authorization_code\",\"refresh_token\"],\"response_types\":[\"code\"],\"scope\":\"endpoint:read message:send\"}\n```\n\nUse a callback the client controls. Remote callbacks require HTTPS. Local clients may use exact HTTP callbacks on localhost or literal loopback IPs, such as http://127.0.0.1:8765/callback. All callbacks in a registration must be local or all must be remote; these sets cannot be mixed. No fragments or user information are permitted. Start the local callback listener before authorization. The website's client-management interface enforces this same callback-set policy.\n\nSuccess is 201 with client_id, client_id_issued_at and accepted metadata. Public clients get no client_secret. Supported DCR scopes are endpoint:read, endpoint:write, message:read, message:send, group:read, group:manage, subscription:read and subscription:write. The default is endpoint:read. Request only the task's necessary scopes and check the returned scope. Broader static-client scopes are outside this anonymous profile.\n\nThe registration fingerprint is SHA-256 of compact canonical JSON with sorted object keys and sorted redirect_uris, grant_types and response_types arrays, plus client_name and token_endpoint_auth_method. Defaults are applied before hashing. Array ordering does not create another client. A matching registration returns the original client ID, issue time, scopes and descriptive metadata. It never overwrites the existing client or expands scopes, even if scope or software_id differs in the new request. Fingerprinting is deduplication, not proof of callback ownership or vendor identity.\n\nDefault quotas are 1,000 new registrations per rolling day and 10,000 retained registrations. Reuse does not consume new-registration quota. A quota failure returns 429 with Retry-After. An operator can disable new registrations without retiring existing grants. Read the [registration operation](/docs/for-ai/operations/registerDynamicOAuthClient.md) for exact request, response and error schemas.\n\n### CIMD: allowlisted metadata clients\n\nA supported CIMD client uses its allowlisted HTTPS metadata URL as client_id instead of posting a DCR request. Port OS retrieves and validates that client metadata, including its exact callbacks and public PKCE profile. Arbitrary metadata URLs and redirects from the metadata fetch are not supported. If your metadata URL is not allowlisted, arrange onboarding or use DCR if your client supports it. Do not pretend another client's metadata URL belongs to you.\n\nClient_name, software_id, software_version and client_uri remain unverified claims. No trusted software-statement issuer is configured; software_statement is rejected. A registration called Muse or Grok does not establish a verified vendor integration or gain additional permissions. Static confidential clients retain their separately configured client authentication method.\n\nCanonical component: [Register an OAuth client with DCR or CIMD](/docs/for-ai/guides/oauth-client-registration.md).\n\n## Obtain user consent and validate the OAuth callback\n\nUse the endpoints and resource from [discovery](/docs/for-ai/guides/oauth-discovery.md) and the client ID and exact callback from [registration](/docs/for-ai/guides/oauth-client-registration.md). These steps are identical for DCR and CIMD, REST and MCP; the chosen resource is the transport-specific input.\n\n`resource` is optional. Omitting it selects the canonical REST audience (the authorization-server issuer). For MCP, supply its discovered `/mcp` resource explicitly. Token exchange and refresh can omit `resource` and inherit the audience bound to the authorization code or refresh token. Explicit mismatches are rejected as `invalid_target`.\n\n1. Start the callback handler the client controls. For a loopback callback, bind its listener locally before opening authorization.\n2. Generate a cryptographically random PKCE verifier of 43–128 permitted characters. Compute code_challenge = BASE64URL(SHA256(verifier)), without padding. Generate a separate random state and retain both in this authorization attempt.\n3. Open the discovered authorization_endpoint with the following query parameters. Percent-encode parameter values; do not append raw callback URLs or scopes into an unescaped query.\n\n```text\nclient_id=<registered ID or supported CIMD metadata URL>\nredirect_uri=<exact registered callback>\nresponse_type=code\nscope=<requested subset of the client's accepted scopes>\nresource=<chosen canonical REST or MCP resource>\nstate=<random client state>\ncode_challenge=<S256 challenge>\ncode_challenge_method=S256\n```\n\nFor REST, use the `resource = authorizationServer.issuer` value retained from discovery. Construct the URL rather than writing an alias into a template. This JavaScript fragment assumes `clientId`, `redirectUri` and `acceptedScope` come from your registration response and callback configuration:\n\n```javascript\nconst base64url = bytes => btoa(String.fromCharCode(...bytes))\n .replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/, '');\nconst verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));\nconst state = base64url(crypto.getRandomValues(new Uint8Array(32)));\nconst challenge = base64url(new Uint8Array(await crypto.subtle.digest(\n 'SHA-256', new TextEncoder().encode(verifier))));\nconst authorizationURL = new URL(authorizationServer.authorization_endpoint);\nauthorizationURL.search = new URLSearchParams({\n client_id: clientId, redirect_uri: redirectUri, response_type: 'code',\n scope: acceptedScope, resource, state,\n code_challenge: challenge, code_challenge_method: 'S256',\n}).toString();\n// Retain verifier, state and authorizationServer.issuer privately until callback validation.\n// Open authorizationURL.href in the user's browser; wait for their consent.\n```\n\nThe user signs in on Port OS and reviews the requested permissions. Pause for the user; an agent must not approve its own grant, request passwords or manufacture a production sign-in identity. Local functional tests substitute an existing signed fixture identity at this boundary without changing production sign-in.\n\nAfter approval, the consent page navigates to a one-time Port OS continuation.\nThat endpoint returns HTTP 303 See Other with the exact registered callback in\nLocation, carrying code, original state and iss. Denial uses the same 303 handoff\nwith access_denied instead of a code. The authenticated consent fetch returns\n200 JSON only for the intermediate continuation; it must be followed by document\nnavigation, not another fetch. Continuations expire after two minutes and are\nsingle-use. They require no login token and cannot be used to approve consent.\n\nReject a callback whose state or issuer does not match this attempt. Treat an\nerror callback as a denied or failed authorization, not a code. Codes and pending\nconsent expire after ten minutes and are single-use. Do not paste codes,\ncontinuation references or credentials into shared chat or logs. Continue with\n[code exchange and token lifecycle](/docs/for-ai/guides/oauth-token-lifecycle.md).\n\nFor hosted-client acceptance, preserve the browser network log and approve a\nfresh request. Verify the document request to /oauth/authorization-response\nreturns 303, the next GET reaches the registered client callback, and the client\nposts its code and original PKCE verifier to the discovered token endpoint.\nRepeat with Deny and verify access_denied without a code. Backend functional and\nwebsite browser tests cover these boundaries against an isolated callback;\ncompatibility with a specific hosted client still requires that live trace.\n\nCanonical component: [Obtain user consent and validate the OAuth callback](/docs/for-ai/guides/oauth-consent-and-callback.md).\n\n## Exchange, refresh and revoke scoped OAuth tokens\n\nComplete [callback validation](/docs/for-ai/guides/oauth-consent-and-callback.md) first. For a public DCR/CIMD client, POST application/x-www-form-urlencoded to the discovered token_endpoint with:\n\n```text\ngrant_type=authorization_code\nclient_id=<client ID used for authorization>\ncode=<validated callback code>\nredirect_uri=<the same exact callback>\ncode_verifier=<this attempt's original verifier>\nresource=<the same canonical resource used for authorization>\n```\n\nContinue with the same discovery values and verifier from the consent example. `code` below must be from a callback whose `state` and `iss` you validated; abort on any callback `error`:\n\n```javascript\nconst tokenResponse = await fetch(authorizationServer.token_endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code', client_id: clientId, code,\n redirect_uri: redirectUri, code_verifier: verifier, resource,\n }),\n});\nif (!tokenResponse.ok) throw new Error('OAuth code exchange failed');\nconst tokens = await tokenResponse.json(); // Store securely; do not print tokens.\n```\n\nSave access_token, refresh_token and returned scope in the connector's secure credential store. Public clients have no client secret. Use Authorization: Bearer <access_token> with REST requests or the MCP HTTP connection, according to that token's resource. A refresh token is never an API credential. [Scopes bound access; resource policies still apply](/docs/for-ai/guides/authorization-rules.md).\n\nRefresh with grant_type=refresh_token, client_id and refresh_token at token_endpoint. The resource parameter is optional for code exchange and refresh: omission inherits the existing grant audience; if supplied, it must match the original resource. Scope may stay the same or narrow; it cannot expand. Credentials rotate: store the newly returned refresh token atomically and stop using the previous one. A revoked or reused refresh token must not be retried in a loop. Reauthorize when the grant no longer permits the intended operation.\n\nRevoke by POSTing application/x-www-form-urlencoded token=<refresh_token>&client_id=<client_id> to revocation_endpoint. Revoked grants stop authorizing both access and refresh requests. Removing a local configuration file alone is not server-side revocation.\n\nRead [the token operation](/docs/for-ai/operations/generateToken.md), [revocation operation](/docs/for-ai/operations/revokeOAuthGrant.md), and [connection recovery](/docs/for-ai/guides/troubleshooting.md) for schemas and failures. Verify account access using [first setup](/docs/for-ai/guides/first-setup.md), then perform only the customer's intended task. Dispatch acceptance is distinct from observed device state.\n\nCanonical component: [Exchange, refresh and revoke scoped OAuth tokens](/docs/for-ai/guides/oauth-token-lifecycle.md).\n\n## Scopes and authorization rules\n\nAuthentication establishes the principal and client. OAuth scopes bound the user's delegated authority; resource rules decide which selected resources and actions that principal may access. A scope is not an ownership or sharing grant.\n\nFor delegated REST grants, Port OS verifies token signature, expiry, issuer, REST audience, access-token type and active grant, then checks the operation's scope before existing service resource-policy evaluation. MCP tokens have a separate /mcp audience and cannot be reused on REST. A refresh token is never an API bearer credential.\n\n| Task | Scope |\n| --- | --- |\n| Enumerate or query endpoints/routes | endpoint:read |\n| Modify endpoints/routes | endpoint:write |\n| Send a device message | message:send |\n| Read groups and relationships | group:read |\n| Manage group membership | group:manage |\n| Read subscriptions | subscription:read |\n| Create/update/delete subscriptions | subscription:write |\n\nOther operations are outside the anonymous DCR device profile and fail closed. [Operation pages](/docs/for-ai/operations/index.md) expose exact credential alternatives and resource requirements. [Machine-readable authorization metadata](/docs/references/authorization.yaml) links the contract.\n\nThe existing resource engine converts principal, action, resource and entity data into Cedar requests. Default owner rules and applicable sharing/conditional rules are evaluated; only an Allow outcome admits access. The typed operation IDs come from Port OS's policy action catalog, not invented dotted action names. Owning an endpoint does not override a delegated token's missing scope.\n\nA token with endpoint:read can enumerate permitted lights but cannot dispatch a command. Adding message:send permits dispatch only to endpoints that the signed-in principal's rules allow. An authorized light does not imply camera access. A generic power-capable plug is not automatically a light. For a group request, evaluate the selected targets and report denied or unresolved members separately.\n\nAn invalid/expired/revoked token needs renewed authentication. A scope denial requires the user to approve the needed scope. A resource denial requires the owner to grant the appropriate resource/action access. Never fix denial by switching principal, requesting unrestricted credentials or retrying blindly. Provider authentication failures can require account relinking; they are different from Port OS policy denial. Keep inaccessible resource identities out of diagnostics.\n\nSee [troubleshooting](/docs/for-ai/guides/troubleshooting.md).\n\nCanonical component: [Scopes and authorization rules](/docs/for-ai/guides/authorization-rules.md).\n",
|
|
11
|
+
"content": "# Authentication and dynamic client registration\n\nAll supported agents use the same OAuth components. REST and MCP select different protected resources; DCR and CIMD select different registration methods. Neither product branding nor registration grants device access.\n\nChoose one reading path. This complete walkthrough already includes discovery, registration, consent, token lifecycle and authorization rules below; you do not need to fetch those component links again. If your connector already implements some steps, read only the missing components instead. Both paths use the same canonical instructions.\n\nFor REST, use the discovered issuer as the OAuth resource. For MCP, use the MCP protected-resource metadata. Keep that choice through authorization, exchange and refresh. If you chose the wrong transport, start a new authorization flow for the correct resource; refresh does not switch audiences.\n\nWalkthrough steps (the linked components are also included below):\n\n1. [Discover endpoints and choose REST or MCP](/docs/for-ai/guides/oauth-discovery.md).\n2. [Register with DCR or supported CIMD](/docs/for-ai/guides/oauth-client-registration.md). Remote callbacks require HTTPS; local callback registrations contain only localhost/loopback callbacks. Repeated canonical fingerprints reuse the original public client without expanding scopes.\n3. [Obtain user consent and validate the callback](/docs/for-ai/guides/oauth-consent-and-callback.md). PKCE S256 is required. Pause for the user to sign in and approve access.\n4. [Exchange, refresh and revoke tokens](/docs/for-ai/guides/oauth-token-lifecycle.md). Keep the same canonical resource through authorization, exchange and refresh.\n5. [Verify the connection](/docs/for-ai/guides/first-setup.md), then use [the REST quickstart](/docs/for-ai/guides/quickstart.md) or your client's MCP tools.\n\nRead [authorization rules](/docs/for-ai/guides/authorization-rules.md) for scopes, principal/resource policies, sharing and denial diagnosis. Never ask for a Google password, paste credentials into chat, or approve the agent's own grant. Claimed client names such as Muse and Grok remain unverified.\n\n## Discover the OAuth server and choose REST or MCP\n\nThis discovery step is shared by every client. The deployed pilot API is https://api.portoperatingsystem.lol. Fetch its /.well-known/oauth-authorization-server document anonymously. Read issuer, authorization_endpoint, token_endpoint, registration_endpoint, revocation_endpoint and scopes_supported. Use the returned endpoints exactly. An alias can advertise a different canonical Cloud Run issuer; do not substitute the alias into token audiences.\n\n| Interface | API destination | OAuth resource |\n| --- | --- | --- |\n| REST | The returned issuer, plus the documented operation path | The exact returned issuer |\n| MCP | The returned issuer plus /mcp, Streamable HTTP | The resource returned by /.well-known/oauth-protected-resource/mcp, normally issuer plus /mcp |\n\nAn MCP connector can start at https://api.portoperatingsystem.lol/mcp and follow its WWW-Authenticate resource_metadata URL. Fetch that public metadata and the authorization server it names. MCP initialization alone does not prove that the account's devices are accessible. Never use a REST token on MCP or an MCP token on REST.\n\nChoose the transport before authorizing. Omitting resource at authorization selects REST. Supply the discovered resource explicitly to select MCP. Code exchange and refresh may omit resource and inherit the grant audience; an explicit resource must stay unchanged. If a REST request fails because you authorized the MCP resource (or the reverse), obtain a new user authorization for the correct resource. Refresh cannot change the token's audience.\n\nChoose one supported [client registration method](/docs/for-ai/guides/oauth-client-registration.md), then follow the same [consent and callback steps](/docs/for-ai/guides/oauth-consent-and-callback.md). If metadata omits registration_endpoint, new DCR registration is unavailable; do not guess a replacement endpoint or silently switch to another client's credentials.\n\nSee [scopes and resource rules](/docs/for-ai/guides/authorization-rules.md). Authorization-server scopes_supported describes server vocabulary; a particular client's accepted scopes can be narrower.\n\n### Carry discovery values into every request\n\nThis JavaScript fragment initializes a REST connection. Keep `authorizationServer` and `resource` for the consent and token examples; the API alias is only the discovery starting point.\n\n```javascript\nconst response = await fetch('https://api.portoperatingsystem.lol/.well-known/oauth-authorization-server');\nif (!response.ok) throw new Error('OAuth discovery failed');\nconst authorizationServer = await response.json();\nconst resource = authorizationServer.issuer;\nconst apiBase = authorizationServer.issuer;\n```\n\nFor MCP, assign `resource` from the protected-resource metadata's `resource` field instead. Do not replace either value with the hostname you started from. A wrong `resource` can produce an `invalid_target` error callback even when client registration succeeded.\n\nCanonical component: [Discover the OAuth server and choose REST or MCP](/docs/for-ai/guides/oauth-discovery.md).\n\n## Register an OAuth client with DCR or CIMD\n\nStart with [discovery](/docs/for-ai/guides/oauth-discovery.md). DCR and CIMD identify a client; they do not sign in a user or grant device access. Both use the same [PKCE consent and callback flow](/docs/for-ai/guides/oauth-consent-and-callback.md) and [token lifecycle](/docs/for-ai/guides/oauth-token-lifecycle.md).\n\n### DCR: public clients\n\nPOST application/json to the discovered registration_endpoint:\n\n```json\n{\"client_name\":\"My device assistant\",\"redirect_uris\":[\"https://your-client.example/oauth/callback\"],\"token_endpoint_auth_method\":\"none\",\"grant_types\":[\"authorization_code\",\"refresh_token\"],\"response_types\":[\"code\"],\"scope\":\"endpoint:read message:send\"}\n```\n\nUse a callback the client controls. Remote callbacks require HTTPS. Local clients may use exact HTTP callbacks on localhost or literal loopback IPs, such as http://127.0.0.1:8765/callback. All callbacks in a registration must be local or all must be remote; these sets cannot be mixed. No fragments or user information are permitted. Start the local callback listener before authorization. The website's client-management interface enforces this same callback-set policy.\n\nSuccess is 201 with client_id, client_id_issued_at and accepted metadata. Public clients get no client_secret. Supported DCR scopes are endpoint:read, endpoint:write, message:read, message:send, group:read, group:manage, subscription:read and subscription:write. The default is endpoint:read. Request only the task's necessary scopes and check the returned scope. Broader static-client scopes are outside this anonymous profile.\n\nThe registration fingerprint is SHA-256 of compact canonical JSON with sorted object keys and sorted redirect_uris, grant_types and response_types arrays, plus client_name and token_endpoint_auth_method. Defaults are applied before hashing. Array ordering does not create another client. A matching registration returns the original client ID, issue time, scopes and descriptive metadata. It never overwrites the existing client or expands scopes, even if scope or software_id differs in the new request. Fingerprinting is deduplication, not proof of callback ownership or vendor identity.\n\nDefault quotas are 1,000 new registrations per rolling day and 10,000 retained registrations. Reuse does not consume new-registration quota. A quota failure returns 429 with Retry-After. An operator can disable new registrations without retiring existing grants. Read the [registration operation](/docs/for-ai/operations/registerDynamicOAuthClient.md) for exact request, response and error schemas.\n\n### CIMD: allowlisted metadata clients\n\nA supported CIMD client uses its allowlisted HTTPS metadata URL as client_id instead of posting a DCR request. Port OS retrieves and validates that client metadata, including its exact callbacks and public PKCE profile. Arbitrary metadata URLs and redirects from the metadata fetch are not supported. If your metadata URL is not allowlisted, arrange onboarding or use DCR if your client supports it. Do not pretend another client's metadata URL belongs to you.\n\nClient_name, software_id, software_version and client_uri remain unverified claims. No trusted software-statement issuer is configured; software_statement is rejected. A registration called Muse or Grok does not establish a verified vendor integration or gain additional permissions. Static confidential clients retain their separately configured client authentication method.\n\nCanonical component: [Register an OAuth client with DCR or CIMD](/docs/for-ai/guides/oauth-client-registration.md).\n\n## Obtain user consent and validate the OAuth callback\n\nUse the endpoints and resource from [discovery](/docs/for-ai/guides/oauth-discovery.md) and the client ID and exact callback from [registration](/docs/for-ai/guides/oauth-client-registration.md). These steps are identical for DCR and CIMD, REST and MCP; the chosen resource is the transport-specific input.\n\n`resource` is optional. Omitting it selects the canonical REST audience (the authorization-server issuer). For MCP, supply its discovered `/mcp` resource explicitly. Token exchange and refresh can omit `resource` and inherit the audience bound to the authorization code or refresh token. Explicit mismatches are rejected as `invalid_target`.\n\n1. Start the callback handler the client controls. For a loopback callback, bind its listener locally before opening authorization.\n2. Generate a cryptographically random PKCE verifier of 43–128 permitted characters. Compute code_challenge = BASE64URL(SHA256(verifier)), without padding. Generate a separate random state and retain both in this authorization attempt.\n3. Open the discovered authorization_endpoint with the following query parameters. Percent-encode parameter values; do not append raw callback URLs or scopes into an unescaped query.\n\n```text\nclient_id=<registered ID or supported CIMD metadata URL>\nredirect_uri=<exact registered callback>\nresponse_type=code\nscope=<requested subset of the client's accepted scopes>\nresource=<chosen canonical REST or MCP resource>\nstate=<random client state>\ncode_challenge=<S256 challenge>\ncode_challenge_method=S256\n```\n\nFor REST, use the `resource = authorizationServer.issuer` value retained from discovery. Construct the URL rather than writing an alias into a template. This JavaScript fragment assumes `clientId`, `redirectUri` and `acceptedScope` come from your registration response and callback configuration:\n\n```javascript\nconst base64url = bytes => btoa(String.fromCharCode(...bytes))\n .replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/, '');\nconst verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));\nconst state = base64url(crypto.getRandomValues(new Uint8Array(32)));\nconst challenge = base64url(new Uint8Array(await crypto.subtle.digest(\n 'SHA-256', new TextEncoder().encode(verifier))));\nconst authorizationURL = new URL(authorizationServer.authorization_endpoint);\nauthorizationURL.search = new URLSearchParams({\n client_id: clientId, redirect_uri: redirectUri, response_type: 'code',\n scope: acceptedScope, resource, state,\n code_challenge: challenge, code_challenge_method: 'S256',\n}).toString();\n// Retain verifier, state and authorizationServer.issuer privately until callback validation.\n// Open authorizationURL.href in the user's browser; wait for their consent.\n```\n\nThe user signs in on Port OS and reviews the requested permissions. Pause for the user; an agent must not approve its own grant, request passwords or manufacture a production sign-in identity. Local functional tests substitute an existing signed fixture identity at this boundary without changing production sign-in.\n\nAfter approval, the consent page navigates to a one-time Port OS continuation.\nThat endpoint returns HTTP 302 Found with the exact registered callback in\nLocation, carrying code, original state and iss. Denial uses the same 302 handoff\nwith access_denied instead of a code. The authenticated consent fetch returns\n200 JSON only for the intermediate continuation; it must be followed by document\nnavigation, not another fetch. Continuations expire after two minutes and are\nsingle-use. They require no login token and cannot be used to approve consent.\n\nReject a callback whose state or issuer does not match this attempt. Treat an\nerror callback as a denied or failed authorization, not a code. Codes and pending\nconsent expire after ten minutes and are single-use. Do not paste codes,\ncontinuation references or credentials into shared chat or logs. Continue with\n[code exchange and token lifecycle](/docs/for-ai/guides/oauth-token-lifecycle.md).\n\nFor hosted-client acceptance, preserve the browser network log and approve a\nfresh request. Verify the document request to /oauth/authorization-response\nreturns 302, the next GET reaches the registered client callback, and the client\nposts its code and original PKCE verifier to the discovered token endpoint.\nRepeat with Deny and verify access_denied without a code. Backend functional and\nwebsite browser tests cover these boundaries against an isolated callback;\ncompatibility with a specific hosted client still requires that live trace.\n\nCanonical component: [Obtain user consent and validate the OAuth callback](/docs/for-ai/guides/oauth-consent-and-callback.md).\n\n## Exchange, refresh and revoke scoped OAuth tokens\n\nComplete [callback validation](/docs/for-ai/guides/oauth-consent-and-callback.md) first. For a public DCR/CIMD client, POST application/x-www-form-urlencoded to the discovered token_endpoint with:\n\n```text\ngrant_type=authorization_code\nclient_id=<client ID used for authorization>\ncode=<validated callback code>\nredirect_uri=<the same exact callback>\ncode_verifier=<this attempt's original verifier>\nresource=<the same canonical resource used for authorization>\n```\n\nContinue with the same discovery values and verifier from the consent example. `code` below must be from a callback whose `state` and `iss` you validated; abort on any callback `error`:\n\n```javascript\nconst tokenResponse = await fetch(authorizationServer.token_endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code', client_id: clientId, code,\n redirect_uri: redirectUri, code_verifier: verifier, resource,\n }),\n});\nif (!tokenResponse.ok) throw new Error('OAuth code exchange failed');\nconst tokens = await tokenResponse.json(); // Store securely; do not print tokens.\n```\n\nSave access_token, refresh_token and returned scope in the connector's secure credential store. Public clients have no client secret. Use Authorization: Bearer <access_token> with REST requests or the MCP HTTP connection, according to that token's resource. A refresh token is never an API credential. [Scopes bound access; resource policies still apply](/docs/for-ai/guides/authorization-rules.md).\n\nRefresh with grant_type=refresh_token, client_id and refresh_token at token_endpoint. The resource parameter is optional for code exchange and refresh: omission inherits the existing grant audience; if supplied, it must match the original resource. Scope may stay the same or narrow; it cannot expand. Credentials rotate: store the newly returned refresh token atomically and stop using the previous one. A revoked or reused refresh token must not be retried in a loop. Reauthorize when the grant no longer permits the intended operation.\n\nRevoke by POSTing application/x-www-form-urlencoded token=<refresh_token>&client_id=<client_id> to revocation_endpoint. Revoked grants stop authorizing both access and refresh requests. Removing a local configuration file alone is not server-side revocation.\n\nRead [the token operation](/docs/for-ai/operations/generateToken.md), [revocation operation](/docs/for-ai/operations/revokeOAuthGrant.md), and [connection recovery](/docs/for-ai/guides/troubleshooting.md) for schemas and failures. Verify account access using [first setup](/docs/for-ai/guides/first-setup.md), then perform only the customer's intended task. Dispatch acceptance is distinct from observed device state.\n\nCanonical component: [Exchange, refresh and revoke scoped OAuth tokens](/docs/for-ai/guides/oauth-token-lifecycle.md).\n\n## Scopes and authorization rules\n\nAuthentication establishes the principal and client. OAuth scopes bound the user's delegated authority; resource rules decide which selected resources and actions that principal may access. A scope is not an ownership or sharing grant.\n\nFor delegated REST grants, Port OS verifies token signature, expiry, issuer, REST audience, access-token type and active grant, then checks the operation's scope before existing service resource-policy evaluation. MCP tokens have a separate /mcp audience and cannot be reused on REST. A refresh token is never an API bearer credential.\n\n| Task | Scope |\n| --- | --- |\n| Enumerate or query endpoints/routes | endpoint:read |\n| Modify endpoints/routes | endpoint:write |\n| Send a device message | message:send |\n| Read groups and relationships | group:read |\n| Manage group membership | group:manage |\n| Read subscriptions | subscription:read |\n| Create/update/delete subscriptions | subscription:write |\n\nOther operations are outside the anonymous DCR device profile and fail closed. [Operation pages](/docs/for-ai/operations/index.md) expose exact credential alternatives and resource requirements. [Machine-readable authorization metadata](/docs/references/authorization.yaml) links the contract.\n\nThe existing resource engine converts principal, action, resource and entity data into Cedar requests. Default owner rules and applicable sharing/conditional rules are evaluated; only an Allow outcome admits access. The typed operation IDs come from Port OS's policy action catalog, not invented dotted action names. Owning an endpoint does not override a delegated token's missing scope.\n\nA token with endpoint:read can enumerate permitted lights but cannot dispatch a command. Adding message:send permits dispatch only to endpoints that the signed-in principal's rules allow. An authorized light does not imply camera access. A generic power-capable plug is not automatically a light. For a group request, evaluate the selected targets and report denied or unresolved members separately.\n\nAn invalid/expired/revoked token needs renewed authentication. A scope denial requires the user to approve the needed scope. A resource denial requires the owner to grant the appropriate resource/action access. Never fix denial by switching principal, requesting unrestricted credentials or retrying blindly. Provider authentication failures can require account relinking; they are different from Port OS policy denial. Keep inaccessible resource identities out of diagnostics.\n\nSee [troubleshooting](/docs/for-ai/guides/troubleshooting.md).\n\nCanonical component: [Scopes and authorization rules](/docs/for-ai/guides/authorization-rules.md).\n",
|
|
12
12
|
"setupPrompt": null
|
|
13
13
|
},
|
|
14
14
|
{
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
{
|
|
81
81
|
"id": "oauth-consent-and-callback",
|
|
82
82
|
"title": "Obtain user consent and validate the OAuth callback",
|
|
83
|
-
"content": "# Obtain user consent and validate the OAuth callback\n\nUse the endpoints and resource from [discovery](/docs/for-ai/guides/oauth-discovery.md) and the client ID and exact callback from [registration](/docs/for-ai/guides/oauth-client-registration.md). These steps are identical for DCR and CIMD, REST and MCP; the chosen resource is the transport-specific input.\n\n`resource` is optional. Omitting it selects the canonical REST audience (the authorization-server issuer). For MCP, supply its discovered `/mcp` resource explicitly. Token exchange and refresh can omit `resource` and inherit the audience bound to the authorization code or refresh token. Explicit mismatches are rejected as `invalid_target`.\n\n1. Start the callback handler the client controls. For a loopback callback, bind its listener locally before opening authorization.\n2. Generate a cryptographically random PKCE verifier of 43–128 permitted characters. Compute code_challenge = BASE64URL(SHA256(verifier)), without padding. Generate a separate random state and retain both in this authorization attempt.\n3. Open the discovered authorization_endpoint with the following query parameters. Percent-encode parameter values; do not append raw callback URLs or scopes into an unescaped query.\n\n```text\nclient_id=<registered ID or supported CIMD metadata URL>\nredirect_uri=<exact registered callback>\nresponse_type=code\nscope=<requested subset of the client's accepted scopes>\nresource=<chosen canonical REST or MCP resource>\nstate=<random client state>\ncode_challenge=<S256 challenge>\ncode_challenge_method=S256\n```\n\nFor REST, use the `resource = authorizationServer.issuer` value retained from discovery. Construct the URL rather than writing an alias into a template. This JavaScript fragment assumes `clientId`, `redirectUri` and `acceptedScope` come from your registration response and callback configuration:\n\n```javascript\nconst base64url = bytes => btoa(String.fromCharCode(...bytes))\n .replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/, '');\nconst verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));\nconst state = base64url(crypto.getRandomValues(new Uint8Array(32)));\nconst challenge = base64url(new Uint8Array(await crypto.subtle.digest(\n 'SHA-256', new TextEncoder().encode(verifier))));\nconst authorizationURL = new URL(authorizationServer.authorization_endpoint);\nauthorizationURL.search = new URLSearchParams({\n client_id: clientId, redirect_uri: redirectUri, response_type: 'code',\n scope: acceptedScope, resource, state,\n code_challenge: challenge, code_challenge_method: 'S256',\n}).toString();\n// Retain verifier, state and authorizationServer.issuer privately until callback validation.\n// Open authorizationURL.href in the user's browser; wait for their consent.\n```\n\nThe user signs in on Port OS and reviews the requested permissions. Pause for the user; an agent must not approve its own grant, request passwords or manufacture a production sign-in identity. Local functional tests substitute an existing signed fixture identity at this boundary without changing production sign-in.\n\nAfter approval, the consent page navigates to a one-time Port OS continuation.\nThat endpoint returns HTTP
|
|
83
|
+
"content": "# Obtain user consent and validate the OAuth callback\n\nUse the endpoints and resource from [discovery](/docs/for-ai/guides/oauth-discovery.md) and the client ID and exact callback from [registration](/docs/for-ai/guides/oauth-client-registration.md). These steps are identical for DCR and CIMD, REST and MCP; the chosen resource is the transport-specific input.\n\n`resource` is optional. Omitting it selects the canonical REST audience (the authorization-server issuer). For MCP, supply its discovered `/mcp` resource explicitly. Token exchange and refresh can omit `resource` and inherit the audience bound to the authorization code or refresh token. Explicit mismatches are rejected as `invalid_target`.\n\n1. Start the callback handler the client controls. For a loopback callback, bind its listener locally before opening authorization.\n2. Generate a cryptographically random PKCE verifier of 43–128 permitted characters. Compute code_challenge = BASE64URL(SHA256(verifier)), without padding. Generate a separate random state and retain both in this authorization attempt.\n3. Open the discovered authorization_endpoint with the following query parameters. Percent-encode parameter values; do not append raw callback URLs or scopes into an unescaped query.\n\n```text\nclient_id=<registered ID or supported CIMD metadata URL>\nredirect_uri=<exact registered callback>\nresponse_type=code\nscope=<requested subset of the client's accepted scopes>\nresource=<chosen canonical REST or MCP resource>\nstate=<random client state>\ncode_challenge=<S256 challenge>\ncode_challenge_method=S256\n```\n\nFor REST, use the `resource = authorizationServer.issuer` value retained from discovery. Construct the URL rather than writing an alias into a template. This JavaScript fragment assumes `clientId`, `redirectUri` and `acceptedScope` come from your registration response and callback configuration:\n\n```javascript\nconst base64url = bytes => btoa(String.fromCharCode(...bytes))\n .replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/, '');\nconst verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));\nconst state = base64url(crypto.getRandomValues(new Uint8Array(32)));\nconst challenge = base64url(new Uint8Array(await crypto.subtle.digest(\n 'SHA-256', new TextEncoder().encode(verifier))));\nconst authorizationURL = new URL(authorizationServer.authorization_endpoint);\nauthorizationURL.search = new URLSearchParams({\n client_id: clientId, redirect_uri: redirectUri, response_type: 'code',\n scope: acceptedScope, resource, state,\n code_challenge: challenge, code_challenge_method: 'S256',\n}).toString();\n// Retain verifier, state and authorizationServer.issuer privately until callback validation.\n// Open authorizationURL.href in the user's browser; wait for their consent.\n```\n\nThe user signs in on Port OS and reviews the requested permissions. Pause for the user; an agent must not approve its own grant, request passwords or manufacture a production sign-in identity. Local functional tests substitute an existing signed fixture identity at this boundary without changing production sign-in.\n\nAfter approval, the consent page navigates to a one-time Port OS continuation.\nThat endpoint returns HTTP 302 Found with the exact registered callback in\nLocation, carrying code, original state and iss. Denial uses the same 302 handoff\nwith access_denied instead of a code. The authenticated consent fetch returns\n200 JSON only for the intermediate continuation; it must be followed by document\nnavigation, not another fetch. Continuations expire after two minutes and are\nsingle-use. They require no login token and cannot be used to approve consent.\n\nReject a callback whose state or issuer does not match this attempt. Treat an\nerror callback as a denied or failed authorization, not a code. Codes and pending\nconsent expire after ten minutes and are single-use. Do not paste codes,\ncontinuation references or credentials into shared chat or logs. Continue with\n[code exchange and token lifecycle](/docs/for-ai/guides/oauth-token-lifecycle.md).\n\nFor hosted-client acceptance, preserve the browser network log and approve a\nfresh request. Verify the document request to /oauth/authorization-response\nreturns 302, the next GET reaches the registered client callback, and the client\nposts its code and original PKCE verifier to the discovered token endpoint.\nRepeat with Deny and verify access_denied without a code. Backend functional and\nwebsite browser tests cover these boundaries against an isolated callback;\ncompatibility with a specific hosted client still requires that live trace.\n",
|
|
84
84
|
"setupPrompt": null
|
|
85
85
|
},
|
|
86
86
|
{
|
package/generated/openapi.json
CHANGED
|
@@ -7863,7 +7863,7 @@
|
|
|
7863
7863
|
}
|
|
7864
7864
|
],
|
|
7865
7865
|
"responses": {
|
|
7866
|
-
"
|
|
7866
|
+
"302": {
|
|
7867
7867
|
"description": "Navigate to sign-in and pending consent.",
|
|
7868
7868
|
"headers": {
|
|
7869
7869
|
"Location": {
|
|
@@ -7924,7 +7924,7 @@
|
|
|
7924
7924
|
},
|
|
7925
7925
|
"responses": {
|
|
7926
7926
|
"200": {
|
|
7927
|
-
"description": "One-time browser continuation URL. Navigate the browser to receive a
|
|
7927
|
+
"description": "One-time browser continuation URL. Navigate the browser to receive a 302 to the registered callback.",
|
|
7928
7928
|
"content": {
|
|
7929
7929
|
"application/json": {
|
|
7930
7930
|
"schema": {
|
|
@@ -8058,7 +8058,7 @@
|
|
|
8058
8058
|
}
|
|
8059
8059
|
],
|
|
8060
8060
|
"responses": {
|
|
8061
|
-
"
|
|
8061
|
+
"302": {
|
|
8062
8062
|
"description": "Navigate with GET to the exact registered callback.",
|
|
8063
8063
|
"headers": {
|
|
8064
8064
|
"Location": {
|
|
@@ -120,8 +120,8 @@ authorizationURL.search = new URLSearchParams({
|
|
|
120
120
|
The user signs in on Port OS and reviews the requested permissions. Pause for the user; an agent must not approve its own grant, request passwords or manufacture a production sign-in identity. Local functional tests substitute an existing signed fixture identity at this boundary without changing production sign-in.
|
|
121
121
|
|
|
122
122
|
After approval, the consent page navigates to a one-time Port OS continuation.
|
|
123
|
-
That endpoint returns HTTP
|
|
124
|
-
Location, carrying code, original state and iss. Denial uses the same
|
|
123
|
+
That endpoint returns HTTP 302 Found with the exact registered callback in
|
|
124
|
+
Location, carrying code, original state and iss. Denial uses the same 302 handoff
|
|
125
125
|
with access_denied instead of a code. The authenticated consent fetch returns
|
|
126
126
|
200 JSON only for the intermediate continuation; it must be followed by document
|
|
127
127
|
navigation, not another fetch. Continuations expire after two minutes and are
|
|
@@ -135,7 +135,7 @@ continuation references or credentials into shared chat or logs. Continue with
|
|
|
135
135
|
|
|
136
136
|
For hosted-client acceptance, preserve the browser network log and approve a
|
|
137
137
|
fresh request. Verify the document request to /oauth/authorization-response
|
|
138
|
-
returns
|
|
138
|
+
returns 302, the next GET reaches the registered client callback, and the client
|
|
139
139
|
posts its code and original PKCE verifier to the discovered token endpoint.
|
|
140
140
|
Repeat with Deny and verify access_denied without a code. Backend functional and
|
|
141
141
|
website browser tests cover these boundaries against an isolated callback;
|
|
@@ -41,8 +41,8 @@ authorizationURL.search = new URLSearchParams({
|
|
|
41
41
|
The user signs in on Port OS and reviews the requested permissions. Pause for the user; an agent must not approve its own grant, request passwords or manufacture a production sign-in identity. Local functional tests substitute an existing signed fixture identity at this boundary without changing production sign-in.
|
|
42
42
|
|
|
43
43
|
After approval, the consent page navigates to a one-time Port OS continuation.
|
|
44
|
-
That endpoint returns HTTP
|
|
45
|
-
Location, carrying code, original state and iss. Denial uses the same
|
|
44
|
+
That endpoint returns HTTP 302 Found with the exact registered callback in
|
|
45
|
+
Location, carrying code, original state and iss. Denial uses the same 302 handoff
|
|
46
46
|
with access_denied instead of a code. The authenticated consent fetch returns
|
|
47
47
|
200 JSON only for the intermediate continuation; it must be followed by document
|
|
48
48
|
navigation, not another fetch. Continuations expire after two minutes and are
|
|
@@ -56,7 +56,7 @@ continuation references or credentials into shared chat or logs. Continue with
|
|
|
56
56
|
|
|
57
57
|
For hosted-client acceptance, preserve the browser network log and approve a
|
|
58
58
|
fresh request. Verify the document request to /oauth/authorization-response
|
|
59
|
-
returns
|
|
59
|
+
returns 302, the next GET reaches the registered client callback, and the client
|
|
60
60
|
posts its code and original PKCE verifier to the discovered token endpoint.
|
|
61
61
|
Repeat with Deny and verify access_denied without a code. Backend functional and
|
|
62
62
|
website browser tests cover these boundaries against an isolated callback;
|
|
@@ -62,7 +62,7 @@ post:
|
|
|
62
62
|
responses:
|
|
63
63
|
'200':
|
|
64
64
|
description: >-
|
|
65
|
-
One-time browser continuation URL. Navigate the browser to receive a
|
|
65
|
+
One-time browser continuation URL. Navigate the browser to receive a 302 to the registered
|
|
66
66
|
callback.
|
|
67
67
|
content:
|
|
68
68
|
application/json:
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "@portpowered/reference-data",
|
|
3
3
|
"goModule": "github.com/portpowered/portos-reference-data",
|
|
4
|
-
"version": "0.4.
|
|
5
|
-
"sourceCommit": "
|
|
4
|
+
"version": "0.4.12",
|
|
5
|
+
"sourceCommit": "bedde1081f87c9ef0231e1b3ed71b2aea065d33f",
|
|
6
6
|
"sourceInputState": "committed",
|
|
7
|
-
"sourceInputSHA256": "
|
|
7
|
+
"sourceInputSHA256": "b4cb79d7b84df257a0d9d12cce3df4d3ae2acec6135b2a2c8afcb64f54c653f4",
|
|
8
8
|
"sourceInputCount": 765,
|
|
9
|
-
"assetSetSHA256": "
|
|
9
|
+
"assetSetSHA256": "fc03c3ccf4478be81463149c1aba26c1f5a9d13cd074f5a5bd108840b8882f88",
|
|
10
10
|
"files": [
|
|
11
11
|
{
|
|
12
12
|
"path": "/docs/for-ai/api-catalog.md",
|
|
@@ -1324,8 +1324,8 @@
|
|
|
1324
1324
|
{
|
|
1325
1325
|
"path": "/docs/for-ai/guides/authentication-and-dcr.md",
|
|
1326
1326
|
"contentType": "text/plain; charset=utf-8",
|
|
1327
|
-
"bytes":
|
|
1328
|
-
"sha256": "
|
|
1327
|
+
"bytes": 19247,
|
|
1328
|
+
"sha256": "9ed31b5adeb2149677cae9225b0161fb5d407161533d10293c85abda34ac7aa2",
|
|
1329
1329
|
"links": [
|
|
1330
1330
|
"/docs/for-ai/guides/authorization-rules.md",
|
|
1331
1331
|
"/docs/for-ai/guides/first-setup.md",
|
|
@@ -1499,8 +1499,8 @@
|
|
|
1499
1499
|
{
|
|
1500
1500
|
"path": "/docs/for-ai/guides/oauth-consent-and-callback.md",
|
|
1501
1501
|
"contentType": "text/plain; charset=utf-8",
|
|
1502
|
-
"bytes":
|
|
1503
|
-
"sha256": "
|
|
1502
|
+
"bytes": 4587,
|
|
1503
|
+
"sha256": "72f246a4b8972e464f2c18d9990f04f0e48c11536918b9212cbe9403e5373d8d",
|
|
1504
1504
|
"links": [
|
|
1505
1505
|
"/docs/for-ai/guides/oauth-client-registration.md",
|
|
1506
1506
|
"/docs/for-ai/guides/oauth-discovery.md",
|
|
@@ -1669,7 +1669,7 @@
|
|
|
1669
1669
|
"path": "/docs/for-ai/operations/beginOAuthAuthorization.md",
|
|
1670
1670
|
"contentType": "text/plain; charset=utf-8",
|
|
1671
1671
|
"bytes": 2967,
|
|
1672
|
-
"sha256": "
|
|
1672
|
+
"sha256": "0f40c8616f94702c3f55b29d6303480f0a9800687d2582c93484c466f2a2c642",
|
|
1673
1673
|
"links": [
|
|
1674
1674
|
"/docs/for-ai/guides/authentication-and-dcr.md",
|
|
1675
1675
|
"/docs/for-ai/schemas.md"
|
|
@@ -1679,7 +1679,7 @@
|
|
|
1679
1679
|
"path": "/docs/for-ai/operations/completeOAuthConsent.md",
|
|
1680
1680
|
"contentType": "text/plain; charset=utf-8",
|
|
1681
1681
|
"bytes": 2605,
|
|
1682
|
-
"sha256": "
|
|
1682
|
+
"sha256": "2cdf0d186c9acc781f797090c78d43defa3f6e9df1854c977557167c7b0c5042",
|
|
1683
1683
|
"links": [
|
|
1684
1684
|
"/docs/for-ai/guides/authentication-and-dcr.md",
|
|
1685
1685
|
"/docs/for-ai/schemas.md"
|
|
@@ -1963,7 +1963,7 @@
|
|
|
1963
1963
|
"path": "/docs/for-ai/operations/deliverOAuthAuthorizationResponse.md",
|
|
1964
1964
|
"contentType": "text/plain; charset=utf-8",
|
|
1965
1965
|
"bytes": 2286,
|
|
1966
|
-
"sha256": "
|
|
1966
|
+
"sha256": "0c114c53738844f2c0af3e1f7a3c21979531dae0dbb01648530981ad4c5dd46e",
|
|
1967
1967
|
"links": [
|
|
1968
1968
|
"/docs/for-ai/guides/authentication-and-dcr.md",
|
|
1969
1969
|
"/docs/for-ai/schemas.md"
|
|
@@ -7641,7 +7641,7 @@
|
|
|
7641
7641
|
"path": "/docs/references/openapi.yaml",
|
|
7642
7642
|
"contentType": "application/yaml; charset=utf-8",
|
|
7643
7643
|
"bytes": 783218,
|
|
7644
|
-
"sha256": "
|
|
7644
|
+
"sha256": "952f0da29e1461c83068444b190332d9881e07c7db3525c8d22e1469a8df01f0",
|
|
7645
7645
|
"links": []
|
|
7646
7646
|
},
|
|
7647
7647
|
{
|
|
@@ -5698,7 +5698,7 @@ paths:
|
|
|
5698
5698
|
enum:
|
|
5699
5699
|
- S256
|
|
5700
5700
|
responses:
|
|
5701
|
-
'
|
|
5701
|
+
'302':
|
|
5702
5702
|
description: Navigate to sign-in and pending consent.
|
|
5703
5703
|
headers:
|
|
5704
5704
|
Location:
|
|
@@ -5745,7 +5745,7 @@ paths:
|
|
|
5745
5745
|
responses:
|
|
5746
5746
|
'200':
|
|
5747
5747
|
description: >-
|
|
5748
|
-
One-time browser continuation URL. Navigate the browser to receive a
|
|
5748
|
+
One-time browser continuation URL. Navigate the browser to receive a 302 to the
|
|
5749
5749
|
registered callback.
|
|
5750
5750
|
content:
|
|
5751
5751
|
application/json:
|
|
@@ -5845,7 +5845,7 @@ paths:
|
|
|
5845
5845
|
schema:
|
|
5846
5846
|
type: string
|
|
5847
5847
|
responses:
|
|
5848
|
-
'
|
|
5848
|
+
'302':
|
|
5849
5849
|
description: Navigate with GET to the exact registered callback.
|
|
5850
5850
|
headers:
|
|
5851
5851
|
Location:
|