DomainLinkage and allowed domains

This page describes how the Verifier applies W3C Domain Linkage checks and the optional issuer allow-list (issuerAllowedDomains) during VP/VC validation.


What problem this solves

  • Bind issuer DID → web origin: Proves that an issuer controls a given HTTPS origin via W3C Domain Linkage Credentials (DLC) published at /.well-known/did-configuration.json.

  • Restrict acceptable issuers: Lets verifiers allow-list issuer websites via issuerAllowedDomains to enforce business or compliance policies.


When it runs

During VP verification:

  1. Validate VP holder DID and VP proof.

  2. For each embedded VC:

    • Validate VC proof and issuer DID Document.

    • If issuer advertises LinkedDomains, verify Domain Linkage for each advertised origin.

    • If issuerAllowedDomains present, enforce allow-list by origin intersection.

    • Check revocation/expiry/etc.

If any VC fails its linkage or allow-list check, the VP is rejected per policy.


Inputs

Configuration surface

You can provide the allow-list at request time or via a stored VP Query:

  • Create Authorization Request (CreateAuthorizationRequestDto)

    • issuerAllowedDomains?: string[]

  • Create VP Query (CreateVpQueryRequestDto)

    • issuerAllowedDomains?: string[]

Format: canonical HTTPS URLs

  • Must include https://

  • Optional :port and /path (queries/fragments are not allowed)

  • Examples: https://issuer.example.com, https://issuer.example.com:8443, https://issuer.example.com/trusted

Normalization (runtime):

  • Host is case-folded

  • Trailing slashes trimmed

  • Duplicates removed

  • Matching is by URL.origin (paths accepted in config but ignored for linkage matching per spec)

If omitted or empty → no issuer-domain restriction (backward-compatible).


Domain Linkage (W3C) — how it works

  1. Discover linked origins: From issuer DID Document services (e.g., LinkedDomains), the resolver extracts HTTPS origins.

  2. Fetch configuration: For each origin, download origin + "/.well-known/did-configuration.json".

  3. Validate DLCs:

    • Check type includes DomainLinkageCredential

    • Subject { id: <issuer DID>, origin: <that origin> }

    • Issuer equals the same DID

    • Proof verifies against one of the DID’s assertionMethod keys

    • Enforce safe limits (payload sizes, max entries, timeout)

  4. Accept origin if any DLC for that origin validates.

This proves control of the website by the issuer DID.


Allow-list enforcement (issuerAllowedDomains)

  • Build allowedOrigins = unique(origin(url) for url in issuerAllowedDomains).

  • For each VC issuer:

    • Compute linkedOrigins (validated via Domain Linkage).

      • If issuer has no LinkedDomains, linkedOrigins may be empty.

    • Decision:

      • If allow-list is not provided → skip restriction.

      • If allow-list is provided:

        • If issuer advertises LinkedDomains → require intersection(allowedOrigins, linkedOrigins) ≠ ∅.

        • If issuer does not advertise LinkedDomains:

          • did:web: treat the DID’s web origin as the issuer origin and compare to allowedOrigins.

          • Other methods (e.g., did:empe) with no LinkedDomains → reject (cannot bind DID to a web origin) unless your policy explicitly allows such issuers without origins.

Paths in issuerAllowedDomains are accepted for configuration convenience but do not participate in the origin match.


did:web specifics

  • Domain Linkage is not required for did:web because the DID is inherently bound to a domain.

  • For allow-list:

    • Extract the origin from the DID URL (e.g., did:web:example.comhttps://example.com).

    • Compare against allowedOrigins. If no match → reject.


Practical examples

1) Stored VP Query with allow-list

{
  "query": [ { "fields": [ { "path": ["$.type"], "filter": { "type": "array", "contains": { "const": "IdentityCredential" } } } ] } ],
  "issuerAllowedDomains": [
    "https://issuer.example.com",
    "https://partners.example.org:8443/trusted"
  ]
}
  • During verification:

    • Issuer’s LinkedDomains are DLC-validated.

    • Must match https://issuer.example.com or https://partners.example.org:8443 by origin.

2) did:web issuer

  • did:web:university.edu

  • No LinkedDomains needed. Verify VC; then ensure origin https://university.edu is in issuerAllowedDomains (if provided).

3) did:empe issuer without LinkedDomains

  • If issuerAllowedDomains is set → reject (no origin to compare), unless you disable the policy or the issuer adds LinkedDomains+DLC.


Last updated