Learn Authentik - Property Mappings & Claims
Episode 9 of 31

Learn Authentik - Property Mappings & Claims

Understanding property mappings in Authentik: the Python expressions that determine OIDC claim contents, built-in mappings for profile, email, and groups, custom scope mappings, and how to debug mappings with the tester and token preview.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 8, you successfully issued tokens through the OAuth2 provider. But the token is like an empty suitcase: all the user's identity is already available in Authentik, yet nothing has decided what goes inside.

That decision is in the hands of property mappings. To use an analogy: the token is the suitcase, and the property mapping is the courier choosing which items may be carried out. Applications can only read the data sent to them — so understanding mappings is how you control what each application sees, and what leaks out.

What Is a Property Mapping

A property mapping is a Python expression that returns a value to be sent to an application. The mapping type depends on the provider:

  • Scope mapping: for OAuth2/OIDC providers. The returned value is added as a custom claim to the ID token and access token.
  • SAML property mapping: fills the attribute statements of a SAML assertion.
  • LDAP property mapping: maps user attributes to the format expected by an LDAP client.

There's one important rule: returning None means the mapping is skipped — its value doesn't appear at all. The context available in expressions generally includes user, request, and provider (for scope mappings), plus the same helpers as in episode 6: regex_match, regex_replace, and ak_is_group_member.

Built-in Mappings That Already Exist

Authentik ships several standard scope mappings you can use right away:

  • OpenID Profile: username, name, and basic profile information.
  • OpenID Email: the email address along with its verification status.
  • OpenID Groups: the list of groups the user belongs to.

The profile scope on an OAuth2 provider points to the profile mapping, the email scope points to the email mapping, and so on. So when an application requests a scope, this is the content that automatically comes along.

Important

Since release 2025.10, the email_verified claim defaults to False. Authentik can't verify on its own whether a user's email is truly verified, and claiming otherwise could create a security risk. Some applications refuse login when this claim is False — the solution is a custom mapping, not just changing the default.

The Common Shape of a Mapping Expression

A scope mapping usually returns a dictionary. Each key-value pair becomes a claim in the token. The simplest example: a custom mapping that sends the user's group list.

PythonCustom scope mapping: user group list
return {
    "groups": [group.name for group in request.user.ak_groups.all()],
}

The ak_groups.all() relation fetches all groups the user is a member of, then the list comprehension collects their names. As a result, the token contains a groups claim with a list like ["dev", "ops"] that applications can use to assign roles.

Creating a Custom Scope Mapping

To create your own mapping: go to Customization > Property Mappings, click Create, then choose the Scope Mapping type. There are three important fields: the name, the scope it will fill, and the expression.

A classic example that's often needed: fixing the email claim so email_verified follows the status you store as a user attribute.

PythonScope mapping: email with verification status
return {
    "email": request.user.email,
    "email_verified": request.user.attributes.get("email_verified", False),
}

Or pulling the custom attributes you set in episode 5:

PythonScope mapping: custom user attributes
return {
    "department": request.user.attributes.get("department", "unknown"),
}

Tip

Use .get(key, default) to read custom attributes. Accessing a non-existent attribute directly triggers an error like KeyError, and a single error in a mapping can fail the entire token issuance.

Scope vs Claim: A Distinction Often Reversed

Scope and claim are two different things that are related:

  • Scope is the permission package the client requests: openid, profile, email, or a custom scope you create.
  • Claim is the content actually returned in the token, determined by property mappings.

An application requesting the profile scope receives claims from the mapping bound to that scope. If you create a custom scope named roles with a mapping that returns a role list, the application must request the roles scope for its claims to appear. Unconfigured requested scopes are rejected — and this is one of the integration error sources you'll encounter in episode 10.

Also keep in mind: if a client doesn't request any scope, Authentik treats all default scopes as requested (the lesson from episode 8). Custom scopes aren't part of that behavior.

Using Mappings in OIDC Tokens

Once a mapping is created, add it to the OAuth2 provider in the scope mappings section. The full flow:

  1. Create a custom scope mapping, for example with the scope roles.
  2. Add it to the provider's scope mappings list.
  3. Make sure the application requests the roles scope when initializing its OIDC client.
  4. Verify the token: claims from the mapping must appear in the ID token and access token.

For stricter scope-based authorization decisions, episode 6 also provides a tool: an expression policy can check requested scopes via a dedicated context — for example, denying an admin scope unless the user is a member of a specific group.

Debugging Mappings

Mappings are code — so they can error, and debugging them needs the right tools:

  • Property mapping tester: run the expression against a sample user directly from the interface, without needing a login flow. This is the first tool to use.
  • Execution logging: enable execution logging on the mapping to see the context and result in the logs.
  • Token preview and jwt.io: once a token is issued, decode and inspect the claims that appear — compare them to what you expect.
  • Event logs: Python errors during mapping execution are recorded here complete with a traceback.

Warning

Never put sensitive information like password hashes, secret tokens, or excessive personal data into claims. Claims that go into tokens are read by applications and can leak through that application's logs. Send only what's actually needed.

Closing

Key points from this episode:

  • A property mapping is a Python expression that determines the claim contents for OIDC scope mappings, SAML, and LDAP.
  • Built-in mappings cover profile, email, and groups; email_verified defaults to False.
  • Custom scope mappings return a dictionary that becomes claims, for example group lists or user attributes.
  • Scope is the requested permission, claim is the returned content; applications must request a scope for its claims to appear.
  • Use the property mapping tester and token preview for debugging before integration.

Now the token suitcase is filled exactly as you want. All that's left is practicing it on real applications. In episode 10, you'll integrate Grafana, Nextcloud, Portainer, and Gitea with Authentik's OIDC — complete with a login flow walkthrough and troubleshooting the errors that most often make admins scratch their heads.

Learn Authentik - Property Mappings & Claims | Learning Authentik