Skip to main content

Protocol Mappers

Protocol mappers tell Keycloak to include custom user attributes as claims in the OAuth tokens. Without them, Keycloak tokens only contain standard claims (email, name, sub). Odoo reads these custom claims to determine which dealerships a user can access, their employee ID, region, and department.


Where to find them

Protocol mappers live under a client's dedicated scope. Navigate to:

Clients > portal-odoo > Client scopes tab > portal-odoo-dedicated

Protocol mappers list

The portal-odoo-dedicated scope shows all 5 custom mappers:

NameCategoryTypePurpose
employee_idToken mapperUser AttributeUAAGI employee ID
regionToken mapperUser AttributeUser's assigned region
allowed_dealershipsToken mapperUser AttributeDealerships the user can access (multivalued)
primary_dealershipToken mapperUser AttributeUser's default dealership
departmentToken mapperUser AttributeUser's department

All mappers share the same type: User Attribute — meaning they read a value from the user's attribute list and inject it into the token.


Creating a mapper

  1. Click Add mapper > By configuration > User Attribute.
  2. Fill in the form fields as described below.
  3. Click Save.

Mapper detail: allowed_dealerships

Click any mapper name to see its full configuration. Here is the allowed_dealerships mapper as an example:

Mapper detail — allowed_dealerships (top)

Mapper detail — allowed_dealerships (bottom)

Field reference

FieldValueDescription
Mapper typeUser AttributeRead-only — set when creating the mapper
Nameallowed_dealershipsDisplay name in the mapper list
User Attributeallowed_dealershipsThe key to read from the user's Attributes tab in Keycloak
Token Claim Nameallowed_dealershipsThe claim name that appears in the JWT token and userinfo response
Claim JSON TypeStringData type of the claim value
Add to ID tokenOnInclude in the ID token (used for logout id_token_hint)
Add to access tokenOnInclude in the access token
Add to lightweight access tokenOffNot needed
Add to userinfoOnInclude in the /userinfo endpoint response — this is what Odoo reads
Add to token introspectionOnInclude in introspection responses
MultivaluedOnA user can access multiple dealerships — values are returned as a JSON array
Aggregate attribute valuesOffNot needed

:::warning Multivalued is critical for allowed_dealerships With Multivalued: On, the claim is returned as a JSON array (["makati-dealership", "cebu-dealership"]). If this is Off, only the first value would be returned and the user would see only one dealership. :::


All 5 mappers — configuration summary

Each mapper follows the same pattern. The only differences are the Name/User Attribute/Token Claim Name (which always match each other) and the Multivalued flag.

MapperUser AttributeClaim NameMultivalued
allowed_dealershipsallowed_dealershipsallowed_dealershipsOn
primary_dealershipprimary_dealershipprimary_dealershipOff
employee_idemployee_idemployee_idOff
regionregionregionOff
departmentdepartmentdepartmentOff

All other toggles are the same across all 5 mappers:

ToggleValue
Add to ID tokenOn
Add to access tokenOn
Add to lightweight access tokenOff
Add to userinfoOn
Add to token introspectionOn
Claim JSON TypeString

Dedicated vs. default scopes

These mappers are on the dedicated scope (portal-odoo-dedicated), which means they only apply to tokens issued for the portal-odoo client.

If you want the same claims available on dealership clients too (e.g. bacolod-dealership), you have two options:

  1. Add the same mappers to each dealership client's dedicated scope — more work, but gives per-client control.
  2. Create a shared client scope (e.g. uaagi-dealership-claims) with these mappers and add it as a default scope to all clients — recommended for consistency.
tip

For most setups, dealership clients don't need these custom mappers because the portal handles dealership assignment. The dealership instance only needs standard OIDC claims (email, name, sub) to identify the user.


How it all connects

User Attributes (Keycloak) Protocol Mappers Token Claims Odoo Fields
────────────────────────── ──────────────── ──────────── ───────────
allowed_dealerships → allowed_dealerships → allowed_dealerships → allowed_dealership_ids
primary_dealership → primary_dealership → primary_dealership → primary_dealership_id
employee_id → employee_id → employee_id → employee_id_uaagi
region → region → region → region
department → department → department → department
  1. Sysadmin sets user attributes in Keycloak (see User Management)
  2. Protocol mappers inject those attributes into the OAuth token on login
  3. Odoo reads the claims from the userinfo response and updates user fields (see Odoo Configuration)

What's next