Auth0
This guide configures a Podium registry to authenticate against Auth0. Setup takes about 15 minutes. Group claims are not native to Auth0; an Action adds them, or a legacy Rule does.
Prerequisites
- Auth0 tenant with admin access.
- Podium registry running and reachable from developers’ browsers.
- Decide your audience identifier (suggestion:
https://podium.acme.com; Auth0 conventionally uses URL-shaped audiences).
1. Create the API in Auth0
Auth0 dashboard: Applications → APIs → Create API.
- Name: Podium.
- Identifier:
https://podium.acme.com(this is theaudience). - Signing Algorithm: RS256.
Save. The API is now what tokens are issued for.
2. Create the application
Dashboard: Applications → Applications → Create Application.
- Name: Podium CLI.
- Type: Native (best fit for the device-code flow).
In the new application’s settings:
- Token Endpoint Authentication Method: None (public client).
- Grant Types: enable Device Code and Refresh Token.
- Save.
Note from the app’s settings tab: Client ID.
Connect the application to the API:
- APIs tab in the application → toggle Authorized for the Podium API.
- Permissions: leave default. Podium uses identity claims rather than Auth0-issued permissions.
3. Add the groups claim via an Action
Dashboard: Actions → Library → Build Custom.
- Name: Add groups to access token.
- Trigger: Login / Post Login.
Action code:
exports.onExecutePostLogin = async (event, api) => {
const namespace = "https://podium.acme.com/";
const groups = (event.user.app_metadata && event.user.app_metadata.groups) || [];
api.idToken.setCustomClaim(`${namespace}groups`, groups);
api.accessToken.setCustomClaim(`${namespace}groups`, groups);
};
Save and deploy. Then attach the Action: Actions → Triggers → post-login → drag the new Action into the flow → Apply.
This reads the user’s groups from app_metadata. Populate app_metadata through your provisioning process: manually for small teams, or via SCIM for larger setups. The claim emitted is namespaced (https://podium.acme.com/groups) because Auth0 disallows non-namespaced custom claims.
4. Configure Podium
Registry side (registry.yaml):
identity_provider:
type: oauth-device-code
audience: https://podium.acme.com
authorization_endpoint: https://<your-tenant>.auth0.com
The registry reads the namespaced group claim (https://podium.acme.com/groups) and maps its values to group names through the IdpGroupMapping adapter configured registry-side. Configure the adapter to read the namespaced claim path that the Action emits. Restart the registry.
Developer side:
podium init --global --registry https://podium.acme.com
export PODIUM_OAUTH_CLIENT_ID=<client-id>
export PODIUM_OAUTH_AUDIENCE=https://podium.acme.com
export PODIUM_OAUTH_AUTHORIZATION_ENDPOINT=https://<your-tenant>.auth0.com/oauth/device/code
podium login
The device-flow verification URL is https://<your-tenant>.auth0.com/activate. After completion, podium login prints the resolved identity.
5. Populate user groups
For small teams, edit app_metadata per user manually:
{
"groups": ["engineering", "platform"]
}
(Dashboard: User Management → Users → [user] → Metadata → app_metadata.)
For larger setups, populate via SCIM (Auth0 Enterprise) or via a directory sync script.
6. Test
Configure an admin layer scoped to a group in the tenant’s layer config. Group-scoped visibility is set in the registry layer config, or with podium layer register --group <name> (also --public, --organization, and --user). Layers registered with --user-defined are private to the registrant and cannot be widened.
layers:
- id: engineering-only
source:
git:
repo: git@github.com:acme/podium-engineering.git
ref: main
visibility:
groups: [engineering]
A user with engineering in app_metadata.groups sees the layer; a user without it does not.
Troubleshooting
- Groups claim is missing from the token. The Action was not attached to the post-login trigger, or the user has no
groupsinapp_metadata. Check the Action’s logs: Actions → Library → [Action] → Logs. - Token rejected. The token’s
audmust match the registry’saudience:. Confirm the API identifier andaudience:match exactly. - Custom claim namespace error. Auth0 rejects non-namespaced custom claims. The claim must look like
https://your-namespace/groups. A baregroupsis rejected. ConfigureIdpGroupMappingto read the namespaced claim path.