Sign in with Swum
Sign in with Swum
An agent requests a connection; the school owner chooses the access in Swum’s server-backed consent page.
How it works
- Discover metadata and register the client.
- Generate an S256 PKCE verifier/challenge and unpredictable state. Send the owner to the API origin’s authorize endpoint.
- The server records a ten-minute authorization request and redirects to the app at
/oauth/authorize?request=REQUEST_ID. - The app loads the client identity and requested scopes from that server record. Query parameters cannot supply a trusted client name, owner or redirect.
- The owner picks locations and Read Only, Ask Me First or Can Act. Only the owner may approve; staff mode is refused.
- The exact registered callback receives code, state and iss. Verify state and the expected issuer, then exchange the code within 60 seconds.
Discovery
Read /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource from the deployment’s API origin. An unauthenticated MCP call returns 401 with WWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource".
The exact resource is https://api.swum.ai/mcp in production, or the DEV deployment’s base plus /mcp. Use that same resource in authorization and token requests.
Register your client
POST JSON to /oauth/register with client_name, redirect_uris and optional token_endpoint_auth_method: none. There is no client secret. Register 1–5 HTTPS redirect URIs; HTTP is allowed only on loopback hosts. Redirects cannot contain credentials or fragments, and authorization requires an exact registered URI.
Use Dynamic Client Registration (DCR) for the setup steps in this guide. New dynamic registrations are unverified. Public registration has a separate IP rate limit; unused registrations without connections may be removed after seven days.
Public-client metadata documents are also supported when the document declares token_endpoint_auth_method: none: send an https URL serving your metadata as client_id. Swum fetches it from a public HTTPS address and verifies the exact client URL and registered redirect. This does not establish compatibility with a provider's published identity that requires private_key_jwt; choose DCR for the documented flow.
Apps using a registered confidential client, such as Gemini Enterprise and Microsoft Copilot Studio, use a connector the school owner makes in Settings → Developers & Integrations → Apps: a client ID and a secret shown once. They authenticate at /oauth/token and /oauth/revoke with client_secret_basic or client_secret_post. For them PKCE and state are optional (still checked when sent), and resource defaults to the MCP server. Only the owner who made a connector can allow it, and deleting it disconnects every agent that used it.
Ask the owner
Start at the API authorize endpoint, not directly at the app consent page. Public clients must send response_type=code, client_id, exact redirect_uri, state, S256 PKCE and resource. Ask only for needed area scopes. The owner can reduce access and cannot grant more than requested. Reports is read-only; supported payment writes require the owner's approval inside Swum. Existing connections do not automatically gain newly available areas: reconnect and review the requested grant when expanding access.
https://api.swum.ai/oauth/authorize
?response_type=code
&client_id=YOUR_REGISTERED_CLIENT_ID
&redirect_uri=https%3A%2F%2Fagent.example.test%2Fcallback
&scope=families%3Aread%20lessons%3Awrite
&resource=https%3A%2F%2Fapi.swum.ai%2Fmcp
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256
&state=YOUR_UNPREDICTABLE_STATETokens
Authorization codes last 60 seconds and are consumed once in a transaction. Access tokens are opaque bearer strings lasting one hour; refresh tokens last 30 days and rotate on every refresh. They are bound to client, owner, connection, resource, scopes and locations.
curl https://api.swum.ai/oauth/token \
-d grant_type=authorization_code \
-d client_id=YOUR_REGISTERED_CLIENT_ID \
-d code=YOUR_SINGLE_USE_CODE \
--data-urlencode redirect_uri=https://agent.example.test/callback \
--data-urlencode resource=https://api.swum.ai/mcp \
-d code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXkPersist the replacement refresh token atomically before another refresh. Reusing a consumed refresh token revokes the entire connection. Coordinate refreshes in one worker so concurrent clients do not accidentally trigger reuse protection. A token never gains broader scopes or locations than its issued grant; owner downgrades take effect immediately.
Disconnect
The owner can disconnect in the app. To revoke from the agent, POST client_id (plus the secret, for a connector) and an issued access or refresh token to /oauth/revoke. Revocation closes the connection, so its other tokens stop working too.