auditing-jit-provisioning-and-role-mapping · git:20260903.19a7174 · 2026-09-03 · sha256 f5122f2feaf21755

auditing-jit-provisioning-and-role-mapping git:20260903.19a7174A

Immutable. This exact content is served forever at /api/v1/blob/f5122f2feaf21755.

---
name: auditing-jit-provisioning-and-role-mapping
description: >-
  Audit just-in-time account provisioning at federated (SAML or OIDC) login for trust misplaced in the assertion
  that drives it: a first login that creates an account and assigns roles from identity-provider claims (groups,
  email domain, department) the service never validates, a claim-to-role mapping that grants more privilege than
  the claim should or defaults new users into a privileged role, an email or domain claim trusted to auto-join a
  tenant so an attacker with a lookalike address lands inside it, and a JIT update that re-elevates an account on
  every login from mutable claims. Use when a federated login provisions an account and the mapping from
  assertion claims to local roles and tenancy is the boundary. The attacker-shaped login assertion is the
  source, the over-privileged or wrong-tenant provisioned account is the sink, and the unvalidated claim or
  over-granting role mapping is the bug.
license: MIT
---

# Auditing JIT provisioning and role mapping: the first login decides the role, from claims you did not issue

Just-in-time provisioning creates a local account the first time someone logs in through a federated identity
provider, and often updates that account's roles on every subsequent login, all from the claims in the login
assertion. The claims, group memberships, an email, a domain, a department, come from the identity provider,
not from you, so JIT hands account creation and role assignment to whatever the assertion says. That is fine
when the mapping is tight and the claims are validated, and dangerous when either is loose. A claim-to-role
mapping that grants more privilege than the claim should, or defaults every new user into a privileged role,
elevates at first login. An email or domain claim trusted to auto-join a tenant or organization lets an
attacker with a lookalike or attacker-controlled address land inside it. A JIT update that re-reads mutable
claims every login can re-elevate or reassign an account an admin previously corrected. And any claim provisioned
without validation, an unverified email, a group the attacker can influence, an unsigned or overtrusted
assertion field, becomes an access grant. The audit follows a federated login into the account and roles it
creates and checks that every claim is validated and every mapping is minimal. You audit this by logging in
with shaped assertions and seeing what account and privilege you are given.

## When to use

- A federated login (SAML or OIDC) provisions a local account and assigns roles or tenancy from assertion
  claims on first login, and may update them on repeat logins.
- A claim-to-role mapping may over-grant, default new users into a privileged role, or trust an email or domain
  claim to auto-join an organization.
- Claims (email, groups, department) may be provisioned without validation.

## Scope check

Test JIT provisioning only against applications and identity providers you own or are authorized to assess, on
non-production tenants. Logging in with shaped assertions creates real accounts and role grants, so use test
identity providers and tenants and never provision or elevate access in an organization that is not yours. If
you can't name the authorization, stop.

## The loop

1. **Establish the intended claim-to-role and claim-to-tenant mapping first.** Name which claims the service
   trusts, how each maps to a local role, how tenancy or organization membership is decided, and what a brand
   new user should get by default. This is the false-positive killer: a service that validates every claim it
   provisions from, maps claims to least privilege, defaults new users into no privileged role, and decides
   tenancy from a verified, non-spoofable signal is behaving correctly. Name the intended mapping, then test
   shaped logins.

2. **Test the claim-to-role mapping.** Log in with assertions carrying various group and role claims and confirm
   each maps to exactly the intended privilege. Attempt a claim that should map to an ordinary role and check it
   cannot reach an admin or elevated role, and confirm a new user with no privileged claim is not defaulted into
   one. A mapping that over-grants or defaults high is a first-login escalation.

3. **Test tenant and organization auto-join.** Log in with an email or domain claim and confirm how the service
   decides which tenant or organization the account joins. Try a lookalike domain, a subdomain, and an
   attacker-controlled address, and confirm none auto-joins an organization it should not. An email or domain
   claim trusted to auto-join lets an attacker land inside a tenant.

4. **Test claim validation.** For each provisioned claim, confirm the service validates it: the email is
   verified, the assertion is signed and the claim is within its authority, and the group is one the identity
   provider is authorized to assert. Provision from an unverified email and an attacker-influenced group and
   confirm both are rejected. An unvalidated claim is an access grant the attacker writes.

5. **Test JIT update on repeat login.** Log in again with changed claims and confirm whether the service
   re-reads them to re-elevate or reassign the existing account. Check whether an admin's manual correction
   (demotion, tenant move) survives the next federated login. A JIT update that blindly re-applies mutable
   claims undoes local administration every login.

