Skip to content
ADR-0046Architecture decisionAcceptedversion 1.0.011 October 2026

In short ​

Today a diploma or membership credential can be shown to any verifier on the trust list if the person approves. The wallet only checks whether the verifier asks for more than it is registered for (ADR-0026 K5, over-asking warning). The EU wants the issuer to be able to say "show this credential only to these verifiers" and the wallet to check it. This record decides where that rule is carried, how the wallet evaluates it and what the person is shown.

Context ​

What the EU requires (ARF 3.0, Annex 2, Topic 43; main text §6.6.2.8, §6.6.3.4; Implementing Regulation (EU) 2024/2979 Annex III; ETSI TS 119 472-3 §4.2.5):

RequirementSummary
EDP_01The wallet lets an attestation provider optionally express an embedded disclosure policy for an EAA (QEAA, PuB-EAA, non-qualified EAA). Not required for PIDs.
EDP_02"Authorised relying parties only" policy: a list of (relying party identifier, service identifier) duplets. The wallet takes the duplet from the verifier's registration certificate (not the access certificate; with an intermediary the access certificate names the intermediary); if not listed, the evaluation fails and the person is told.
EDP_03"Specific root of trust" policy: a list of root or intermediate certificates. The wallet compares the certificates in the chain that signed the registration certificate with the list; if none matches, it fails and the person is told.
EDP_05 (SHOULD + SHALL)The policy should link to a page explaining it in plain language; if present, the wallet shows the link and lets the person open it.
EDP_06The wallet evaluates the policy together with the registration certificate, following the evaluation rules of ETSI TS 119 472-3.
EDP_07Based on the outcome, the wallet lets the person deny or allow the presentation.
EDP_08The format complies with ETSI TS 119 472-3.
EDP_09The issuer includes the policy (if any) by value in the OpenID4VCI Credential Issuer metadata.
EDP_10The wallet retrieves and stores the policy at issuance (so it can evaluate it at presentation, including in proximity, without asking again).
EDP_11The issuer revokes the credential if the policy is added, changed or deleted.

EDP_04 is empty; 10 requirements in total.

The three common policies of Annex III of the Regulation: (1) no policy (default), (2) authorised relying parties only, (3) specific root of trust. Policies apply to whole credentials, not to individual attributes.

ETSI TS 119 472-3 §4.2.5.2 data model (ISS-MDATA-EBD-01…13): identified by a unique URI; optional description and responsible authority; may state "no restrictions"; a list of authorised relying parties identified (a) by the subject distinguished name of the access certificate (RFC 4514 LDAP string; for a legal person commonName, organizationName, organizationIdentifier, countryName) and/or (b) by TS 119 475 entitlement URIs in the registration certificate; a list of roots of trust (each element: issuer distinguished name + certificate serial number); extensions (the wallet may ignore them); a link to a plain-language page. The policy is not revealed to the verifier. ETSI does not define JSON member names.

Difference between the ARF and ETSI: the ARF describes the authorised verifier by the (identifier, service) duplet of the registration certificate and the root of trust by the registration certificate chain; ETSI and the Regulation describe it by subject name or entitlement and by the access certificate root. The decision accepts both (K3).

In Tamga today:

  • A verifier registration certificate (WRPRC, rc-wrp+jwt) is produced per usage and arrives in the OpenID4VP request via verifier_info; the wallet checks its signature, validity and the match between sub and the organizationIdentifier of the access certificate (ADR-0026 K5). It carries no separate service identifier (ARF RPRC_17a partial); it has a usage identifier intended_use_id.
  • The issuer's Credential Issuer metadata is signed and carries the institution's WRPRC in issuer_info.
  • The credential configuration has display and credential_reuse_policy under credential_metadata.
  • There is no embedded disclosure policy in the code. EDP_02 counts as "partial" because the over-asking check gives a similar protection.
  • In proximity (ISO 18013-5) and in wallet-to-wallet requests there is no registration certificate.
  • ADR-0028 K5 gives an entitlement-based policy example for the practice licence ("only to verifiers whose registration certificate carries a healthcare-provider entitlement") and leaves the JSON names to this record.

Options considered ​

1. Where the policy lives ​

OptionResultWhy
In the signed Credential Issuer metadata, by value, in the credential_metadata object of the credential configurationchosenExactly EDP_09; the credential format does not change; the metadata is already signed and read by the wallet at issuance.
Inside the credential (SD-JWT claim or mdoc element)rejectedThe policy must not be revealed to the verifier (ETSI §4.2.5.1); the format changes; the ARF says no format change is needed.
By URL, the wallet downloads it at presentationrejectedThe ARF says by value, not by link (§6.6.2.8.3); fails in proximity and offline; leaks presentation time to the issuer.
In the institution's trust list entryrejectedNot the EU route; EU wallets would not read it.

2. When the evaluation fails ​

OptionResultWhy
Warn and leave the decision to the person (default button "Don't share")chosenEDP_07 gives the person the choice to deny or allow; same pattern as the over-asking warning of ADR-0026 (WL8).
Hard blockrejected (question 3)Conflicts with EDP_07; a stricter Tamga-only rule; EU wallets only warn.
The issuer chooses "warn / block"rejected (question 3)A new field with no EU counterpart; the same credential would behave differently in an EU wallet.

3. How the authorised verifier is identified ​

OptionResultWhy
ARF duplet + ETSI subject name + ETSI entitlement URI; passes if any listed item matcheschosenFits both the ARF and ETSI; the institution uses what fits its case ("these three verifiers" or "everyone with this entitlement").
ARF duplet onlyrejectedCannot read EU policies written the ETSI way; no entitlement-based "category" rule.
ETSI onlyrejectedMisses the ARF intermediary note (the identity in the registration certificate is decisive).

Decision ​

K1 — Location and format ​

For every credential configuration that has a policy, the issuer publishes the following object in its signed Credential Issuer metadata (the field and member names were approved by project management; ETSI defines no JSON names, so this is Tamga's choice following the ETSI data model; if the EU or ETSI publishes a JSON encoding, Tamga switches to it, ADR-0029):

json
"credential_configurations_supported": {
  "<configuration>": {
    "credential_metadata": {
      "embedded_disclosure_policy": {
        "id": "https://institution.example/policy/diploma-1",
        "type": "authorized_relying_parties",
        "relying_parties": [{ "rp_id": "VATTR-1234567890", "service_id": "hiring" }],
        "subject_dns": ["ORGID=VATTR-1234567890,O=Example Ltd,C=TR"],
        "entitlements": ["<TS 119 475 entitlement URI>"],
        "info_uri": "https://institution.example/policy/diploma"
      }
    }
  }
}
  • id (required): unique URI of the policy (ETSI -01).
  • type (required): none · authorized_relying_parties · specific_roots_of_trust (the three policies of Annex III).
  • For authorized_relying_parties, at least one of: relying_parties (ARF duplet; rp_id is the sub of the registration certificate, service_id optional), subject_dns (ETSI -07a), entitlements (ETSI -07b).
  • For specific_roots_of_trust, roots_of_trust: [{ "issuer_dn": "<RFC 4514>", "serial_number": "<hex>" }] (ETSI -09).
  • Optional: info_uri (EDP_05, ETSI -13), authority (ETSI -05), description (ETSI -04).
  • Unknown members and extensions are ignored (ETSI -10/-11). The attribute-level policy extension (ETSI -12) is not supported.
  • The policy does not go into the credential and is not sent to the verifier.
  • Scope: institution credentials only (EAA). The Tamga identity credential (and its ZK copy), the driving licence information and the contact credentials carry no policy; the metadata builder rejects a policy on these types.

K2 — Wallet: storing at issuance (EDP_10) ​

At issuance the wallet reads the policy from the signature-verified metadata, checks its format and stores it next to the credential record (policy + digest). At presentation no request is made to the issuer or any other server (same principle as WL9). A malformed policy does not stop issuance, but is stored as "not evaluable" and produces the K4 warning at presentation.

K3 — Wallet: evaluation (EDP_02, EDP_03, EDP_06) ​

When a presentation request arrives, for every requested credential, after the registration certificate has been verified per ADR-0026 K5:

PolicyPasses if
none or nonealways
authorized_relying_parties(a) the sub of the registration certificate equals the rp_id of a relying_parties item and, if the item has a service_id, the service identifier of the registration certificate also matches; or (b) the subject name of the access certificate that signed the request equals a subject_dns item (RFC 4514 normalised comparison); or (c) the entitlements of the registration certificate contain an entitlements item
specific_roots_of_trustthe (issuer name, serial number) pair of a certificate in the chain that signed the registration certificate (ARF EDP_03) or in the access certificate chain (Regulation Annex III, ETSI -08) is listed
  • Without a registration certificate (not sent in the request; proximity; wallet-to-wallet) the evaluation cannot be performed and counts as failed.
  • For an intermediated request, the intermediated verifier in the registration certificate is decisive (ARF EDP_02 note).
  • Today the registration certificate has no service identifier (RPRC_17a partial). Until it is added, an item with a service_id does not match; an item without service_id covers all usages of that verifier. Adding the service identifier to the WRPRC is a prerequisite of this record and is done in the same round (packages 0.5.0).
  • If the evaluation passes, the screen is unchanged.
  • If it fails or cannot be performed: a separate warning block — "[issuer] wants this credential to be shown only to institutions it allows. [verifier] is not one of them." (if not evaluable: "...could not be checked."). With info_uri, a "Read the rule" link. The default button is "Don't share"; "Share anyway" becomes active after a short delay (WL8 pattern). The wallet does not hard-block: the final decision is the person's (EDP_07).
  • When several credentials are requested, the warning sits on the row of the affected credential; the person can remove it and share the rest.

K5 — Issuer: revocation (EDP_11) ​

  • If the policy of a configuration is added, changed or removed, the issuer revokes all still-valid credentials issued under that configuration. The credential record keeps the policy digest at issuance time; revocation is driven by the digest.
  • Before changing a policy, the Institution Console shows how many credentials will be revoked and asks for confirmation. People receive the credential again; if the automatic refresh conditions (ADR-0023) allow it, new copies come with the new policy. This cost is accepted.

Invariants ​

CodeRule
EP1An embedded disclosure policy is carried only by value in the signed Credential Issuer metadata, in an institution credential configuration; it does not go into the credential and is not sent to the verifier.
EP2The wallet stores the policy at issuance and evaluates it at presentation, without network requests, against the registration certificate and the access certificate.
EP3If the evaluation fails or cannot be performed, the wallet shows a separate warning on the consent screen; the default choice is not to share, the final decision is the person's.
EP4Valid credentials of a configuration whose policy is added, changed or removed are revoked.

ARF mapping (10 requirements) ​

RequirementHow it is met
EDP_01K1: optional policy for institution credentials
EDP_02K3 (a): (identifier, service) duplet from the registration certificate; intermediated verifier for intermediated requests; service identifier added to the WRPRC
EDP_03K3: registration certificate chain (and access certificate chain)
EDP_05K1 info_uri, K4 "Read the rule"
EDP_06K3: together with the registration certificate, per the ETSI data model
EDP_07K4: warning + "Don't share" / "Share anyway"
EDP_08K1: ETSI TS 119 472-3 §4.2.5.2 data model; JSON names follow an ETSI encoding once published
EDP_09K1: by value in the signed Credential Issuer metadata
EDP_10K2
EDP_11K5

Affected packages and version ​

Packages in 0.5.0 (new field and function = minor):

PackageChange
@tamga-network/schemasJSON Schema and validator for the policy object
@tamga-network/issuerPer-configuration policy in the metadata builder; policy digest; format check
@tamga-network/trustRFC 4514 distinguished-name parsing and normalisation; extracting (issuer name, serial number) from a certificate
@tamga-network/wallet-coreStoring at issuance; evaluateDisclosurePolicy (result: passed / failed / not evaluable + reason + link); result in the consent view
@tamga-network/verifierNo change (the policy is not revealed to the verifier)

Outside the packages: a service identifier in the registration certificate (list publisher, RPRC_17a), the policy digest in the credential record and bulk revocation on change in the hosted issuance service, a policy editor in the Institution Console (operator repository), the consent-screen warning in wallet apps.

Consequences ​

  • Specifications: SPEC-PROTO-0001 metadata field; SPEC-WALLET-0001 evaluation and consent-screen rule; FW-RB-0001 an "access restriction" rule (ARF note: the restriction is also announced to verifiers in the rulebook); Tamga ARF rows on the trust model and privacy measures (updated on acceptance; code with 0.5.0).
  • In wallet-to-wallet and proximity presentation the policy cannot be evaluated; a credential with a policy is shown there with a warning (proximity) or not at all (wallet-to-wallet; the wallet's own decision).
  • An institution that changes a policy accepts that its credentials are re-issued; the Institution Console makes this explicit.

Plan and estimate ​

#WorkEstimate (engineer-days)
1schemas: policy schema + tests0.5
2issuer: metadata, policy digest, format check + tests1
3trust: RFC 4514 normalisation, (issuer name, serial number) + tests1
4Service identifier in the registration certificate (list publisher + wallet check, RPRC_17a)1
5wallet-core: storing + evaluation + consent view; test matrix of policy types × registration certificate present/absent × intermediated request2
6Hosted issuance: policy digest in the credential record, bulk revocation on change; Institution Console editor2
7Wallet app: consent-screen warning block, "Read the rule", i18n1
8End-to-end scene in the sandbox (a test credential with a policy; allowed and not-allowed verifier)0.5
9Specifications, rulebook, Tamga ARF1
Total≈ 10 days

All work is code and documents; no device or certificate is needed.

Answered questions (2026-10-11) ​

  1. Name approval: embedded_disclosure_policy, the types none / authorized_relying_parties / specific_roots_of_trust and the member names — approved (K1).
  2. Scope: — institution credentials only; the Tamga identity and contact credentials carry no policy (K1).
  3. Warn or block: — the wallet warns and the person decides; default "Don't share" (K4).
  4. Bulk revocation: — accepted: when a policy changes, valid credentials of that type are revoked and re-issued (K5).
  5. Service identifier: — added to the registration certificate in the same round (K3).

Status ​

Accepted — 2026-10-11. With project management approval. DECISIONS: D-TRUST-5. Code with the 0.5.0 packages.