Skip to content

[Enh]: Add rolesPath and rolesFormat under JWT for custom roles claim extraction #3078

@JerryNixon

Description

@JerryNixon

What?

Add new properties under authentication.jwt so developers can specify their JWT's roles property:

Config Example:

"authentication": {
  "provider": "Custom",
  "jwt": {
    "rolesPath": "roles",         // new, string (can use dots: e.g., "realm_access.roles" or a namespaced claim like "https://example.com/roles")
    "rolesFormat": "array"         // new: "array" (default), "string", "space-delimited"
  }
}

Why?

Developers today must rewrite or remap their JWTs to match our hardcoded requirement for roles as an array under roles. For many, this JWT surgery is a blocker. Many providers (Auth0, Okta, Keycloak, etc.) emit roles/groups in different formats and property names.

Current requirement:

{
  "roles": ["Admins", "ReportWriters"]
}

Common provider formats:

  • Auth0 namespaced array: { "https://example.com/roles": ["admin", "writer"] }
  • Auth0 scope string: { "scope": "openid profile email read:orders" }
  • Okta groups array: { "groups": ["Admins", "ReportWriters"] }
  • Okta nested: { "claims": { "app": { "roles": ["admin", "auditor"] }}}
  • Keycloak realm roles: { "realm_access": { "roles": ["editor", "contributor"] }}

This enhancement allows developers to use their JWT as issued and configure Data API Builder to interpret the appropriate property/format easily.

How?

  • rolesPath: (optional, default roles) String. Use dot notation (e.g., claims.app.roles) to traverse objects, or provide a literal key (e.g., groups or https://example.com/roles).

    • If the claim is not present in the JWT, authorization fails with a clear error/log.
    • Paths ( claims.roles) and namespaces ( https://example.com/roles) both have . dots which means we must explicitly support namespaces by looking for https:// or http:// in the string prefix before inferring path operations by the presence of a . dot.
    • We will not support escaping for literal . dots in claim names.
  • rolesFormat: (optional, enum: array [default], string, space-delimited).

    • array: claim must be an array of strings (["admin","writer"])
    • string: claim is a string, treat as a single role ("admin")
    • space-delimited: claim is a string, split on whitespace into roles ("admin writer" => ["admin","writer"]). If no whitespace, yield a single role as array.
    • Objects/numbers/booleans as a role value: always error.

Command Line

  • dab configure --runtime.host.authentication.jwt.rolesPath
  • dab configure --runtime.host.authentication.jwt.rolesFormat

Notes

  • rolesPath can be a dot path or a literal key. Dot navigation only works on nested objects. Namespaced claims with special characters (like URLs) are treated as literal key names.
  • No support for roles encoded as objects; only arrays or strings.
  • If claim is missing or value is wrong type, request fails with clear reason.
  • Designed to reduce user friction for common provider defaults and custom JWT layouts.

Implementation

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions