Skip to content

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

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

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions