Choosing Between Static and OIDC‑Derived RBAC Roles in Teleport
Guide to choosing Teleport's RBAC source: static local roles vs OIDC/JWT‑derived roles, with a comparison table, trade‑offs, and step‑by‑step OIDC setup.
19 Mar 2026, 12:22 UTC

Decision and Constraints
Teleport can enforce access policies either through role definitions stored locally in its configuration (YAML or database) or by consuming roles from an external OIDC identity provider via JWT claims. The decision must satisfy three main constraints:
- Auditability: How easily can changes be traced and reviewed?
- Change frequency: Do roles need to be updated rarely, often, or in real‑time?
- Integration requirements: Is there already an IdP in place that can issue tokens with the needed claims?
Supported Options (Compact Comparison)
| Option | Where roles are defined | Update latency | Admin overhead | Typical use case |
|---|---|---|---|---|
| Static local roles | Teleport YAML/DB | Immediate on config reload | Low (manual edits) | Infrequent, stable role sets |
| Dynamic OIDC/JWT roles | External IdP (Azure AD, Okta, etc.) | Token expiry (5‑15 min) | Medium (IdP claim mapping) | Frequent changes, just‑in‑time provisioning, federated SSO |
| Hybrid (static fallback) | Both local YAML and IdP | Static immediate; dynamic per token | Medium‑high (maintain both) | Baseline access plus IdP‑driven adjustments |
Trade‑offs
- Static roles give instant, auditable changes and avoid reliance on network‑dependent IdP, but require manual updates and risk drift if the source of truth diverges.
- OIDC/JWT roles enable automated, just‑in‑time provisioning and central IdP governance, yet introduce token‑validation latency, potential mis‑configuration of claim mapping, and a dependency on IdP availability.
- Hybrid provides a safety net of static baseline roles while allowing IdP‑driven adjustments, at the cost of higher operational complexity.
Enabling Dynamic OIDC Roles – Implementation
Add the OIDC block to
teleport.yamlunder theauth_servicesection. Replace placeholders with your actual values:auth_service: oidc: client_id: "teleport" client_secret: "{{OIDC_CLIENT_SECRET}}" issuer_url: "https://{{YOUR_IDP_DOMAIN}}/" scopes: - "openid" - "profile" - "email" role_claim: "teleport_roles" # JWT claim containing a comma‑separated list of role namesReload Teleport to apply the new configuration:
# Requires root or teleport service user privileges systemctl reload teleport # or: teleport start --config=/etc/teleport/teleport.yamlObtain an OIDC token for a test user:
tctl login --auth=oidc --username={{TEST_USER}} --password={{TEST_PASSWORD}}This command opens a browser flow; after successful authentication Teleport stores the token locally.
Verify that the role derived from the JWT claim is loaded:
# Replace with the value you expect from the IdP claim tctl get role --nameThe output should show the role definition (permissions, allowed logins, etc.). If the role is not found, the claim mapping or
role_claimvalue is likely incorrect.Validate permissions by attempting an SSH session to a node that should be accessible only via the dynamically assigned role:
ssh {{TEST_USER}}@{{NODE_ADDRESS}}A successful login confirms the dynamic role was applied. Failure indicates a mis‑map, missing scope, or IdP token issue.
Rollback (if the OIDC configuration causes issues)
Remove or comment out the entire
oidc:block fromteleport.yaml.Reload Teleport again:
systemctl reload teleportConfirm that Teleport falls back to static local roles by running
tctl statusand checking that the auth service no longer reports an OIDC provider.
Limitations and Practical Verification
- Version requirement: OIDC role mapping was introduced in Teleport 4.2. Older releases will ignore the
role_claimsetting and rely solely on local roles. - Non‑production testing: Always validate the OIDC flow in a staging environment first. Mis‑aligned
role_claimvalues or missing scopes can result in users receiving no roles, leading to lock‑out. - Verification steps:
- After reload, run
tctl status; the output should include a line likeOIDC provider: connected. - List loaded roles from the token with
tctl get roles --format=jsonand compare against the IdP claim. - Perform a login (
tctl login --auth=oidc) and inspect the user object viatctl get users --format=jsonto see the associated roles.
- After reload, run
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.