Skip to content

Generic issuer-to-credentialSubject attribute matching for did:x509 #4085

@stevenvegt

Description

@stevenvegt

Parent PRD

#4079

What to build

Extract the validatePolicyAssertions logic from X509CredentialValidator and make it apply generically to any credential with a did:x509 issuer. This implements PSA 10.6.2 rule 9: identifier values in credentialSubject that originate from the issuer DID must match the corresponding attributes in the issuer DID.

  • In the Verify function (verifier.go), after signature verification succeeds for a credential with a did:x509 issuer, match credentialSubject identifiers against issuer DID attributes
  • Implement a recursive walk of the credentialSubject JSON to find all objects with system/value fields (identifier pattern per PSA 10.6.1)
  • Match each identifier against the corresponding issuer DID attribute based on system URI:
    • http://fhir.nl/fhir/NamingSystem/ura → URA from issuer DID
    • http://fhir.nl/fhir/NamingSystem/uzi-nr-pers → UZI-nummer from issuer DID
  • Handle roleCode as a known special case (direct attribute, not an identifier object)
  • Remove validatePolicyAssertions from X509CredentialValidator

This is independent of the CRL/resolver changes and can be worked on in parallel.

Acceptance criteria

  • Identifier matching runs for any credential with a did:x509 issuer, not just X509Credential type
  • Recursive walk finds deeply nested identifiers (e.g., credentialSubject.hasEnrollment.enrolledBy.identifier)
  • URA mismatch between credentialSubject and issuer DID produces an error
  • UZI-nummer mismatch between credentialSubject and issuer DID produces an error
  • roleCode mismatch produces an error
  • validatePolicyAssertions is removed from X509CredentialValidator
  • Existing X509Credential tests pass
  • New test: PatientEnrollmentCredential with matching UZI-nummer passes
  • New test: PatientEnrollmentCredential with mismatched UZI-nummer fails
  • New test: HealthcareProviderCredential with matching URA passes
  • New test: HealthcareProviderCredential with mismatched URA fails

Blocked by

None — can start immediately (independent of resolver/key resolution changes).

User stories addressed

  • User story 1: PatientEnrollmentCredentials get attribute matching
  • User story 2: HealthcareProfessionalDelegationCredentials get UZI-nummer and roleCode validated
  • User story 3: HealthcareProviderCredentials get URA validated
  • User story 7: existing behavior preserved
  • User story 8: no type-specific validators needed for new credential types

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions