Claim sets
Issue several distinct credentials of the same credential configuration to a single user.
Claim set identifiers are offered as a closed beta preview feature and are not generally available yet. They are enabled per tenant, and their behavior may change in a way that breaks existing integrations before they become generally available. If you are interested in trying this feature, please contact us to have it enabled on your tenant.
Overview
By default, MATTR VII manages one credential per user, per credential configuration. If you issue a user a second credential from the same configuration, every flow treats it as a replacement for the first.
Claim sets remove that restriction. A claim set is one distinct credential's worth of claims, named by an identifier that you choose. In practice that identifier is usually a key you already hold: the record number you would use to look the record up in your own system. By supplying several claim set identifiers for the same credential configuration, you can issue the same user several credentials of that type, each carrying different data, and each managed independently in the holder's wallet.
Claim sets are unrelated to Claims sources, despite the similar name. A Claims source is where MATTR VII fetches claims from. A claim set is which of several credentials of the same type the claims belong to. The two work together: MATTR VII passes the claim set identifier to your Claims source so it can return the right data.
What this enables
- Held-on-behalf-of credentials: A parent can hold a separate birth certificate for each of their children, rather than one certificate that overwrites the last.
- Multiple qualifications of the same type: A learner can hold several micro-credentials that share a credential configuration but certify different subjects.
- A mix of your own and held-on-behalf-of credentials: A person can hold their own certificate alongside one they hold for another adult, both from the same credential configuration.
- Independent lifecycle management: Each credential is stored, updated and deleted on its own, without affecting the others.
A worked scenario
Suppose you are a government registry that issues birth certificates. Your system of record already holds a registration number for every certificate, and those numbers are stable. A name correction or a re-registration changes the values inside a record without changing which record it is. That stability is what makes them good claim set identifiers.
Jamie is a parent entitled to hold the certificates for two children, records
bc-2019-114837 and bc-2022-508122.
- Configure your Claims source once to accept the identifier, by mapping a request
parameter from
claimSetId. This is opt in. If you do not declare the mapping, your Claims source never receives the identifier. - Decide what Jamie can hold. Jamie authenticates, and your Interaction hook runs your own entitlement check against your own records. It returns both registration numbers as claim set identifiers.
- MATTR VII abstracts them away. The token response carries one opaque credential identifier per claim set, so your registration numbers stay on your side of the wire and the wallet never learns them.
- The wallet claims each credential separately. For each identifier, MATTR VII resolves it back to the matching registration number, calls your Claims source with that number, and issues a credential holding only that child's claims.
Jamie ends up with two birth certificates side by side, each independently viewable, refreshable and deletable. Without claim sets, the second would have replaced the first.
If one certificate is later amended, you create a Pre-authorized Code offer naming only that record. The offer is scoped to a single claim set, so only that credential is reissued and the other is left untouched. To replace the credential Jamie already holds rather than adding a second copy of it, target the existing credential bundle. See Credential Update.
Claim set identifiers and credential identifiers
Two different identifiers are involved, and keeping them apart is the key to understanding the feature.
A claim set identifier is chosen by you, the issuer. It is your own key into your system of record, such as a record number for a particular birth certificate. Choose one that is stable for the life of the record, because MATTR VII treats a change of identifier as a different credential rather than an update to the existing one. You supply it when you create an offer or when your Interaction hook returns a result.
A credential identifier is derived by MATTR VII, one per claim set. It is returned to the holder's wallet in the token response, and the wallet uses it to request each credential. Treat it as opaque: it does not encode your claim set identifier, and the wallet never sees the claim set identifier itself. This keeps your internal record keys out of the holder's device.
For mDocs, the credential identifier is also returned as credential_bundle_id on the
credential response, so you can correlate an issued credential back to the claim set it was
issued for.
How it works
- You supply claim set identifiers, either on a Pre-authorized Code flow offer or from an Interaction hook during an Authorization Code flow.
- MATTR VII scopes the authorization grant to those claim sets. Any access token issued from that grant is limited to the same set.
- The token response carries
authorization_details, listing onecredential_identifierper claim set for each credential configuration. - The wallet makes one credential request per
credential_identifier. - MATTR VII resolves the identifier to its claim set, passes
claimSetIdto your Claims source, and issues a credential containing only that claim set's data.
Supplying claim set identifiers
There are two entry points, one per flow. On a Pre-authorized Code offer, credentials names
which claim sets to issue, and claimSets supplies their claims. On an Interaction hook
during an Authorization Code flow, claimSets alone does both.
| Entry point | Where | Shape |
|---|---|---|
| Pre-authorized Code flow offer | credentials and claimSets on the offer request | credentials maps configuration IDs to claim set IDs. claimSets maps configuration ID, then claim set ID, to claims |
| Interaction hook | claimSets in the response JWT | Maps configuration ID, then claim set ID, to claims, same as the offer |
Claim values are optional in both places. Supply them directly in claimSets, set a claim
set's value to an empty object and let your Claims source resolve it at issuance time using
claimSetId, or do both. These are not alternatives: claims are resolved in order, with each
step overriding the last. Persisted user claims, then persisted claim set claims, then the
claims from your Authentication Provider and the sibling claims on the offer or hook, then
the values in claimSets, then your Claims source. See the
guide for worked examples of both.
On an Interaction hook, an empty object is how you name a claim set that carries no claims,
because MATTR VII takes the identifiers from the keys of claimSets. On a Pre-authorized Code
offer, credentials names them, so you can omit claimSets altogether.
Requirements
- Your tenant must be enabled for claim sets. Claim sets are a closed beta preview feature, so contact us to have them enabled on your tenant.
- The Pre-authorized Code flow entry point supports mDocs credential configurations only.
Limits and considerations
- Supplying claim set identifiers is optional. Where you do supply them, each credential configuration takes between 1 and 50 identifiers, so an empty list is rejected.
- Each claim set identifier is between 1 and 255 characters.
- Wallets must not send
authorization_detailson the token request. The credential issuer determines it, and a request that includes it is rejected withinvalid_authorization_details. - When a grant binds more than one claim set for a configuration, a credential request that
supplies only
credential_configuration_idis ambiguous and is rejected. The wallet must sendcredential_identifierinstead. - When a grant binds a single claim set,
credential_configuration_idon its own is still sufficient, so existing integrations keep working unchanged. credential_bundle_idis returned on mDocs credential responses only.
Next steps
How would you rate this page?
Last updated on