Skip to content
Deze documentatie wordt actief uitgebreid — kom regelmatig terug.

ADR-00006: Token Claim Composition for Participant Context

Status flow: Proposed → Accepted → Reviewed → Approved (or Rejected), or Not Required. A superseded ADR keeps its file; only its status changes to Superseded by NNNNN.

Governance bodyStatusLast update
CTN Project TeamProposed2026-05-29
CTN Technical Advisory BoardPending
CTN Steering CommitteePending
BDI Conformance TeamProposed2026-07-08
BDI Framework TeamPending

ADR-00003 split the data between two systems:

  • Keycloak (the login system) stores everything about a user’s login (their identity as an account that can sign in).
  • The ASR (the Association Register, CTN’s own back-end service) is the authoritative record for participant data — the registered organisations, their business identifiers (such as KVK or LEI numbers) and their verification status (whether those identifiers have been checked).

ADR-00003 also decided that Keycloak keeps track of which users belong to which participant and what role each user has there — using its built-in Organizations feature (version 26.6), one Keycloak Organization per participant.

Service providers and connectors that receive an access token need to know:

  1. Which participant the user is acting for (and which alternative participants the user could switch to).
  2. What role the user holds within that participant (admin / member / signatory).
  3. Which business identifiers identify the participant authoritatively (EUID, KVK, LEI, EORI, VAT — only those that are verified).

Of these, (1) and (2) are pure IAM concerns and can come from Keycloak directly. (3) is authoritative in ASR and must not be mirrored into Keycloak attributes (per ADR-00003).

Two prior issues from the an earlier CTN-ASR prototype review (2026-03-27) directly shape this decision:

  • M17 — EUID used as attribute key: Keycloak’s built-in organization claim emits {"organization": {"acme-corp": {...}}} with the alias as key. Consumers cannot rely on a predictable JSON path.
  • M16 — Trust level missing from tokens: verification status existed in the prototype’s database but was never reflected in tokens. Service providers could not distinguish a fully verified organization from a minimally registered one.

This ADR decides how participant context is composed into the token.

Option 1: Keycloak built-in organization scope only

Section titled “Option 1: Keycloak built-in organization scope only”
  • Description: Use the built-in organization scope and the Organization Group Membership mapper. No ASR-side enrichment. Business identifiers are not in the token; consumers fetch them from an ASR endpoint if needed.
  • Pros: Zero custom code in Keycloak. Token stays small. ASR remains single source of truth — token never goes stale relative to ASR.
  • Cons: Token carries no business identifiers — every consumer needs a second call. Alias-as-key shape (M17) remains. Requires a published ASR introspection-style endpoint.

Option 2: Custom Keycloak protocol mapper that calls ASR at token issuance

Section titled “Option 2: Custom Keycloak protocol mapper that calls ASR at token issuance”
  • Description: A custom protocol mapper (Java SPI or JavaScript mapper) in Keycloak that, during token issuance, calls an internal ASR endpoint to fetch participant claims and merges them into the token under a predictable schema (e.g. participant.euid, participant.identifiers.kvk).
  • Pros: Predictable JSON paths for consumers. Single token round-trip. Claims always reflect current ASR state at issuance.
  • Cons: Couples Keycloak to ASR availability at token-issuance time. Custom mapper is operational surface (deploy, upgrade, test). Latency added to every token issuance.

Option 3: Token exchange — minimal Keycloak token, ASR-issued participant token

Section titled “Option 3: Token exchange — minimal Keycloak token, ASR-issued participant token”
  • Description: Keycloak issues a baseline identity token (sub, email, org membership, role). Client exchanges it at an ASR token endpoint for a second token that carries participant claims, signed by ASR. Consumers validate both, or only the ASR token for participant-scoped APIs.
  • Pros: Clean separation — ASR is the issuer for participant claims, matching the storage boundary. ASR can apply business rules (e.g. only emit claims for participants where verifications are current). No Keycloak customization.
  • Cons: Two tokens to manage. Consumers need to understand which token they are validating. More moving parts; documentation burden.

Option 4: Userinfo-style enrichment — keep token minimal, fetch on demand

Section titled “Option 4: Userinfo-style enrichment — keep token minimal, fetch on demand”
  • Description: Token from Keycloak carries only identity and org membership. ASR exposes a /participant/context endpoint that returns the participant payload for the authenticated user. Consumers fetch when they need it; can cache for the token lifetime.
  • Pros: No Keycloak customization. Token always small. ASR claims always fresh. Easy to evolve the payload without breaking token consumers.
  • Cons: Every consumer must implement the second call. Cache invalidation on the consumer side. Performance impact for high-volume APIs.

Chosen option: TBD.

TBD.

  • Positive: TBD.
  • Negative: TBD.
  • Neutral: TBD.
  • Should business identifiers in the token be limited to those with Approved verifications, or include all known identifiers with a status field?
  • What is the desired token TTL relative to verification-status change frequency?
  • Do connectors / external dataspaces have a preferred claim schema we should align with (BDI, iSHARE, eIDAS-related profiles)?
  • For Option 2 or 3: how do we handle the case where a user is a member of multiple participants — one token per participant, or one token with an array?
  1. Phase 1: Inventory token consumers (connectors, service providers, internal services) and document their claim needs.
  2. Phase 2: Evaluate the four options against those needs; pick one.
  3. Phase 3: Specify the concrete claim schema and update this ADR with the decision.
  • Security review completed
  • Performance impact assessed
  • Integration impact evaluated
  • Documentation updated
  • Stakeholder approval obtained
DateStatusNotes
2026-05-29ProposedSkeleton — options outlined, decision pending

In samenwerking met

Connected Trade NetworkConclusionData in LogisticsContargoInland Terminals GroupVan Berkel