What `proofPurpose` Means in a Verifiable Credential
Our published type hard-codes this field to one value, and the credentials we actually issue do not carry it at all. The term is spec.
What the field is for
A signature proves someone signed something. It does not say what they meant by signing it.
The same key can be used to assert a claim, to authenticate as an identity, to agree a key, to
delegate a capability, or to invoke one. proofPurpose records which of those a given signature
was made for, so a verifier can refuse a signature that was valid but made for a different job.
It is a defence against cross-protocol reuse. Without it, a signature captured in one context
could potentially be replayed in another where the same key is authoritative. Its five values come
from the DID Core verification-relationship vocabulary: assertionMethod, authentication,
keyAgreement, capabilityDelegation, capabilityInvocation.
What our type says, and why it is narrow on purpose
proofPurpose: 'assertionMethod'
A single string literal, not a union of the five. Our credentials are only ever issued, never authenticated-as or delegated with this field, so the type refuses to describe a case that does not arise.
That narrowing is defensible. A type that permitted all five where only one occurs would be documentation of an intent, not of a system. This one is honest about its scope, which makes it the better half of this page.
And then the field is not on the wire
$ curl -s https://capture-api.solidus.network/.well-known/openid-credential-issuer
format : vc+sd-jwt
200, checked 2026-07-31. No proof object. No proofPurpose. The live wire format is
JOSE/SD-JWT, which has no proofPurpose-equivalent concept at all.
So the picture is: a correctly-narrowed type describing a proof block our issuer has never emitted. The type is not wrong about itself: it is describing a path that is not the shipped one. See the cryptosuite field for the same gap from the algorithm-naming side.
The thing you will find if you grep, and it is not this
The live issuer metadata contains proof_types_supported: ["jwt"]. It looks like a match. It
is a different mechanism entirely.
That block is OID4VCI proof-of-possession: during issuance, the wallet proves it holds the private key the credential will be bound to. It concerns who is receiving a credential.
proofPurpose concerns what the issuer's signature on a credential was intended for.
Same word, different layer, no relationship. We are naming it because a researcher scanning our metadata for "proof" will hit it, and it is exactly the kind of near-miss that becomes a wrong conclusion in a comparison table.
How the actual protection is achieved instead
The concern proofPurpose addresses does not disappear because the field is absent: it is
handled by different means in the JOSE path:
- The credential's own type and claims establish what it asserts.
- Key binding ties presentation to a specific holder key, and its token carries an audience and a nonce, which is the anti-replay job, see the key-binding token.
- Different keys for different jobs is a discipline rather than a field.
We are not claiming this is equivalent. It is what a different format does instead, and a reviewer comparing us against a Data Integrity implementation should score the field as absent, not as satisfied by something adjacent.

