Подписанные Verifiable Credentials
VC принимается подписанной издателем и проверяется по его DID: подпись — compact JWS (VC, защищённый JOSE, Content-Type: application/vc+jwt), ключ — из assertionMethod DID издателя. Сервис хранит JWS вместе с записью и перепроверяет его в verify.
Режимы
Переменная VC_PROOF:
Значение | Поведение |
| принимаются и подписанные VC, и JSON-запросы без подписи |
| JSON-запрос без подписи — |
С IDENTITY_SYSTEM_KEY сервис сам подписывает VC, которые выпускает identity-система (did:i:is:identity-system): системный DID публикует этот ключ в assertionMethod.
Формат
protected header:
alg(EdDSA,ES256,ES384,ES512,RS256,PS256),kid— DID URL ключа издателя (did:example:org#key-1),typ: vc+jwt;payload — сам VC (VC Data Model 2.0):
@context,id,type,issuer,validFrom,credentialSubject.idобязательны, остальные поля сохраняются в подписанном JWS.
Проверки при приёме:
kidпринадлежит DID изissuer;ключ входит в
assertionMethodтекущей версии DID издателя, подпись сходится;DID издателя и субъекта зарегистрированы и не деактивированы.
В записи сохраняется proof: формат, JWS, keyId и issuerVersionId — версия DID издателя, ключом которой проверена подпись.
Сценарий: организация выпускает VC о runtime ИИ-агента
DID организации с ключом в
assertionMethod(см. подписанные операции DID).VC
vc.json:
{ "@context": ["https://www.w3.org/ns/credentials/v2"], "id": "urn:uuid:7b0e4b8e-1f6c-4d2a-9f3e-runtime-0001", "type": ["VerifiableCredential", "AgentRuntimeCredential"], "issuer": "did:example:org", "validFrom": "2026-10-15T00:00:00Z", "credentialSubject": { "id": "did:ru:agent:z7iAK46JKsNfPgWkUErXXhtWXH7827MKHqRWeZnmA19C1", "model": "qwen-open-weights", "weightsDigest": "sha256:...", "seed": 42 } }
Подпись и приём:
JWT=$(bin/didsign sign-vc -seed $ORG_SEED -kid did:example:org#key-1 -body vc.json) curl -X POST $V/credentials -H 'Content-Type: application/vc+jwt' --data-binary "$JWT" # 201; тот же VC, подписанный чужим ключом с kid организации, — 422 invalid credential proof
Проверка:
curl -X POST "$V/credentials/urn%3Auuid%3A7b0e4b8e-1f6c-4d2a-9f3e-runtime-0001/verify"
result: registry_valid, cryptographicallyVerified: true checks.proof: valid, checks.issuerKey: current
Отзыв
Отзыв подписывает издатель: заголовок Credential-Operation-Proof — compact JWS (typ: vc-operation+jws, claims {"op":"revoke","credentialId":"…","iat":…}) ключом из assertionMethod или capabilityInvocation DID издателя. В режиме required отзыв без подписи — 401; подпись не издателя или не сходится — 422, VC остаётся действующим.
P=$(bin/didsign sign-revoke -seed $ORG_SEED -kid did:example:org#key-1 -id urn:uuid:7b0e4b8e-1f6c-4d2a-9f3e-runtime-0001) curl -X POST "$V/credentials/urn%3Auuid%3A7b0e4b8e-1f6c-4d2a-9f3e-runtime-0001/revoke" -H "Credential-Operation-Proof: $P"
Что проверяет verify
| Значение |
| подпись сходится с ключом той версии DID издателя, что приняла VC, и сохранённый VC совпадает с подписанным |
| подпись не сходится или VC изменён в базе после приёма; |
| VC принят без подписи; в режиме |
| Значение |
| издатель по-прежнему публикует этот ключ |
| ключ из DID издателя убран после выпуска; подпись остаётся действительной — она проверяется по версии DID на момент приёма. Если ключ скомпрометирован, VC отзывают |
| DID издателя деактивирован; |
Цепочка сертификатов (x5c в ключе издателя) и подписи ГОСТ проверяются PKI-сервисом и в этот сценарий не входят.
Журнал изменений
Дата | Перечень изменений | Автор |
2026-11-05 | Перенесён из архива DID-VC-итоги-2026-11-03 без изменения содержания. | Дис |