Skip to content

Tighten parsed credential binding to signed JWT payload #105

@EfeDurmaz16

Description

@EfeDurmaz16

Summary

verifyParsedCredential() verifies credential.proof.jwt, but downstream claim verifiers read fields from the outer parsed credential object. For pre-parsed credential inputs, that leaves a trust boundary where the signed JWT payload and the outer credential object can diverge.

Context

This came up while reviewing #88. For JWT inputs, parseJwtCredential() decodes the credential from the signed payload, so downstream checks read signed data. For pre-parsed credential inputs, a caller can provide a valid proof JWT while mutating fields on the outer credential object before calling verification.

That is especially relevant for claim verifiers that enforce semantic bindings against credentialSubject, such as payment receipt validation.

Expected behavior

When a credential includes proof.jwt, verification should ensure the outer credential fields used by downstream verifiers are bound to the signed JWT payload.

Possible approaches:

  • Re-parse proof.jwt inside verifyParsedCredential() and compare the parsed credential body to the outer credential before running claim verifiers.
  • Or normalize verification so claim verifiers receive the verified credential decoded from the JWT payload rather than the caller-provided outer object.

Acceptance criteria

  • Add a regression test where proof.jwt is valid but the outer credentialSubject is mutated.
  • Ensure verification rejects the mismatch or runs claim verifiers against the signed payload.
  • Keep the behavior for normal JWT-derived credentials unchanged.

Notes

This is a pre-existing trust-boundary issue in parsed credential verification, not introduced by #88.

AI Usage Disclosure

This issue was AI-assisted using Codex CLI and the Codex app. AI assistance was used for repository navigation, understanding the verification flow, and drafting the issue text. I reviewed the final text and take responsibility for the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions