Auth0
Auth0 is the recommended SaaS IdP for swsrs. It has a generous free tier and supports everything we need: Custom APIs with arbitrary scopes, OIDC discovery, and device flow.
The Auth0 vocabulary doesn't match Keycloak's, so the mapping is:
| swsrs concept | Auth0 concept |
|---|---|
| Resource server / audience | Custom API (its "Identifier") |
Scope (swsrs:session:create) | Permission on the Custom API |
| OAuth client | Application (Native type for device flow) |
1. Create a Custom API in Auth0
This is the resource server that represents swsrs.
- Auth0 Dashboard → APIs → + Create API
- Name:
swsrs - Identifier:
swsrs(or a stable URN — this becomes theaudclaim and theSWSRS_OIDC_AUDIENCEvalue; change it once and never again, Auth0 won't let you edit it later) - Signing algorithm:
RS256 - Create
On the resulting API page:
- Settings → Allow Offline Access: on (so refresh tokens work)
- Permissions tab → add three permissions:
swsrs:session:create— "Create sessions"swsrs:session:read— "Read sessions"swsrs:session:delete— "Delete sessions"
2. Create a Native Application for end-user clients
Public OAuth client, used by swsrs auth and the SDKs.
- Applications → + Create Application
- Name:
swsrs CLI - Application Type: Native (required for device flow without a client secret)
- Create
On the application's Settings:
- Token Endpoint Authentication Method:
None(it's a public client) - Grant Types (under Advanced Settings → Grant Types):
- Enable:
Device Code,Refresh Token - Disable everything else unless you need it for other purposes.
- Enable:
- Save changes
Copy the Client ID from the top — that's your SWSRS_OIDC_CLIENT_ID.
3. Authorize the application to call the API
- Applications → swsrs CLI → APIs tab
- Toggle Authorized for the
swsrsAPI. - Expand it and check the permissions you want the client to be able to request (typically all three).
Important nuance: enabling a permission here lets the client ask for it. Whether a specific user actually gets it on their token is governed by role assignments (next step) plus your RBAC settings.
4. Enable RBAC + permissions on the API
Back on APIs → swsrs → Settings:
- RBAC Settings:
- Enable RBAC: on
- Add Permissions in the Access Token: on (this is what makes scopes appear in the
scopeclaim that swsrs reads)
5. Create roles for scope mapping
- User Management → Roles → + Create Role
- Name:
swsrs-operator(orswsrs-creatorfor the narrow role)
- Name:
- Permissions tab on the role → Add Permissions
- Select the
swsrsAPI and the permissions this role should grant.
- Select the
- User Management → Users → <user> → Roles → Assign Roles — assign the role to each user that should be able to mint sessions.
For most apps you'll grant only swsrs:session:create to your users.
6. Configure the relay
Auth0's issuer URL is https://<your-tenant>.<region>.auth0.com/ (trailing slash required — Auth0 is picky about it):
SWSRS_OIDC_ISSUER=https://your-tenant.us.auth0.com/ \
SWSRS_OIDC_AUDIENCE=swsrs \
SWSRS_OIDC_CLIENT_ID=<the Client ID from step 2> \
swsrs serve7. Smoke test
# Discovery should now return Auth0's endpoints
curl -s https://relay.example.com/.well-known/swsrs-config | jq
# Run device flow
swsrs auth --relay https://relay.example.com
# Create a session
swsrs create --admin-url https://relay.example.comTroubleshooting
| Symptom | Likely cause |
|---|---|
audience claim ... not valid | Token was issued for Auth0's userinfo endpoint, not for your API. Make sure your client code requests audience=swsrs (the SDK does this automatically when SWSRS_OIDC_CLIENT_ID is set and discovery surfaces the audience). |
403 missing required scope: swsrs:session:create | RBAC is off, OR the user doesn't have the role with that permission, OR "Add Permissions in the Access Token" is off (step 4). |
Discovery returns empty device_authorization_endpoint | Auth0 always advertises this; if it's empty, your relay couldn't reach the tenant. Check egress firewall. |
swsrs auth says "not authorized for grant_type:device_code" | Step 2.6 wasn't completed — device code grant isn't enabled on the application. |
swsrs auth hangs on poll forever | User closed the browser tab without completing the consent. Re-run. |