6. **Confirm and record.** Confirm on a test tenant by provisioning an over-privileged account from a shaped
   role claim, auto-joining a tenant from a lookalike email, provisioning from an unverified or
   attacker-influenced claim, or re-elevating an account on repeat login, without touching a real organization.
   Kill the lead if the service validates every provisioned claim, maps claims to least privilege, defaults new
   users into no privileged role, decides tenancy from a verified signal, and does not let a JIT update override
   local correction. Record the attacker-shaped login assertion, the over-privileged or wrong-tenant account,
   and the unvalidated claim or over-granting mapping.

## Where JIT provisioning leaks

- **Over-granting role mapping.** A claim that maps to more privilege than it should, or a default that puts new
  users in a privileged role, escalates at first login.
- **Email or domain auto-join.** Trusting an email or domain claim to auto-join a tenant lets an attacker with a
  lookalike or controlled address land inside an organization.
- **Unvalidated claims.** Provisioning from an unverified email, an attacker-influenced group, or an
  overtrusted assertion field turns a claim into an access grant.
- **Blind JIT updates.** Re-reading mutable claims on every login re-elevates or reassigns accounts and undoes
  an admin's local corrections.
- **Trusting unsigned or out-of-authority claims.** Accepting a claim the identity provider is not authorized to
  assert, or from an unsigned assertion, lets the attacker set roles directly.

## Worked example (a confirm and a kill)

> **Confirm.** An application provisions accounts at first SAML login and joins the user to an organization based
> on the email domain in the assertion, with any member of the `staff` group mapped to an admin role. On a test
> identity provider, an assertion with a lookalike domain and a `staff` group claim provisions an admin account
> inside the target organization, because the service trusts the domain to auto-join and maps `staff` straight to
> admin. **Confirmed** wrong-tenant admin provisioning via trusted domain and over-granting mapping, `critical`,
> remediation = decide tenancy from a verified, claimed-domain-ownership signal rather than the raw email domain,
> map groups to least privilege with admin unreachable from a broad group, and verify the email before
> provisioning.
>
> **Kill.** The service provisions only from validated claims (verified email, signed assertion, groups within
> the provider's authority), maps each claim to least privilege with admin roles unreachable from ordinary
> claims, defaults new users into no privileged role, decides organization membership from a verified
> domain-ownership signal, and does not let a repeat login override an admin's manual role or tenant correction.
> A lookalike domain does not auto-join, a broad group does not reach admin, and an unverified email does not
> provision. **Killed**, `kill_reason` = "every provisioned claim is validated, claims map to least privilege
> with no high default, tenancy comes from a verified signal, and JIT updates do not override local correction;
> no shaped login provisions over-privileged or wrong-tenant access."

## Rationalizations to reject

- *"The claims come from the IdP, so they are trusted."* → Confirm each claim is within the provider's authority
  and the assertion is signed; a claim the attacker can influence or that the provider should not assert is not
  trustworthy just because it arrived over federation.
- *"We map groups to roles, that is standard."* → Confirm the mapping is least privilege and admin is unreachable
  from a broad group; a `staff`-to-admin mapping is standard and wrong.
- *"New users get a default role."* → Confirm the default is not privileged; defaulting new federated users into
  an elevated role is a first-login escalation for anyone who can log in.
- *"Email domain identifies the company."* → An email domain is spoofable in an assertion and lookalikes exist;
  decide tenancy from verified domain ownership, not the raw claim.
- *"JIT keeps roles in sync."* → Confirm it does not undo local corrections; blindly re-applying mutable claims
  every login re-elevates accounts an admin already demoted.

## Executing this in practice

You need which claims the service provisions from, how each maps to a role and to tenancy, how claims are
validated, and whether repeat logins re-apply mutable claims over local changes. On a test identity provider,
log in with shaped role, group, and email claims, with lookalike and unverified addresses, and on repeat with
changed claims. Reading the provisioning and mapping code shows the intended trust; an over-privileged or
wrong-tenant account from a shaped login shows whether it holds.

## Related

- `auditing-scim-provisioning-trust` - the push counterpart; SCIM provisions ahead of login while JIT provisions
  at login, and both turn a source attribute into a role and a tenant.
- `auditing-saml-and-oidc-federation-trust` - the assertion validation JIT depends on; an unsigned or wrapped
  assertion feeds JIT attacker-chosen claims.
- `auditing-idp-initiated-flow-trust` - an IdP-initiated login is a common JIT trigger; the two combine when an
  unsolicited assertion provisions an account.
- `hunting-iam-privilege-escalation-paths` - a role over-granted at first login is the start of an escalation
  path that skill traces onward.
- [FINDING-SCHEMA.md](../../FINDING-SCHEMA.md) - source = the attacker-shaped login assertion, sink = the
  over-privileged or wrong-tenant provisioned account, evidence = the unvalidated claim or over-granting role
  mapping.