Register the application
Apply the database migration and build the frontend when deploying this feature:--redirect-uri to register more
callbacks; omitting --scope permits both supported scopes. Callbacks require
HTTPS and cannot contain fragments, credentials or reserved response parameters.
In local or testing, HTTP callbacks on .test or loopback hosts are also
accepted. URL matching is exact, including path and query string. HTTP loopback callbacks
accept variable ports as required by RFC 8252.
For the Herd project AskMyDocsDev, the authorization-server base URL is
https://askmydocsdev.test. Use APP_URL for other deployments. No OAuth
provider credentials are needed on AskMyDocs.
Implement the connect button
Generate a new verifier and state for each connection attempt. Keep both in the external application’s server-side session, associated with the signed-in user. A backend route handling the button can use Node’s built-in crypto:Handle the callback and obtain the API key
AskMyDocs redirects to the registered callback withcode, the original
state, and iss. On cancellation it returns error=access_denied, state
and iss. The API key is returned only by the token endpoint, never in the
browser’s callback URL.
The external backend must verify state against the saved session and verify
iss against the expected AskMyDocs base URL before using the code. Consume
the saved connection attempt once and handle error before exchanging:
Cache-Control: no-store and Referrer-Policy: no-referrer; consent pages cannot be embedded in a frame.
Call the service
SendAuthorization: Bearer <access_token>. The company is resolved from the
key automatically. If you also send X-Tenant-Id, it must match the authorised
company. A key cannot switch companies, even when the user belongs to both.
Document ACLs, project memberships, lifecycle checks and the user’s existing
permissions continue to apply. OAuth keys cannot access administrative,
ingestion, account-management or consent endpoints, including keys granted by
an administrator. An unavailable scope or disallowed route fails authentication
with
401. Use /oauth/userinfo for the authorised account/company; first-party
/api/auth/me is intentionally outside this external API surface.
Disconnect and operate
Users can revoke individual connections at/oauth/connections, also linked
from the application’s Connected Apps page. This screen is session-only and
shows only the current user’s connections across companies.
An external backend can revoke its own key with POST /oauth/revoke:
200 even for an unknown, already revoked or mismatched
token, without revoking a different application’s key. The operator can disable
an entire application and revoke all its keys:
oauth:prune to delete expired or consumed codes; the command is also available
manually. Sanctum’s normal token pruning removes expired keys and their OAuth
metadata through the database foreign key.
Discovery metadata is available at /.well-known/oauth-authorization-server.
Both public backchannel POST endpoints are rate-limited to 30 requests per
minute per IP. Browser consent submissions use Laravel’s session and request
forgery protection. Third-party browsers use top-level navigation for consent;
the token exchange is a server-to-server call and needs no cross-origin cookies.
The protocol checks follow OAuth security BCP (RFC 9700),
PKCE (RFC 7636) and
token revocation (RFC 7009).