Scopes & Claims
This page documents every scope supported by mwen.io, the claims each produces, the credential format, and how to handle them in your application.
Scope overview
Scopes are declared in MwenClientConfig.scopes and determine what the extension asks the user to share. The user sees each requested claim individually on the consent screen and can toggle any of them off.
Your application must handle the case where a claim is absent — the user may have hidden it or may not have set a value in their profile.
Scope reference
openid
| Claim | Type | Format | Notes |
|---|---|---|---|
| (none) | — | — | Required by the SIOP v2 protocol. Carries no claims. Always include as the first scope. |
identity
| Claim | Type | Format | Notes |
|---|---|---|---|
sub | string | N/A | The user's per-app did:jwk. Always included — cannot be hidden or denied. Not selectively disclosable. |
identity is implicitly included in every authentication. You do not need to list it explicitly.
name
| Claim | Type | Format | Notes |
|---|---|---|---|
given_name | string | vc+sd-jwt | User's first name. Independently disclosable. |
family_name | string | vc+sd-jwt | User's last name. Independently disclosable. |
// Example claim value in session.claims
session.claims?.given_name // { value: 'Alice', format: 'vc+sd-jwt' }
session.claims?.family_name // { value: 'Smith', format: 'vc+sd-jwt' }
nickname
| Claim | Type | Format | Notes |
|---|---|---|---|
nickname | string | vc+sd-jwt | User-chosen display name. Independently disclosable. |
age
| Claim | Type | Format | Notes |
|---|---|---|---|
age_over_18 | boolean | vc+bbs | Zero-knowledge proof. true if the user is over 18. Birth date is never revealed. |
age_over_21 | boolean | vc+bbs | Zero-knowledge proof. true if the user is over 21. |
age_over_13 | boolean | vc+bbs | Zero-knowledge proof. true if the user is over 13. |
The age scope uses BBS+ signatures to generate derived proofs. The user's birth date is never transmitted to your app in any form.
session.claims?.age_over_18 // { value: true, format: 'vc+bbs', zkProof: true }
You cannot request only
age_over_21without also gettingage_over_18andage_over_13. All three predicates are produced together when theagescope is granted.
birthdate
| Claim | Type | Format | Notes |
|---|---|---|---|
birth_date | string | vc+sd-jwt | ISO 8601 date (e.g. "1990-05-15"). The user can hide this. |
This scope provides the raw birth date. If you need only age gating, use age instead — it avoids handling birth dates entirely.
country
| Claim | Type | Format | Notes |
|---|---|---|---|
country | string | vc+sd-jwt | ISO 3166-1 alpha-2 country code (e.g. "TT", "GB", "US"). |
email
| Claim | Type | Format | Notes |
|---|---|---|---|
email | string | vc+sd-jwt | The user's email address. Independently disclosable. |
email_verified | boolean | vc+sd-jwt | Whether the email was verified by a third-party issuer. Independently disclosable. |
session.claims?.email // { value: 'alice@example.com', format: 'vc+sd-jwt' }
session.claims?.email_verified // { value: true, format: 'vc+sd-jwt' }
Note: for self-attested credentials, email_verified reflects the user's own attestation, not external verification. Third-party issuer verification is a planned future feature.
phone
| Claim | Type | Format | Notes |
|---|---|---|---|
phone_number | string | vc+sd-jwt | E.164 format (e.g. "+18005551234"). |
phone_verified | boolean | vc+sd-jwt | Whether the phone number was externally verified. |
address
| Claim | Type | Format | Notes |
|---|---|---|---|
street_address | string | vc+sd-jwt | Street address. Independently disclosable. |
locality | string | vc+sd-jwt | City / town. |
region | string | vc+sd-jwt | State / province. |
postal_code | string | vc+sd-jwt | Postal / ZIP code. |
Each address sub-claim is independently disclosable — the user may share locality without sharing street_address.
Credential formats
| Format | Used by | What it means |
|---|---|---|
vc+sd-jwt | All scopes except age | An SD-JWT Verifiable Credential. Claim values are disclosed in plaintext when the user consents. |
vc+bbs | age scope only | A BBS+ signed credential with a derived zero-knowledge proof. The underlying value is never disclosed. |
Handling missing claims
The user may hide a claim or may not have set a value in their profile. A missing claim is simply absent from session.claims — it is never transmitted as null or undefined.
Always guard against absent claims:
const { session } = useMwen();
// Safe pattern
const name = session?.claims?.given_name?.value as string | undefined;
const isAdult = session?.claims?.age_over_18?.value as boolean | undefined;
// Render conditionally
if (isAdult === false) {
// Proof was returned and user is NOT over 18
}
if (isAdult === undefined) {
// Claim was not shared — treat as unknown, not as denied
}
The distinction between false (proof returned, predicate failed) and undefined (claim absent) is significant — do not conflate them.