Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
검증 가능한 자격 증명은 암호학적으로 안전하고, 프라이버시를 존중하며, 기계가 검증할 수 있는 방식으로 Web에서 자격 증명을 표현하는 메커니즘을 제공합니다. 이 명세는 그러한 생태계에서 사용되는 데이터를 발급, 검증, 제시 및 관리하기 위한 데이터 모델과 HTTP 프로토콜을 제공합니다.
이 절은 이 문서가 공개된 시점의 상태를 설명합니다. 현재 W3C 공개 문서 목록과 이 기술 보고서의 최신 개정판은 W3C 표준 및 초안 색인에서 확인할 수 있습니다.
이 명세는 활발히 개발 중입니다. 이 명세와 관련된 활동을 조율하는 주간 회의에 참여하고 있지 않다면, 프로덕션 시스템에 배포하는 것은 권장되지 않습니다.
이 문서는 Verifiable Credentials Working Group에서 권고안 트랙을 사용하여 작업 초안으로 공개했습니다.
작업 초안으로 공개되었다는 것이 W3C와 그 회원들의 지지를 의미하지는 않습니다.
이 문서는 초안 문서이며 언제든지 다른 문서에 의해 갱신, 대체 또는 폐기될 수 있습니다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않습니다.
이 문서는 W3C 특허 정책에 따라 운영되는 그룹이 작성했습니다. W3C는 이 그룹의 산출물과 관련하여 이루어진 특허 공개의 공개 목록을 관리합니다. 해당 페이지에는 특허 공개 지침도 포함되어 있습니다. 개인이 필수 청구항을 포함한다고 믿는 특허에 대해 실제 지식을 가지고 있는 경우, W3C 특허 정책 제6절에 따라 그 정보를 공개해야 합니다.
이 문서는 2025년 8월 18일 W3C 프로세스 문서의 적용을 받습니다.
이 절은 비규범적입니다.
Verifiable Credentials 명세 [VC-DATA-MODEL-2.0]는 디지털 자격 증명을 암호학적으로 안전하고, 프라이버시를 존중하며, 기계가 검증할 수 있는 방식으로 표현하기 위한 데이터 모델과 직렬화를 제공합니다. 이 명세는 검증 가능한 자격 증명을 발급, 검증, 제시 및 관리하기 위한 HTTP 애플리케이션 프로그래밍 인터페이스(HTTP API)와 프로토콜의 집합을 제공합니다.
검증 가능한 자격 증명을 관리할 때, 고려되는 API에는 두 가지 일반적인 유형이 있습니다. 첫 번째 유형의 API는 단일 보안 도메인 내에서 사용되도록 설계됩니다. 두 번째 유형의 API는 서로 다른 보안 도메인 간 통신에 사용될 수 있습니다. 이 명세는 두 유형의 API를 모두 정의합니다.
단일 보안 도메인 내에서 사용되도록 설계된 API는 발급자, 검증자, 또는 보유자와 같은 단일 역할을 대신하여 운영되는 시스템에서 사용됩니다. Verifiable Credentials 생태계에서 이러한 API가 제공하는 이점 중 하나는 검증 가능한 자격 증명을 관리하기 위한 유용하고, 공통적이며, 검토된 모듈식 아키텍처를 정의한다는 점입니다. 예를 들어, 이러한 접근 방식은 소프트웨어 아키텍트가 공통 구성 요소와 통합하고, 검증 가능한 자격 증명을 발급하는 시스템을 구현할 때 공통 언어를 사용하도록 돕습니다. 특정 아키텍처가 검토되었다는 점을 아는 것은 검증 가능한 자격 증명을 전문으로 하지 않는 아키텍트에게도 유익합니다. 문서화된 아키텍처와 API는 시장 경쟁을 높이고 벤더 종속성과 전환 비용을 줄입니다.
여러 보안 도메인에 걸쳐 작동하도록 설계된 API는 검증 가능한 자격 증명 상호작용에서 두 개의 서로 다른 역할 간에 통신하는 시스템이 사용합니다. 예를 들어 보유자와 검증자 간에 프레젠테이션을 전달하는 데 사용되는 API가 있습니다. 검증 가능한 자격 증명 상호작용에서 프로토콜 상호운용성을 달성하려면 이러한 API가 표준화되는 것이 필수적입니다. 이러한 API를 문서화함으로써 얻는 추가 이점은 단일 보안 도메인 API를 문서화할 때와 동일합니다. 즉 공통적이고 검토된 아키텍처와 API, 시장 경쟁 증가, 벤더 종속성과 전환 비용 감소입니다.
이 명세에는 소프트웨어 아키텍트와 구현자가 유용하게 볼 수 있는 다음 절들이 포함되어 있습니다.
이 절은 비규범적입니다.
Verifiable Credentials API는 다음 설계 목표에 맞추어 최적화되어 있습니다.
| 목표 | 설명 |
|---|---|
| 모듈성 | 구현자는 자신의 사용 사례에 필요한 API만 구현하면 되므로 발급, 검증, 제시 사이의 모듈성을 가능하게 합니다. |
| 단순성 | API 수와 선택 사항을 최소한으로 유지하여 보안 관점에서 구현하고 감사하기 쉽게 합니다. |
| 조합 가능성 | API는 소수의 단순한 API 기본 요소를 사용해 복잡한 흐름을 구현할 수 있도록 조합 가능하게 설계됩니다. |
| 확장성 | API 엔드포인트에 대한 확장이 예상되며 API 설계에서 이를 지원하여 실험과 기본 API 플랫폼 위에 부가가치 서비스를 추가할 수 있게 합니다. |
RESTful API 접근 방식이 명세의 기반으로 사용되었습니다. 일부 엔드포인트는 'controller' 리소스 명명 스타일이라고 불리는 방식을 사용합니다. JSON 문서를 설명하기 위한 미디어 유형인 JSON Schema가 API에 허용되는 입력을 정의하는 데 사용됩니다.
이 절은 비규범적입니다.
Verifiable Credentials Data Model은 세 가지 기본 역할인 발급자, 검증자, 그리고 보유자를 정의합니다.
이러한 각 역할을 수행하는 행위자는 검증 가능한 자격 증명을 교환하기 위한 API를 실현하기 위해 여러 소프트웨어 또는 서비스 구성 요소를 사용할 수 있습니다.
각 역할은 역할별 Coordinator, Service, Admin과 자체 전용 Storage Service에 연결됩니다. 또한 발급자는 발급자가 발급한 취소 가능한 자격 증명을 위한 Status Service도 관리할 수 있습니다.
어떤 구현이든 이러한 구성 요소의 일부 또는 전부를 하나의 기능적 애플리케이션으로 결합하도록 선택할 수 있습니다. 이러한 구성 요소 간의 경계와 인터페이스는 Verifiable Credential 적합 생태계 전반에서 상호운용성과 대체 가능성을 보장하기 위해 이 명세에서 정의됩니다.
이러한 아키텍처적 사고를 바탕으로, 이 API를 최대한의 대체 가능성을 위해 확장 가능한 방식으로 통합된 관련 명세의 로드맵으로 구성하고 싶을 수 있습니다. EDV와 WebKMS 같은 여러 기술은 검증 가능한 자격 증명 증명에 대해 취한 crypto suite 접근 방식의 이점을 얻을 가능성이 큽니다. 기능적으로 적합한 어떤 기술로도 실현할 수 있는 일반적인 메커니즘을 정의하면, 현재 존재하는 기능으로 기반을 마련하면서도 유연성을 확보할 수 있습니다. 이러한 방식으로, Key Services, Storage, Status와 같은 요소가 이 API의 필수 부분임을 인정하면서도 그 요소들이 어떻게 동작하는지에 대한 정의는 이미 개발 중인 명세와 앞으로 작성될 명세로 미룰 수 있을 것입니다.
구성 요소를 하나의 앱으로 집계하는 것 외에도, 구현자는 배포된 소프트웨어의 활성 인스턴스 여러 개에 걸쳐 특정 역할을 운영하도록 선택할 수 있습니다. 예를 들어, 브라우저 기반 보유자 coordinator는 웹 브라우저, 그 브라우저에서 실행되는 다양한 코드, 하나 이상의 웹 서버 (교차 출처 AJAX 또는 원격 임베디드 콘텐츠의 경우), 그리고 그 서버에서 실행되는 코드의 결합체로 간주되어야 합니다. 이러한 각 요소는 서로 다른 구성의 서로 다른 소프트웨어 패키지로 실행되며, 구성 요소의 전체 기능 중 일부만 실행합니다. 이 API의 목적상, 각 구성 요소는 배포 아키텍처와 관계없이 전체로서 요구되는 모든 기능을 충족합니다.
비규범적이라고 표시된 절뿐만 아니라, 이 명세의 모든 작성 지침, 다이어그램, 예제, 참고는 비규범적입니다. 이 명세의 그 밖의 모든 내용은 규범적입니다.
이 문서에서 MAY, MUST, MUST NOT, OPTIONAL, RECOMMENDED, REQUIRED, SHOULD, 그리고 SHOULD NOT 키워드는 여기 표시된 것처럼 모두 대문자로 나타날 때에만 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석되어야 합니다.
적합한 발급자 서비스 구현은 MUST Section 3.2.1 자격 증명 발급에 설명된 인터페이스를 제공해야 합니다. Section 3.2 발급에 설명된 다른 인터페이스도 MAY 제공될 수 있습니다.
적합한 검증자 서비스 구현은 MUST Section 3.3.1 자격 증명 검증과 Section 3.3.2 프레젠테이션 검증에 설명된 인터페이스를 제공해야 합니다. Section 3.3 검증에 설명된 다른 인터페이스도 MAY 제공될 수 있습니다.
적합한 보유자 서비스 구현은 MUST Section 3.6.4 교환 프로토콜 가져오기와 Section 3.6.5 교환에 참여에 설명된 인터페이스를 제공해야 합니다. Section 3.7 상호작용 시작, Section 3.4 프레젠테이션 요청, Section 3.5.2 프레젠테이션 생성, Section 3.5 제시, 그리고 Section 3.6 워크플로와 교환에 설명된 프로토콜, 쿼리 언어, 데이터 형식에 대한 적합성도 MAY 제공될 수 있습니다.
적합한 상태 서비스 구현은 MUST Section C.3 상태 갱신에 설명된 인터페이스를 제공해야 합니다.
적합한 워크플로 서비스 구현은 MUST Section 3.6 워크플로와 교환의 모든 인터페이스를 제공해야 합니다.
적합한 서비스 클라이언트 구현은 MUST 해당 서비스 구현이 제공하는 모든 REQUIRED 인터페이스와 통신할 수 있는 수단을 제공해야 합니다. 즉, 상태 클라이언트 구현은 상태 서비스 구현이 노출하는 모든 필수 인터페이스와 통신할 수 있는 수단을 제공합니다.
모든 구현은 이 명세를 넘어서는 기능을 MAY 제공할 수 있습니다.
이 절은 비규범적입니다.
이 문서 전체에서 사용되는 용어는 Verifiable Credentials Data Model v2.0 명세의 용어 절에서 정의됩니다.
coordinator는 관련 역할이 설정한 비즈니스 규칙과 정책을 실행합니다. 이는 흔히 해당 역할로 행동하는 단일 당사자를 위해 특별히 개발된 맞춤형 또는 독점 coordinator이며, 통제 당사자를 검증 가능한 자격 증명 생태계에 연결하는 통합 접착제입니다.
Coordinator는 구현에 따라 시각적 사용자 인터페이스를 제공할 수 있습니다. 순수 명령줄 또는 지속 실행 서비스도 이 구성 요소를 실현할 수 있습니다.
상태 서비스를 제외하면, 모든 역할 간 통신은 각 행위자를 대신하여 해당 역할을 수행하는 coordinator들 사이에서 이루어집니다.
발급자 coordinator는 자격 증명을 생성하거나 수신하는 당사자가 어떻게 인증되고 권한을 부여받는지를 포함하여, 누가 어떤 자격 증명을 받는지에 관한 규칙을 실행합니다. 일반적으로 발급자 coordinator는 발급자의 백엔드 시스템을 발급자 서비스와 통합합니다. 이 통합은 적절한 어떤 기술이든 사용합니다. 발급자 coordinator와 백엔드 서비스 사이의 인터페이스는 이 명세의 범위를 벗어납니다. 발급자 coordinator가 발급자 서비스를 구동합니다.
검증자 coordinator는 검증자 서비스와 통신하여 먼저 주어진 검증 가능한 자격 증명 또는 검증 가능한 프레젠테이션의 진정성과 적시성을 확인한 다음, 해당 검증자의 비즈니스 규칙을 적용하여 궁극적으로 그 검증 가능한 자격 증명 또는 검증 가능한 프레젠테이션을 수락하거나 거부합니다. 이러한 비즈니스 규칙에는 특정 클레임의 발급자를 평가하거나 단순히 구성된 허용 목록을 확인하는 것이 포함될 수 있습니다. 검증자 coordinator는 검증 가능한 자격 증명을 검증자의 정책에 따라 검증자에게 제출하기 위한 API를 노출합니다. 예를 들어, 검증자 coordinator는 검증 가능한 자격 증명을 검증자의 다른 서비스의 현재 사용자에게서만 수락할 수 있습니다. 이러한 규칙은 일반적으로 검증자의 기존 백엔드와 맞춤형 통합을 필요로 합니다.
보유자 coordinator는 보유자의 통제 아래 있는 자격 증명의 흐름을 발급자에서 검증자로 승인하기 위한 비즈니스 규칙을 실행합니다. 일부 배포에서는 이것이 개별 보유자에게 검증 가능한 자격 증명 저장 또는 전송을 인가하거나 승인하는 시각적 방법을 제공하는 사용자 인터페이스를 노출하는 것을 의미합니다. 보유자 coordinator의 일부 기능은 흔히 디지털 지갑이라고 불립니다. 이 API에서 보유자 coordinator는 모든 흐름을 시작합니다. 이들은 발급자에게서 검증 가능한 자격 증명을 요청합니다. 이들은 해당 검증 가능한 자격 증명을 검증자와 공유할지, 그리고 언제 공유할지를 결정합니다. 이 API 내에서는 발급자나 검증자가 검증 가능한 자격 증명의 전송을 시작할 방법이 없습니다. 많은 시나리오에서 보유자 coordinator는 개별 인간의 통제 아래 있을 것으로 예상되며, 전송을 인가하는 단계에서만이라도 사람이 검증 가능한 자격 증명의 통신에 직접 관여하도록 보장합니다. 그러나 일부 검증 가능한 자격 증명은 개인이 아니라 조직에 관한 것입니다. 조직과 관련된 보유자 coordinator를 사용하는 개인이 어떻게 행동하는지, 특히 조직 자격 증명이 그 조직의 (법적) 대리인에게 어떻게 안전하게 공유되고 그들에 의해 제시되는지는 이 명세의 범위에 포함되지 않습니다.
서비스는 관련 coordinator에 의해 구동되는 하위 수준의 API 기능을 제공하며, 인프라 제공자가 Software-as-a-Service와 같은 서비스 제공 아키텍처를 통해 검증 가능한 자격 증명 기능을 제공할 수 있도록 설계됩니다. 모든 서비스는 관련 역할을 대신하여 운영되는 인가된 coordinator에게 HTTP 엔드포인트를 노출합니다. 배포된 서비스가 자체 HTML 인터페이스를 제공할 수는 있지만, 그러한 인터페이스는 이 명세의 범위를 벗어납니다. 여기서는 서비스의 HTTP 엔드포인트만 정의됩니다.
발급자 서비스는 인가된 발급자 coordinator로부터 검증 가능한 자격 증명을 발급하라는 요청을 받아 적합한 검증 가능한 자격 증명을 반환합니다. 이 서비스는 검증 가능한 자격 증명에 대한 증명을 만들기 위해, 개인 키 또는 개인 키를 활용하는 키 서비스와 같은 암호학적 자료에 접근할 수 있습니다. 발급자 서비스와 관련 암호학적 키 관리 서비스 사이의 API는 이 명세의 범위를 벗어납니다.
검증자 서비스는 검증 가능한 자격 증명과 검증 가능한 프레젠테이션을 검증하라는 요청을 받아, 그 증명과 상태(존재하는 경우)를 확인한 결과를 반환합니다. 이 서비스는 검증 가능한 자격 증명의 진정성과 적시성만 확인하며, 필요한 비즈니스 규칙의 나머지 적용은 검증자 coordinator가 완료하도록 남겨 둡니다.
보유자 서비스는 선택적 검증 가능한 자격 증명 집합으로부터 Verifiable Presentations를 생성하라는 요청을 받아, 해당 VC를 포함하는 잘 형성되고 서명된 Verifiable Presentations를 반환합니다. 이러한 검증 가능한 프레젠테이션은 발급자와 함께 사용되어 검증 가능한 자격 증명 발급 전에 DID에 대한 제어를 입증하고, 검증자에게 특정 VC를 제시하는 데 사용됩니다.
상태 서비스는 발급자가 발급한 모든 Verifiable Credentials의 상태를 공개하고 확인하기 위한 프라이버시 보존 수단을 제공합니다. 검증자 서비스 구현자는 검증 가능한 자격 증명에서 사용하는 각 상태 명세를 참조하여 상태 확인의 프라이버시 영향을 이해하도록 권장됩니다. 검증 가능한 자격 증명 상태를 관리하는 구체적인 메커니즘에 대해서는 [VC-BITSTRING-STATUS-LIST]와 같은 잘 알려진 외부 명세를 참조하는 것이 권장됩니다.
저장소 서비스는 시스템의 각 행위자가 필요에 따라 자신의 검증 가능한 자격 증명과 해당 데이터를 저장하는 데 사용됩니다. 알려진 여러 구현은 보유자의 검증 가능한 자격 증명을 저장하기 위해 암호화된 데이터 저장소 같은 안전한 데이터 저장소를 사용하고, 보유자의 지시에 따라 그 검증 가능한 자격 증명에 대한 접근 권한을 검증자 coordinator에게 부여하기 위해 암호학적 권한 부여를 사용합니다. 이러한 저장된 자격 증명의 브라우저 내 검색은 웹 기반 검증자 coordinator가 그 데이터를 검증자와 공유하지 않고 보유자의 데이터를 통합할 수 있게 합니다. 데이터는 브라우저에만 존재합니다. 보유자 저장소에 대한 제3자 원격 접근 권한 부여는 이 API의 범위에 포함될 가능성이 높지만, 다양한 저장소 및 권한 부여 접근 방식을 지원하기 위해 확장 가능한 메커니즘을 사용하여 정의될 것으로 예상합니다.
발급자와 검증자의 저장소 솔루션은 안전한 데이터 저장소를 사용할 수도 있고 사용하지 않을 수도 있습니다. 이러한 모든 저장소 상호작용은 맞춤형 발급자와 Storage Coordinator에 의해 조정되므로, 필요한 통합은 단순히 그 맞춤형 커스터마이징의 일부가 될 수 있습니다. 우리는 다양한 구현이 여러 백엔드 저장소 플랫폼과 통합하기 쉬운 정도를 두고 경쟁할 것으로 예상합니다.
워크플로 서비스는 coordinator가 특정 사용자를 위한 특정 상호작용을 자동화할 수 있는 방법을 제공합니다. 각 역할(보유자, 발급자, 그리고 검증자)은 특정 워크플로를 실현하는 교환을 생성하고 관리하기 위해 자체 워크플로 서비스를 실행할 수 있습니다. 관리자는 특정 흐름을 지원하도록 워크플로 시스템을 구성합니다. 그런 다음 비즈니스 규칙이 정당화할 때 coordinator는 자신의 워크플로 서비스에서 교환을 만들고 인가된 당사자에게 해당 교환에 대한 접근 권한을 제공합니다.
관리 서비스는 다른 각 구성 요소에 구성되고 관리될 방법이 필요하다는 점을 인정하되, 그 구성의 인터페이스나 수단을 규정하지 않습니다. 일부 구성 요소는 JSON 파일을 사용해 명령줄 인터페이스를 구동할 수 있습니다. 다른 구성 요소는 HTML 페이지를 노출할 수 있습니다. 서로 다른 구현은 관리 기능의 강력함, 용이성, 유연성을 두고 경쟁할 것으로 예상되므로, 구성은 대체로 이 명세의 범위를 벗어납니다. 다만 Section 3.6.1 워크플로 생성처럼 일부 구성 메커니즘이 제공되는 곳도 있으며, 여기서는 일부 구성 매개변수를 표준화하는 데 폭넓은 합의가 있었습니다. 시장이 성숙함에 따라 구성 표준화의 다른 영역도 이 명세의 향후 버전에서 나타날 수 있습니다.
이 명세에서 정의된 API는 시스템 관리자가 마련한 관련 구성을 가진 특정 인스턴스에 연결되어 있다고 가정합니다. 클라이언트가 특정 인스턴스의 엔드포인트를 호출하면, 그 인스턴스는 클라이언트가 제공한 구성과 옵션을 사용하여 작업을 실행합니다.
예를 들어, /credentials/issue 엔드포인트는
/instances/12345/credentials/issue와 같은 더 긴 URL의 끝에 제공될 수 있습니다.
이 경우 발급에 사용할 암호학적 키, 상태 목록의 관여 여부,
발급할 자격 증명의 유형, 자격 증명 형식, 그리고 엔드포인트에서 가능한 추가 옵션을 알도록
구성된 것은 바로 인스턴스입니다.
특정 인스턴스를 호출하는 소프트웨어 클라이언트는 인스턴스를 구성할 능력이 없거나, 적절히 사용하기 위해 필요한 세부사항 외에는 관리자가 그 인스턴스에서 수행한 설정을 알지 못할 수 있습니다. 인스턴스를 구성하기 위한 관리 엔드포인트는 구현에서 제공될 수 있지만, 반드시 HTTP API로 노출되는 것은 아닙니다. 구성은 구성 파일이나 그래픽 인터페이스를 통해서도 수행될 수 있습니다.
coordinator 인스턴스는 다양한 사용 사례 또는 복잡한 흐름이 있는 사용 사례를 지원하기 위해 여러 서비스 인스턴스에 접근할 수 있습니다. 서비스는 배포 시점에 coordinator에게 알려져 있을 것으로 예상되므로, 서비스 인스턴스 구성의 런타임 발견은 이 명세에서 정의되지 않습니다.
각 coordinator 또는 서비스 인스턴스는 그 동작을 구동하는 특정 구성과 연결됩니다. 이 절은 그러한 구성 중 일부가 어떻게 수행될 수 있는지를 포함합니다.
특정 인스턴스의
base URL에는 제한이 없습니다.
이 명세 전반에서 사용되는 URL 경로는 절대 경로로 표시되며,
그 base URL은 서버의 호스트 이름(예:
website.example), 하위 도메인(예: api.website.example), 또는
해당 도메인 내의 경로(예: website.example/api)일 MAY
수 있습니다.
이 API는 적대적인 행위자를 포함할 수 있는 다양한 네트워킹 환경에 배포될 수 있습니다. 그 결과, 적합한 서비스 구현은 특정 유형의 요청을 수행할 때 적합한 서비스 클라이언트 구현이 안전한 권한 부여 기술을 활용하도록 요구합니다. 이 문서에서 정의된 각 HTTP 엔드포인트는 요청을 수행할 때 권한 부여가 필요한지 여부를 명시합니다. 이 절의 뒤에서 논의하는 금지된 권한 부여 프로토콜 부류를 제외하고, 이 API는 권한 부여 메커니즘에 관해 독립적입니다.
이 API는 Verifiable Credentials의 발급, 소유, 제시 및/또는 검증을 필요로 하는 많은 시나리오에서 일반적이고 유용하도록 의도되었습니다. 이를 위해 구현자는 다음과 같은 사용 사례 분류를 고려하는 것이 좋습니다.
이 절의 나머지는 적합한 구현에서 사용하도록 고려된 권한 부여 기술의 예를 제공합니다. 다른 동등한 권한 부여 기술도 사용할 수 있습니다. 구현자는 비표준 또는 레거시 권한 부여 기술을 사용하지 않도록 주의해야 합니다.
이 API에 대한 요청은 사용자 이름과 비밀번호 또는 유사한 값과 같은 장기 정적 자격 정보를 해당 요청에 포함하는 어떠한 권한 부여 프로토콜도 MUST NOT 사용해야 합니다. 그러한 금지된 프로토콜의 예는 HTTP Basic Authentication [RFC7617]입니다.
OAuth 2.0 Authorization Framework [RFC6749]가 권한 부여에 사용되는 경우, 클라이언트가 사용하는 접근 토큰은 OAuth 2.0 Bearer Tokens [RFC6750] 또는 기타 유효한 OAuth 2.0 토큰 유형일 MAY 수 있습니다. 접근 토큰을 요청하기 위해 유효한 OAuth 2.0 grant type은 무엇이든 MAY 사용될 수 있습니다.
| VCALM OAuth 2.0 Scope Syntax |
|---|
|
scope = operation ":" path-absolute ([RFC3986]에
정의됨) operation = "read" / "write" |
read 연산은 시스템에서 리소스를 생성하거나 갱신하지 않는 작업을
제공된 경로에서, 또는 제공된 경로를 접두사로 포함하는 모든 경로에서
수행할 수 있게 합니다. write 연산은 시스템에서 리소스를 생성
및/또는 갱신하는 작업을 제공된 경로에서, 또는 제공된 경로를 접두사로 포함하는
모든 경로에서 수행할 수 있게 합니다.
OAuth 2.0 scope의 예는 아래와 같습니다.
read:/는 특정 인스턴스의 모든 API를 통한 읽기를 허용합니다.
write:/는 특정 인스턴스의 모든 API를 통한 생성과 수정을 허용합니다.
read:/exchanges는 특정 워크플로 인스턴스에서 교환을 읽는 것을 허용합니다.
write:/credentials/issue는 특정 발급자 인스턴스의 자격 증명 발급
API에 쓰는 것을 허용합니다.
read:/와 write:/ 같은 광범위한 OAuth 2.0 scope는
다중 테넌트 환경에서 보안 취약점으로 이어질 수 있습니다. 예를 들어 여러 발급자
coordinator가 같은
발급자 서비스에 호스팅된 서로 다른 발급자
인스턴스를 사용할 때 그렇습니다. 구현자는 JSON Web Token으로
표현된 접근 토큰이 그 접근 토큰이 적용되는 특정 인스턴스를 식별하는
aud(audience) 클레임을 포함하도록 하여, 접근 토큰을 특정 인스턴스에
고정할 수 있게 해야 합니다. OAuth 2.0 scope는 보안 관리자에게 지나치게
부담이 되지 않는 범위에서 가능한 한 좁게 유지하는 것이 좋습니다.
다음 절에서 정의된 일부 엔드포인트는 options
객체를 받습니다. 각 인스턴스를 구성할 때 options 객체의 모든 속성은
OPTIONAL입니다. 이러한 속성은 배포별 필요를 충족하기 위한 것이며,
그 필요는 달라질 수 있기 때문입니다. 따라서 어떤 인스턴스 구성은
클라이언트가 특정 데이터를 그 인스턴스에 전달하지 못하도록 하기 위해
일부 options 속성의 클라이언트 사용을 MAY 금지할 수
있습니다. 마찬가지로, 인스턴스 구성은
클라이언트가 일부 options 속성을 포함하도록 MAY 요구할 수
있습니다.
구현은 options 객체를 추가 속성으로 확장할 MAY
수 있습니다.
확장 속성은 구현별이므로, 필수여서는 안 됩니다. 이는 클라이언트가 특정 구현을 사용하도록 수정되어야 하는 상황을 피함으로써 상호운용성을 유지하기 위한 것입니다.
확장 options 속성을 추가할 때는 클라이언트에 선택 가능성을 제공하는 것이
필요한지 고려하십시오. 필요하지 않다면 인스턴스 구성을 사용하여
API 기능을 변경하는 접근 방식이 더 바람직할 수 있습니다.
구현은 엔드포인트가 이해하지 못하거나 처리 방법을 알지 못하는 데이터, 옵션 또는 옵션 값을 받으면 오류를 MUST 발생시켜야 합니다.
이 명세에서 정의한 API 엔드포인트로 보내지거나 그로부터 수신되는 요청과 응답의
모든 엔티티 본문은 JSON으로 직렬화되어야 하며,
미디어 유형 값이 application/json인 Content-Type 헤더를
포함해야 MUST 합니다.
구현자는 자신의 구현이 처리하는 Verifiable Credentials의 페이로드 크기에 주의를 기울이는 것이 권장됩니다.
프레젠테이션은 많은 양의 자격 증명을 묶을 수 있으며, 이는 구현자가 예상한 것보다 더 큰 요청 크기를 초래할 수 있습니다. 이는 상호운용성 문제의 위험을 높입니다.
각 검증 가능한 자격 증명당 기본 최대 크기는 10MB로 RECOMMENDED되며, 필요할 경우 더 큰 크기를 구성할 가능성을 둔 상호운용성 기준선으로 사용됩니다. 이는 대부분의 문서 기반 데이터베이스 저장소 솔루션의 16MB 크기 제한도 수용합니다.
기본적으로 큰 바이너리 값은 링크되고 해시가 포함될 것으로 예상됩니다 (그렇게 하지 않을 프라이버시 이유가 없는 한).
이 절에는 적합한 구현을 만들 때 따라야 하는 HTTP API 엔드포인트 정의와 구현 지침이 포함되어 있습니다.
이 절은 엔드포인트가 호출될 것으로 예상되는 구성 요소별로 VC-API의 모든 엔드포인트에 대한 개요를 제공합니다. 어떤 구성 요소 아래에 목록이 없다면, 이는 현재 VC-API가 해당 구성 요소에 대한 엔드포인트를 지정하지 않는다는 의미입니다.
아래는 발급자 coordinator가 노출할 것으로 예상되는 모든 엔드포인트와, 해당 엔드포인트를 호출할 것으로 예상되는 구성 요소입니다.
| 엔드포인트 | 예상 호출자 | 정의 |
|---|---|---|
| GET /interactions/{interactionId} | 제공된 URL을 가진 누구나 | 3.7.1 상호작용 URL 형식 |
| POST /callbacks/{localCallbackId} | 워크플로 서비스 | 3.6.7 교환 단계 콜백 |
아래는 발급자 서비스가 노출할 것으로 예상되는 모든 엔드포인트와, 해당 엔드포인트를 호출할 것으로 예상되는 구성 요소입니다.
| 엔드포인트 | 예상 호출자 | 정의 |
|---|---|---|
| POST /credentials/issue | 발급자 Coordinator, 워크플로 서비스 | 3.2.1 자격 증명 발급 |
| GET /credentials/{id} | 발급자 Coordinator, 보유자 Coordinator, 워크플로 서비스 | 3.2.2 특정 자격 증명 가져오기 |
| DELETE /credentials/{id} | 발급자 Coordinator, 보유자 Coordinator | 3.2.3 특정 자격 증명 삭제 |
아래는 검증자 coordinator가 노출할 것으로 예상되는 모든 엔드포인트와, 해당 엔드포인트를 호출할 것으로 예상되는 구성 요소입니다.
| 엔드포인트 | 예상 호출자 | 정의 |
|---|---|---|
| GET /interactions/{interactionId} | 제공된 URL을 가진 누구나 | 3.7.1 상호작용 URL 형식 |
| POST /callbacks/{localCallbackId} | 워크플로 서비스 | 3.6.7 교환 단계 콜백 |
아래는 검증자 서비스가 노출할 것으로 예상되는 모든 엔드포인트와, 해당 엔드포인트를 호출할 것으로 예상되는 구성 요소입니다.
| 엔드포인트 | 예상 호출자 | 정의 |
|---|---|---|
| POST /credentials/verify | 검증자 Coordinator, 워크플로 서비스 | 3.3.1 자격 증명 검증 |
| POST /presentations/verify | 검증자 Coordinator, 워크플로 서비스 | 3.3.2 프레젠테이션 검증 |
| POST /challenges | 검증자 Coordinator, 워크플로 서비스 | 3.3.3 챌린지 생성 |
아래는 보유자 coordinator가 노출할 것으로 예상되는 모든 엔드포인트와, 해당 엔드포인트를 호출할 것으로 예상되는 구성 요소입니다.
| 엔드포인트 | 예상 호출자 | 정의 |
|---|---|---|
| GET /interactions/{interactionId} | 제공된 URL을 가진 누구나 | 3.7.1 상호작용 URL 형식 |
| POST /callbacks/{localCallbackId} | 워크플로 서비스 | 3.6.7 교환 단계 콜백 |
아래는 보유자 서비스가 노출할 것으로 예상되는 모든 엔드포인트와, 해당 엔드포인트를 호출할 것으로 예상되는 구성 요소입니다.
| 엔드포인트 | 예상 호출자 | 정의 |
|---|---|---|
| POST /credentials/derive | 보유자 Coordinator, 워크플로 서비스 | 3.5.1 자격 증명 파생 |
| GET /credentials/{id} | 발급자 Coordinator, 보유자 Coordinator, 워크플로 서비스 | 3.2.2 특정 자격 증명 가져오기 |
| DELETE /credentials/{id} | 발급자 Coordinator, 보유자 Coordinator | 3.2.3 특정 자격 증명 삭제 |
| GET /presentations | 보유자 Coordinator, 워크플로 서비스 | 3.5.3 프레젠테이션 가져오기 |
| POST /presentations | 보유자 Coordinator, 워크플로 서비스 | 3.5.2 프레젠테이션 생성 |
| GET /presentations/{id} | 보유자 Coordinator, 워크플로 서비스 | 3.5.4 특정 프레젠테이션 가져오기 |
| DELETE /presentations/{id} | 보유자 Coordinator | 3.5.5 특정 프레젠테이션 삭제 |
아래는 상태 서비스가 노출할 것으로 예상되는 모든 엔드포인트와, 해당 엔드포인트를 호출할 것으로 예상되는 구성 요소입니다.
| 엔드포인트 | 예상 호출자 | 정의 |
|---|---|---|
| POST /status-lists | 발급자 서비스 | C.1 상태 목록 생성 |
| GET /status-lists/{id} | 공개 | C.2 상태 목록 가져오기 |
| POST /credentials/status | 발급자 서비스 | C.3 상태 갱신 |
아래는 Workflow Service가 노출할 것으로 예상되는 모든 엔드포인트와, 해당 엔드포인트를 호출할 것으로 예상되는 구성 요소입니다.
| 엔드포인트 | 예상 호출자 | 정의 |
|---|---|---|
| POST /workflows | 관리자 | 3.6.1 워크플로 생성 |
| GET /workflows/{localWorkflowId} | 관리자 | 3.6.2 워크플로 구성 가져오기 |
| POST /workflows/{localWorkflowId}/exchanges | Coordinator | 3.6.3 교환 생성 |
| GET /workflows/{localWorkflowId}/exchanges/{localExchangeId} | Coordinator | 3.6.6 교환 상태 가져오기 |
| POST /workflows/{localWorkflowId}/exchanges/{localExchangeId} | 누구나 | 3.6.5 교환에 참여 |
| GET /workflows/{localWorkflowId}/exchanges/{localExchangeId}/protocols | 검증자 Coordinator, 보유자 Coordinator | 3.6.4 교환 프로토콜 가져오기 |
| POST /{inviteId}/invite-request/response | /interactions/{interactionId}가 포함된 URL에 POST한 누구든지 | 3.7.4 상호작용 프로토콜 응답 |
검증 가능한 자격 증명을 발급하기 위해 다음 API가 정의됩니다.
| 엔드포인트 | 설명 |
|---|---|
| GET /credentials/{id} | ID로 자격 증명 또는 검증 가능한 자격 증명을 가져옵니다. credential.id가 설정되어 있지 않지만 관련 credentialId 값이 있는 자격 증명을 가져오려면 대신 credentialId를 전달합니다. |
| DELETE /credentials/{id} | ID로 자격 증명 또는 검증 가능한 자격 증명을 삭제합니다. credential.id가 설정되어 있지 않지만 관련 credentialId 값이 있는 자격 증명을 삭제하려면 대신 credentialId를 전달합니다. |
| POST /credentials/issue | 자격 증명을 발급하고 응답 본문으로 반환합니다. |
| POST /credentials/status | 발급된 자격 증명의 상태를 갱신합니다 |
| POST /status-lists | 새 상태 목록을 생성합니다 |
| GET /status-lists/{id} | 상태 목록 자격 증명을 검색합니다 |
이 엔드포인트는 검증 가능한 자격 증명을 발급하는 데 사용됩니다.
application/vc 이외의 미디어 유형(예:
application/mdoc, application/vc+sd-jwt,
application/vcb;barcode-format=qr_code, 또는
application/vcb;barcode-format=pdf417)으로
자격 증명을 발급하려면,
응답에서 EnvelopedVerifiableCredential를
반환할 수 있습니다.
POST /credentials/issue - 자격 증명을 발급하고 응답 본문으로 반환합니다.
/credentials/issue 엔드포인트는 POST를 받을 때 다음 스키마를 사용합니다.
| 속성 | 설명 |
|---|---|
credential [object] |
발급을 의도한 W3C Verifiable Credential입니다. 다음 형식의 객체여야
MUST 합니다.
|
options [object] |
자격 증명이 발급되는 방식을 지정하기 위한 옵션입니다. 다음 형식의 객체여야
MUST 합니다.
|
/credentials/issue 엔드포인트는 POST를 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 201 | 자격 증명이 성공적으로 발급되었습니다! content-type: application/json
다음 형식의 객체:
|
| 400 | 다음 이유 중 하나로 인해 요청을 처리할 수 없습니다.
- 제공된 'issuer' 값이 예상된 구성과 일치하지 않습니다.
- Bad Request를 초래하는 다른 조건입니다.
|
사용 사례에서 발급자 인스턴스가 제공된 credential에 여러 proof를
첨부해야 하는 경우, 인스턴스는 /credentials/issue 엔드포인트에 대한
단일 호출에 대한 응답으로 이러한 모든 proof를 첨부해야
MUST 합니다.
제공된 credential에 이미 하나 이상의 proof가 포함되어 있는 경우,
동작은 발급자 인스턴스의 구성에 의해 결정됩니다. 발급 인스턴스는
기존 proof를 다음 방식 중 하나로 처리하도록 구성되어야
SHOULD 합니다.
previousProof 속성을 사용하여 chain 관계를 설정할 수 있습니다.
proof 값이 포함된
credential 값이 제공되면 오류를 반환합니다.
사용되는 구체적인 접근 방식은 발급자 인스턴스의 구성과 검증 가능한 자격 증명의 의도된 사용 사례에 따라 달라집니다.
GET /credentials/{id} - ID로 자격 증명 또는 검증 가능한 자격 증명을 가져옵니다. credential.id가 설정되어 있지 않지만 관련 credentialId 값이 있는 자격 증명을 가져오려면 대신 credentialId를 전달합니다.
/credentials/{id} 엔드포인트는 GET을 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 200 | 자격 증명이 검색되었습니다 content-type: application/json
검증 가능한 자격 증명에 대한 성공적인 요청에서 반환되는 형식입니다.
다음 형식의 객체여야 MUST 합니다.
|
| 400 | Bad Request |
| 401 | Not Authorized |
| 404 | 자격 증명을 찾을 수 없습니다 |
| 410 | Gone! 여기에 데이터가 없습니다 |
| 418 | I'm a teapot - 양 당사자 사이에서 사전에 합의된 시나리오 밖에서는
반환되어서는 MUST 안 됩니다 |
발급자 서비스 또는 보유자 서비스는 발급된 검증 가능한 자격 증명을 장기간 저장할 수 있습니다. 이렇게 하는 경우, 그러한 검증 가능한 자격 증명을 삭제하는 것이 유용할 수 있습니다. 예를 들어, 발급자는 잊힐 권리와 같은 규제 요구 사항 때문에 그렇게 해야 할 수 있습니다. 시스템에서 검증 가능한 자격 증명을 제거하는 것과 관련된 추가 고려 사항은 Section B.3 삭제를 참조하십시오.
DELETE /credentials/{id} - ID로 자격 증명 또는 검증 가능한 자격 증명을 삭제합니다. credential.id가 설정되어 있지 않지만 관련 credentialId 값이 있는 자격 증명을 삭제하려면 대신 credentialId를 전달합니다.
/credentials/{id} 엔드포인트는 DELETE를 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 202 | 자격 증명이 삭제되었습니다 - soft delete와 처리 시간이 가정되므로
기본적으로 202입니다 |
| 400 | Bad Request |
| 401 | Not Authorized |
| 404 | 자격 증명을 찾을 수 없습니다 |
| 410 | Gone! 여기에 데이터가 없습니다 |
검증 가능한 자격 증명을 검증하기 위해 다음 API가 정의됩니다.
| 엔드포인트 | 설명 |
|---|---|
| POST /credentials/verify | verifiableCredential를 검증하고 응답 본문에 verificationResult를 반환합니다. |
| POST /presentations/verify | Presentation과 그 안에 포함된 모든 Verifiable Credentials를 검증하고, 상세한 검증 결과를 반환합니다. |
| POST /challenges | 이 엔드포인트에 빈 본문을 전달하면 challenge 문자열을 생성하여 응답 본문에 반환합니다. |
이 엔드포인트는 검증 가능한 자격 증명을 검증하는 데 사용됩니다.
application/vc 이외의 미디어 유형(예:
application/mdoc, application/vc+sd-jwt,
application/vcb;barcode-format=qr_code, 또는
application/vcb;barcode-format=pdf417)의 자격 증명을 검증하려면,
요청에 EnvelopedVerifiableCredential를
제공할 수 있습니다.
POST /credentials/verify - verifiableCredential를 검증하고 응답 본문에 verificationResult를 반환합니다.
/credentials/verify 엔드포인트는 POST를 받을 때 다음 스키마 중 하나를 사용합니다.
| 속성 | 설명 |
|---|---|
verifiableCredential [object] |
다음 형식의 객체:
|
options [object] |
자격 증명이 검증되는 방식을 지정하기 위한 옵션입니다. 다음 형식의 객체여야
MUST 합니다.
|
또는 /credentials/verify 엔드포인트는 다음 스키마도 사용할 수 있습니다.
| 속성 | 설명 |
|---|---|
verifiableCredential [object] |
enveloped verifiable credential을 verifiable presentation의
verifiableCredential 속성과 연결하는 데 사용되는 객체입니다. 다음 형식의
객체여야 MUST 합니다.
|
options [object] |
자격 증명이 검증되는 방식을 지정하기 위한 옵션입니다. 다음 형식의 객체여야
MUST 합니다.
|
/credentials/verify 엔드포인트는 POST를 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 200 | Verifiable Credential이 성공적으로 검증되었습니다! content-type: application/json
VerifiableCredential에 대한 검증 프로세스의 결과를 보고하는 객체입니다.
다음 형식의 객체여야 MUST 합니다.
|
| 400 | 잘못된 입력! |
이 엔드포인트는 검증 가능한 프레젠테이션과, 기본적으로 그 안에 포함된 모든 검증 가능한 자격 증명을 검증하는 데 사용됩니다.
검증 프로세스에는 다음이 포함됩니다.
비즈니스 규칙 검증(예: credential subject가 presentation holder와 일치하는지 검증하거나, 누가 어떤 credential을 제시할 수 있는지에 대한 권한 부여 정책)은 이 검증 엔드포인트의 범위를 벗어나며, 호출 애플리케이션이 수행해야 합니다.
POST /presentations/verify - Presentation과 그 안에 포함된 모든 Verifiable Credentials를 검증하고, 상세한 검증 결과를 반환합니다.
/presentations/verify 엔드포인트는 POST를 받을 때 다음 스키마 중 하나를 사용합니다.
| 속성 | 설명 |
|---|---|
verifiablePresentation [object] |
다음 형식의 객체:
|
options [object] |
프레젠테이션이 검증되는 방식을 지정하기 위한 옵션입니다.
구현은 검증 동작을 제어하기 위해 이 객체를 추가 속성으로 확장할
MAY 수 있습니다. 일반적인 확장에는 포함된
credential의 검증을 비활성화하는 옵션(예: 디버깅용 또는 presentation-level
검증만 필요한 경우), status 확인, 유효 기간 검증, proof 검증 및
schema 검증과 같은 credential 측면의 세분화된 검증 제어, 그리고
프레젠테이션 내 특정 credential에 대한 선택적 검증 제어가 포함될 수 있습니다.
credential 검증이 비활성화되거나 제한될 때 API는 조합적입니다.
개별 credential은 /credentials/verify 엔드포인트를 사용하여 별도로
검증할 수 있습니다. 다음 형식의 객체여야 MUST 합니다.
|
또는 /presentations/verify 엔드포인트는 다음 스키마도 사용할 수 있습니다.
| 속성 | 설명 |
|---|---|
presentation [object] |
proof가 없는 JSON-LD Verifiable Presentation입니다. 다음 형식의 객체여야
MUST 합니다.
|
| 속성 | 설명 |
|---|---|
verifiablePresentation [object] |
enveloped verifiable presentation을 표현하는 데 사용되는 객체입니다. 다음 형식의
객체여야 MUST 합니다.
|
options [object] |
프레젠테이션이 검증되는 방식을 지정하기 위한 옵션입니다.
구현은 검증 동작을 제어하기 위해 이 객체를 추가 속성으로 확장할
MAY 수 있습니다. 일반적인 확장에는 포함된
credential의 검증을 비활성화하는 옵션(예: 디버깅용 또는 presentation-level
검증만 필요한 경우), status 확인, 유효 기간 검증, proof 검증 및
schema 검증과 같은 credential 측면의 세분화된 검증 제어, 그리고
프레젠테이션 내 특정 credential에 대한 선택적 검증 제어가 포함될 수 있습니다.
credential 검증이 비활성화되거나 제한될 때 API는 조합적입니다.
개별 credential은 /credentials/verify 엔드포인트를 사용하여 별도로
검증할 수 있습니다. 다음 형식의 객체여야 MUST 합니다.
|
/presentations/verify 엔드포인트는 POST를 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 200 | 검증 프로세스가 성공적으로 완료되었습니다. 응답 본문에는
presentation과 그 안에 포함된 credential이 검증을 통과했는지 또는
실패했는지를 나타내는 상세 결과가 포함됩니다.
<code>200</code> 상태는 presentation 및/또는 credential이
유효하거나 유효하지 않다고 판단되었는지와 관계없이,
검증 프로세스 자체가 성공했음을 나타냅니다.
content-type: application/json
VerifiablePresentation에 대한 검증 프로세스의 결과를 보고하는 객체입니다.
다음 형식의 객체여야 MUST 합니다.
|
| 400 | 검증 프로세스를 수행할 수 없게 만든 잘못되었거나 malformed 입력입니다.
이는 검증 실패가 아니라 요청 형식, 구조 또는 매개변수의 문제를
나타냅니다.
|
| 413 | 페이로드가 너무 큽니다 |
| 429 | 요청 rate limit을 초과했습니다. |
POST /challenges - 이 엔드포인트에 빈 본문을 전달하면 challenge 문자열을 생성하여 응답 본문에 반환합니다.
/challenges 엔드포인트는 POST를 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 200 | Challenge가 생성되었습니다 content-type: application/json
challenge를 포함하는 객체입니다. 다음 형식의 객체여야
MUST 합니다.
|
| 400 | 잘못되었거나 malformed 입력 |
인스턴스는 검증 중 사용할 challenge를 생성하고, challenge가
options.challenge로 검증 엔드포인트에 전달된 횟수를
추적해야 합니다.
검증 가능한 자격 증명과 분산 식별자 기반 인증을 사용할 때, 한 당사자가 다른 당사자로부터 데이터를 요청해야 하는 경우가 많습니다. 이 절은 그러한 요청의 일반 형식을 설명하고, 구체적인 검증 가능한 프레젠테이션 요청 형식도 제공합니다.
검증 가능한 프레젠테이션 요청은 검증자가 보유자에게 프레젠테이션을 요청하는 요청입니다. 하나 이상의 credential이 검증 가능한 프레젠테이션으로 감싸진 형태를 요청하기 위해, 검증자는 보유자로부터 받기를 원하는 하나 이상의 credential을 설명하는 JSON 요청을 구성합니다. 요청의 일반 형식은 다음과 같습니다.
{
// one or more requests for verifiable credentials
"query": [{
"type": "QueryByExample",
// query details specific to QueryByExample...
}],
// The target security domain, such as a website domain, to include in
// the verifiable presentation
"domain": "domain.example",
// The random challenge string to include in the verifiable presentation
"challenge": "f63cb0d2-760e-11f0-a2b1-67febb854a5f"
}
query 속성은 프레젠테이션의 데이터 요청을 위한 주요 확장 지점
메커니즘 역할을 합니다. 이 문서는 공통 쿼리 메커니즘(Section 3.4.2 예제로
쿼리 참조)을 정의하지만,
모든 query 객체는 다음 형식입니다.
type
속성을 정의해야 MUST 합니다.
"query by example" credential query 형식은 개발자가 특정 비즈니스 프로세스를 가능하게 하기 위해 하나 이상의 검증 가능한 자격 증명에서 필요한 claim을 쉽게 요청할 수 있도록 설계되었습니다. 쿼리는 검증자가 신뢰하는 하나 이상의 발급자 같은 다른 정보도 지정할 수 있습니다.
QueryByExample 쿼리의 credentialQuery 속성은 단일 객체입니다.
여러 쿼리를 결합하기 위한 논리적 "AND" 및 "OR" 연산은 Section 3.4.5 쿼리의 논리 연산에 설명된 것처럼
query level의 group 속성을 통해 처리됩니다. 동일한
group 값을 가진 여러 쿼리는 "AND" 연산으로 처리되고, 서로 다른
group 값이 있거나 group 값이 없는 쿼리는 "OR" 연산으로 처리됩니다.
{
"query": [{
"type": "QueryByExample",
"credentialQuery": {
// (Optional) Reason for requesting this credential that
// may be shown to a user by their software
"reason": "We need to know if you are an alumni of this school.",
// (Optional) An example of the credential being requested
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2"
],
"type": "ExampleAlumniCredential",
// (Optional) Select credential based on credential subject type
"credentialSubject": {
"type": "Alumni"
}
},
// (Optional) Specify credentials from particular acceptedIssuers or
// delegates of the authority
"acceptedIssuers": [{
"issuer": "did:web:authority.example"
}]
}
}],
"challenge": "3182bdea-63d9-11ea-b6de-3b7c1404d57f",
"domain": "reunion.example"
}
credentialQuery 객체는 다음 속성을 지원합니다.
| 속성 | 설명 |
|---|---|
| reason | credential이 요청되는 이유에 대해 사람이 읽을 수 있는 설명을 제공하는 OPTIONAL string입니다. 이는 보유자에게 그들의 소프트웨어에 의해 표시될 MAY 수 있습니다. |
| example |
요청되는 credential의 예를 제공하는 OPTIONAL 객체입니다.
필요한 claim을 나타내기 위해 @context, type 및 선택적으로
credentialSubject 필드를 포함합니다.
|
| acceptedIssuers |
검증자가
검증 가능한
자격 증명의 발급자로 인식하고 수락하는 엔티티를 식별하는
항목 또는 항목을 포함하는 목록의 OPTIONAL 배열입니다.
각 항목은 1) 수신된 검증 가능한
자격 증명의 issuer 속성에서
발급자를 식별하는
[URL]이거나, 2) 수신된 검증 가능한
자격 증명의 issuer 속성에서 발급자를 식별하는
[URL] 값을 가진 id 속성을 포함하는
객체이거나, 3) type 속성이
RecognizedEntityCredential로 설정되고 id 속성이
Recognized Entities
v1.0
명세에서 정의된 그러한 credential을 가리키는 [URL] 값을 가진 객체와 연결된
recognizedIn 속성을 포함하는 객체여야 MUST 합니다.
이 목록에는 검증자가 허용할 수 있는
인식된 발급자가 포함됩니다. 유효한 예시 값은 다음과 같습니다.
|
| acceptedCryptosuites |
검증자가 수락할
암호학적 proof suite를 지정하는 OPTIONAL 배열입니다.
각 요소는 Data Integrity cryptosuite 이름을 참조하는 cryptosuite
속성 또는 레거시용 Ed25519Signature2020을 가진 객체여야
SHOULD 합니다.
(하위 호환성을 위해 string 값도 MAY 사용될 수 있으며
cryptosuite 이름으로 해석됩니다.) 이를 통해 보유자는 적절한
proof 형식을 선택할 수 있습니다. 이 속성은 enveloped credentials에만 적용되는
acceptedEnvelopes와 독립적으로 사용될 MAY
수 있습니다. 유효한 예시 값은 다음과 같습니다.
|
| acceptedEnvelopes |
검증자가 수락할
envelope 형식을 지정하는 OPTIONAL 배열입니다.
각 요소는 envelope의 미디어 유형을 참조하는 mediaType
속성을 가진 객체여야 SHOULD 합니다.
(하위 호환성을 위해 string 값도 MAY 사용될 수 있으며
미디어 유형으로 해석됩니다.) 이를 통해 보유자는
기본 Data Integrity 형식 이외의 형식으로 credential을 제공할 수 있습니다.
이 속성은 허용 가능한 cryptosuite로 서명된 JSON-LD credential에만 적용되는
acceptedCryptosuites와 독립적으로 사용될 MAY
수 있습니다. 유효한 예시 값은 다음과 같습니다.
|
QueryByExample을 위한 JSON Schema는
소프트웨어 시스템에 통합할 수 있도록 별도 파일로 제공됩니다.
다음 예제는 허용되는 cryptosuite와 envelope 형식을 지정하여 보유자가 적절한 proof 메커니즘을 선택할 수 있게 하는 QueryByExample을 보여 줍니다.
{
"query": [{
"type": "QueryByExample",
"credentialQuery": {
"reason": "Please present your PermanentResidentCard to complete the verification process.",
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/citizenship/v3"
],
"type": ["PermanentResidentCard"],
"credentialSubject": {
"birthCountry": ""
}
},
"acceptedCryptosuites": [
{"cryptosuite": "eddsa-rdfc-2022"},
{"cryptosuite": "ecdsa-rdfc-2019"},
{"cryptosuite": "bbs-2023"},
{"cryptosuite": "ecdsa-sd-2023"}
],
"acceptedEnvelopes": [
{"mediaType": "application/jwt"},
{"mediaType": "application/vc+sd-jwt"}
]
}
}],
"challenge": "9876fedc-ba98-7654-3210-fedcba987654",
"domain": "immigration.example"
}
위 예제에서 검증자는
나열된 cryptosuite 중
어느 것으로 보안화된 credential도 수락하겠다고 나타냅니다. bbs-2023와
ecdsa-sd-2023를 포함함으로써, 검증자는 selective
disclosure proof가 허용됨을 신호하여, 보유자가 전체 credential이 아니라
birthCountry 필드만 공개할 수 있게 합니다.
acceptedEnvelopes 속성은 JWT 기반 envelope 형식도 허용됨을 나타냅니다.
Query By Example에 포함된 모든 필드는 필수 필드입니다. 이는 selective disclosure를
활성화하기 위해 Query By Example을 사용할 때, 요청자가 자신의 사용 사례에 필요하지 않은
필드를 쿼리에 포함하지 않도록 주의해야 함을 의미합니다. Query By Example은 "optional"
필드를 나타낼 방법을 제공하지 않습니다. 따라서 쿼리에 응답하는 wallet이
요청된 것 이상의 정보를 응답에서 공개하지 않도록 보장해야 합니다. 참고: 검증 가능한
자격 증명을 보호하는 일부 메커니즘은 selective disclosure를 허용하지 않습니다. 이러한 경우에는
요청된 정보를 보내기 위해 요청되지 않은 정보도 전송해야 할 수 있습니다. Digital wallets는
어떤 정보가 공유될지 사용자에게 알려 줄 것으로 기대됩니다.
예상 값에 대한 어떤 진술도 없이 필드를 요청하려면, 요청자는 요청에 해당 필드를 포함하고
값을 빈 문자열로 남길 수 있습니다. 예를 들어, 요청자가 이름이 필요한 경우
선택적 "credentialSubject" 객체에 단일 필드
"firstName": ""를 포함할 수 있습니다.
이렇게 하면 wallet은 요청된 credential의 firstName만 응답하고
다른 필드가 포함될 것이라는 기대는 없게 할 수 있습니다. _이는 wallet이 쿼리에 대한
응답에 추가 필드를 포함하여 과도하게 공유하는 것을 막지는 않습니다._
selective disclosure cryptosuite가 허용됨을 신호하려면, 검증자는
acceptedCryptosuites 배열에 bbs-2023 또는
ecdsa-sd-2023 같은 cryptosuite를 포함해야
SHOULD 합니다.
이 절은 검증자가 보유자에게 Decentralized Identifier 기반 인증 [DID-CORE]을 수행하도록 요청하는 방법을 정의합니다. 가장 단순한 형태에서 인증 프로토콜은 검증자의 challenge와 보유자의 응답으로 구성됩니다.
{
"query": [{
"type": "DIDAuthentication",
"acceptedMethods": [{"method": "example"}]
}],
"challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
"domain": "example.com"
}
위 DID Authentication 요청은 검증자가 보유자에게 제공된 challenge에 대한 디지털 서명을 생성하여 DID에 대한 제어를 입증하기를 원한다는 것을 지정합니다. 보유자는 다음 응답을 제공하여 응답할 수 있습니다.
{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": "VerifiablePresentation",
"holder": "did:example:12345",
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-rdfc-2022",
"verificationMethod": "did:example:12345#key-1",
"challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
"domain": "example.com",
"created": "2024-02-25T14:58:42Z",
"proofPurpose": "authentication",
"proofValue": "z3FXQjecWufY46...UAUL5n2Brbx"
}
}
DID Authentication 쿼리 형식은 검증자가 보유자에게 특정 방식으로 인증하도록 요청할 수 있게 합니다. DID Authentication 쿼리는 다음 형식이어야 MUST 합니다.
| 속성 | 설명 |
|---|---|
| type |
DIDAuthentication으로 설정되어야 MUST 하는
REQUIRED string 값입니다.
|
| acceptedMethods |
검증자가
나열된 DID Method 중 어느 것이든 수락하겠다고 표현하는 선택적 객체 배열입니다.
배열의 각 객체는 method라는 속성을 포함해야
MUST 하며, 그 값은 DID Method 이름이어야 합니다.
또한 DID Method에 특정한 다른 속성을 포함할
MAY 수 있습니다. 유효한 예시 값은 다음과 같습니다.
|
| acceptedCryptosuites |
이 검증자에게
제출할 암호학적 proof를 생성할 때 보유자가
선택해야 MUST 하는 cryptography suite들을 전달하는
선택적 객체 배열입니다. 배열의 각 객체는 Data Integrity cryptosuite 이름
(또는 레거시용 Ed25519Signature2020) 값을 가진
cryptosuite라는 속성을 포함해야 MUST 하며,
cryptosuite에 특정한 다른 속성을 포함할 MAY 수 있습니다.
유효한 예시 값은 다음과 같습니다.
|
다음 예제는 검증자가 보유자에게 Credential Handler API(CHAPI)와 같은 확립된 통신 채널을 통해 인증하기 위해 DID Web method와 data integrity ECDSA cryptography suite를 사용하길 원함을 보여 줍니다.
{
"query": [{
"type": "DIDAuthentication",
"acceptedMethods": [{"method": "key"}],
"acceptedCryptosuites": [{"cryptosuite": "ecdsa-rdfc-2019"}]
}],
"challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
"domain": "example.com"
}
다음 예제에서 검증자는 보유자가 DID Key 또는 DID Web method 중 하나와 표준 EdDSA data integrity cryptography suite를 사용하고, 선택적으로 data integrity BBS proof를 수행할 수 있음을 나타내는 cryptographic proof를 포함하며, 이 경우에는 Verifiable Credential API HTTP 엔드포인트를 사용하여 다른 통신 채널을 통해 인증하기를 원합니다.
{
"query": [{
"type": "DIDAuthentication",
"acceptedMethods": [{"method": "key"}, {"method": "web"}],
"acceptedCryptosuites": [{"cryptosuite": "ecdsa-rdfc-2019"}]
}, {
"type": "DIDAuthentication",
"required": false,
"acceptedMethods": [{"method": "key"}, {"method": "web"}],
"acceptedCryptosuites": [{"cryptosuite": "bbs-2023"}]
}],
"challenge": "zLEwtBYgQVNR4tyeo",
"domain": "didauth.example"
}
DID Authentication 응답 형식은 보유자가 검증자가 요청한 정보를 제공할 수 있게 합니다. DID Authentication 응답은 다음 형식의 검증 가능한 프레젠테이션이어야 MUST 합니다.
| 속성 | 설명 |
|---|---|
| type |
VerifiablePresentation으로 설정되어야 MUST 하는
REQUIRED string 값입니다.
|
| holder | DID Authentication 쿼리에서 요청된 유형의 특정 DID로 설정되어야 MUST 하는 REQUIRED string 값입니다. |
| proof |
DID Authentication 쿼리에서 요청된 하나 이상의 특정 digital proof type이어야
MUST 하는 REQUIRED 값입니다.
각 proof 객체는 DID Authentication 쿼리에서 제공된 domain 및
challenge 값을 포함해야 MUST 합니다.
Holder
구현은 검증자가 지정한
domain이 현재 통신 채널에 사용되는 domain과 일치하도록 보장해야
MUST 합니다.
|
보유자 구현이
verifier가 제공한 domain을 현재 통신 채널에 사용되는 domain과
대조하여 확인하는 것은 매우 중요합니다. 보유자가 그렇게 하지 않으면,
부정직한 검증자가 메시지를 자신의 것이
아닌 domain으로 replay할 수 있습니다. 예를 들어, evil.example domain에서 동작하는
부정직한 검증자는 사용자의
은행에서 challenge를 가져오고, yourbank.example의 domain 값을 지정한 다음,
사용자의 응답을 은행에 replay하여 금융 계정에 접근할 수 있습니다. 이 공격은
구현이 검증 가능한
프레젠테이션을 생성할 때 적절한 domain이 사용되도록 보장하는 한 완화됩니다.
아래 예제는 단순한 DID Authentication 응답을 보여 줍니다.
{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": "VerifiablePresentation",
"holder": "did:example:12345",
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-rdfc-2022",
"verificationMethod": "did:example:12345#key-1",
"challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
"domain": "example.com",
"created": "2024-02-25T14:58:42Z",
"proofPurpose": "authentication",
"proofValue": "z3FXQjecWufY46...UAUL5n2Brbx"
}
}
Verifiable Presentation Requests에서 정보의 구조화와 검색은 논리 연산 사용에 의존합니다. "AND" 및 "OR" 연산은 원하는 데이터로 가는 경로를 정의하는 데 중요한 역할을 합니다.
요청 구조의 최상위 수준에서, 서로 다른 유형의 쿼리는 각 쿼리의
group 속성이 같은 값으로 설정된 경우 "AND" 연산으로 처리될 것으로
예상됩니다.
이 예제에는 group 플래그가 certification으로 설정된
두 개의 쿼리가 있습니다. 이는 "AND" 연산을 초래하며, 요청을 충족하려면
이 두 조건이 모두 충족되어야 함을 나타냅니다.
{
"query": [{
"type": "QueryByExample",
"group": "certification",
// query details ...
},
// "AND"
{
"type": "DigitalCredentialQueryLanguage",
"group": "certification",
// query details ...
}]
}
특정 쿼리 유형 내에서는 group을 지정하지 않거나 서로 다른
group 값을 제공함으로써 "OR" 연산을 적용할 수 있습니다.
{
"query": [{
"type": "QueryByExample",
"group": "college-degree",
// query details ...
},
// "OR"
{
"type": "DigitalCredentialQueryLanguage",
"group": "job-experience",
// query details ...
}]
}
검증 가능한 자격 증명을 제시하기 위해 다음 API가 정의됩니다.
| 엔드포인트 | 설명 |
|---|---|
| POST /credentials/derive | credential을 파생하고 응답 본문에 반환합니다. |
| GET /presentations | presentation 또는 verifiable presentation 목록을 가져옵니다 |
| POST /presentations | presentation을 생성하고 응답 본문에 반환합니다. |
| GET /presentations | presentation 또는 verifiable presentation 목록을 가져옵니다 |
| POST /presentations | presentation을 생성하고 응답 본문에 반환합니다. |
| GET /presentations/{id} | ID로 presentation 또는 verifiable presentation을 가져옵니다 |
| DELETE /presentations/{id} | ID로 presentation 또는 verifiable presentation을 삭제합니다 |
| POST /exchanges/ | 오류: API Endpoint가 정의되지 않았습니다 - /exchanges/ |
| POST /exchanges/{exchangeId} | 오류: API Endpoint가 정의되지 않았습니다 - /exchanges/{exchangeId} |
URL path 값 exchange-id는
서버에는 의미가 있지만 클라이언트에는 불투명합니다. 일부 서버 구현이 우연히 사람이 읽을 수 있는
값을 사용할 수는 있지만, 클라이언트는 사람이 읽을 수 있는 값에 의미를 부여하지 않을 것을
강력히 권고받습니다.
POST /credentials/derive - credential을 파생하고 응답 본문에 반환합니다.
/credentials/derive 엔드포인트는 POST를 받을 때 다음 스키마를 사용합니다.
| 속성 | 설명 |
|---|---|
verifiableCredential [object] |
다음 형식의 객체:
|
options [object] |
파생된 credential이 생성되는 방식을 지정하기 위한 옵션입니다.
다음 형식의 객체여야 MUST 합니다.
|
/credentials/derive 엔드포인트는 POST를 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 201 | Credential이 성공적으로 파생되었습니다. content-type: application/json
다음 형식의 객체:
|
| 400 | 잘못된 요청 |
application/vp 이외의 미디어 유형(예: application/vp+jwt)으로
presentation을 생성하기 위해 응답에서 EnvelopedVerifiablePresentation를
반환할 수 있습니다.
POST /presentations - presentation을 생성하고 응답 본문에 반환합니다.
/presentations 엔드포인트는 POST를 받을 때 다음 스키마를 사용합니다.
| 속성 | 설명 |
|---|---|
presentation [object] |
proof가 없는 JSON-LD Verifiable Presentation입니다. 다음 형식의 객체여야
MUST 합니다.
|
options [object] |
DataIntegrityProof가 생성되는 방식을 지정하기 위한 옵션입니다. 다음 형식의
객체여야 MUST 합니다.
|
/presentations 엔드포인트는 POST를 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 201 | Presentation이 성공적으로 생성되었습니다! content-type: application/json
다음 형식의 객체:
|
| 400 | 잘못된 입력! |
GET /presentations - presentation 또는 verifiable presentation 목록을 가져옵니다
/presentations 엔드포인트는 GET을 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 200 | Presentations가 검색되었습니다 content-type: application/json
배열의 각 항목은 proof가 없는 JSON-LD Verifiable Presentation이어야
MUST 합니다. 다음 형식의 객체여야
MUST 합니다.
|
| 400 | Bad Request |
| 401 | Not Authorized |
| 410 | Gone! 여기에 데이터가 없습니다 |
GET /presentations/{id} - ID로 presentation 또는 verifiable presentation을 가져옵니다
/presentations/{id} 엔드포인트는 GET을 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 200 | Credential이 검색되었습니다 content-type: application/json
proof가 없는 JSON-LD Verifiable Presentation입니다. 다음 형식의
객체여야 MUST 합니다.
|
| 400 | Bad Request |
| 401 | Not Authorized |
| 404 | Presentation을 찾을 수 없습니다 |
| 410 | Gone! 여기에 데이터가 없습니다 |
DELETE /presentations/{id} - ID로 presentation 또는 verifiable presentation을 삭제합니다
/presentations/{id} 엔드포인트는 DELETE를 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 202 | Presentation이 삭제되었습니다 - soft delete와 처리 시간이 가정되므로
기본적으로 202입니다 |
| 400 | Bad Request |
| 401 | Not Authorized |
| 404 | Presentation을 찾을 수 없습니다 |
| 410 | Gone! 여기에 데이터가 없습니다 |
워크플로는 신뢰 경계를 가로질러 두 당사자 사이에서 검증 가능한 자격 증명을 교환하기 위한 특정 단계 집합을 정의합니다. 각 단계는 검증 가능한 자격 증명의 발급, 검증, 전송 및/또는 제시를 포함할 수 있습니다. 워크플로는 선형적인 단계 순서와, 분기 논리 및 반복 단계를 포함하는 더 복잡한 패턴을 모두 지원하도록 설계되어, 관련 당사자 간의 정교한 상호작용을 가능하게 합니다. VC API 워크플로의 예에는 다음이 포함되지만, 이에 국한되지는 않습니다.
워크플로 인스턴스는 예를 들어 coordinator 웹사이트와 함께 사용하기 위해
관리자가 생성할 것으로 예상됩니다. 워크플로 인스턴스는
workflow service의 /workflows 엔드포인트에 HTTP POST를 수행하여 생성됩니다.
HTTP 요청 본문에는 워크플로 인스턴스의 구성이 포함됩니다. 여기에는
워크플로를 정의하는 단계와 검증 가능한 자격 증명을 발급하는 데 사용될
credential template에 관한 정보가 포함되지만, 이에 국한되지는 않습니다.
워크플로를 정의하는 단계 자체도 template일 수 있어
추가적인 유연성을 제공합니다. 워크플로가
검증 가능한 자격 증명의 발급, 또는 presentation이나 credential의 검증을 포함하는 경우,
워크플로 인스턴스 구성에는 하나 이상의 issuer 및/또는 verification service를 사용하기 위한
authorization capability가 포함될 수 있습니다.
워크플로 인스턴스가 존재하면, exchange라고 하는 특정 워크플로 상호작용을 생성하고 쿼리할 권한을 coordinator에게 부여할 수 있습니다.
교환은 주어진 워크플로를 기반으로 하는 특정 상호작용을 나타냅니다. 이 상호작용은 exchange client와 workflow service 사이에서 이루어집니다. Exchange는 일시적일 것으로 예상되며, 상호작용이 완료되는 데 필요한 동안만 존재합니다. workflow service는 각 exchange에 대한 상태 정보를 저장합니다. 예를 들어 exchange가 pending, active 또는 complete인지 여부, 워크플로의 현재 단계, 워크플로별 변수와 데이터, 그리고 exchange가 실행되는 동안 수신된 검증 가능한 presentation과 credential을 저장합니다. 구현자는 Section 3.6.3 교환 생성에 정의된 예약 변수 외에도 구현에 원하는 어떤 변수든 자유롭게 사용할 수 있습니다. 워크플로의 단계 수에는 기술적인 제한이 없지만, 구현자는 버그를 방지하기 위해 기본 최대 단계 수를 강제하고자 할 수 있습니다.
issuer, verifier 또는 holder coordinator는 exchange를 생성할 책임이 있습니다.
coordinator는 workflow service에서 선택한 워크플로의 /exchanges 하위 경로에
HTTP POST를 수행하여 exchange를 생성합니다. HTTP 요청 본문에는 exchange의 만료 날짜와 시간,
그리고 해당 특정 exchange에 대해 워크플로의 template을 채우는 데 사용될 변수가 포함됩니다.
요청 본문에는 이 API를 넘어 추가 프로토콜을 사용하여 exchange를 실행할 수 있게 하는
구성 옵션도 포함될 수 있습니다. exchange가 생성되면, exchange를 식별하고
그와 상호작용할 수 있게 하는 exchange URL이 coordinator에게 반환됩니다.
exchange URL은 exchange client가 exchange를 시작할 수 있도록 해당 client에게 제공됩니다. exchange URL은 coordinator에게 제공된 뒤 exchange client에게 전달되지만, 실제 exchange는 exchange client와 workflow service 사이에서 수행된다는 점에 유의하십시오. coordinator는 exchange URL을 exchange client에게 제공한 이후에는 관여하지 않습니다. 명확히 말하면, coordinator는 exchange 자체를 실행해야 하는 모든 사용 사례에서 여전히 자신의 exchange client를 사용할 수 있습니다.
exchange를 시작하는 데에는 exchange URL 외의 권한 부여가 필요하지 않습니다. workflow service 구현에 따라 exchange URL은 capability URL일 수도 있습니다 (즉, URL은 추측할 수 없는 비밀이며, URL을 받은 사람만 exchange를 시작할 수 있습니다). exchange가 기반으로 하는 워크플로가 exchange URL의 소유 외에 추가 권한 부여를 요구하는 경우, 이는 시작 시점이 아니라 exchange 중에 획득되어야 합니다.
exchange URL은 coordinator가 exchange 진행 중 현재 상태를 쿼리하고, workflow service가 저장한 exchange 관련 정보를 얻는 데에도 사용할 수 있습니다. 이런 방식으로 exchange를 쿼리하려면 coordinator가 보유할 것으로 예상되지만 exchange client는 보유하지 않는 추가 권한 부여가 필요합니다.
exchange URL이 coordinator에서 exchange client로 어떻게 전송되는지는 이 명세의 범위를 벗어납니다. exchange URL을 client와 공유하기 위한 알려진 메커니즘에는 Credential Handler API(일명 CHAPI), QR 코드 또는 universal link가 포함됩니다.
Exchange는 이 API exchange protocol 외에도 다른 프로토콜을 사용해 실행 가능하도록 설계되었습니다. 예를 들어 exchange는 잠재적으로 OID4VCI, OID4VP, DIDComm 및 exchange protocol 중 어느 것으로든 실행될 수 있습니다. 지원되는 프로토콜은 exchange가 기반으로 하는 워크플로의 복잡성과 exchange가 생성될 때 coordinator가 제공한 옵션에 따라 달라집니다.
exchange client는 exchange URL을 받은 방식과 호환되는 프로토콜을 사용하여 exchange를 시작할 것으로 예상됩니다. 예를 들어, exchange URL은 이 API 프로토콜이 사용되어야 함을 나타내는 프로토콜 식별자와 함께 CHAPI를 통해 제공되었을 수 있습니다. 또는 exchange URL이 OID4VCI credential offer의 "credential_issuer"로 포함되거나, OID4VP authorization request의 "client_id"로 포함되어, 각각 OID4VCI 또는 OID4VP가 사용되어야 함을 나타낼 수 있습니다. 이 절은 exchange client가 이 API를 사용해 exchange와 상호작용하는 방법에 초점을 맞춥니다. OID4VCI, OID4VP 및 DIDComm과 같은 다른 프로토콜과 exchange를 결합하는 방법은 부록 TBD를 참조하십시오.
이 API 프로토콜을 사용해 실행되는 exchange는 HTTP를 통해 요청 및 응답 본문으로 전송되는 메시지를 포함합니다. 각 메시지는 다음 속성과 값 중 0개 이상을 포함하는 단순한 JSON 객체로 구성됩니다.
redirectUrl: 다른 위치에서 상호작용을 계속하는 데 사용할 수 있는 URL입니다.
이 사용 사례 중 하나는 exchange가 완료된 뒤 exchange client의 사용자를
coordinator 웹사이트로 다시 보내는 것입니다.
verifiablePresentation: Verifiable Presentation입니다. 이는 exchange의 어느 한
당사자가 다른 당사자에게 정보를 제공하는 데 사용되며, 상대방이 요청했기 때문일 수도 있고
전자가 단순히 제안하기 때문일 수도 있습니다.
verifiablePresentationRequest: Verifiable Presentation Request입니다. 이는
exchange의 어느 한 당사자가 다른 당사자에게 정보를 요청하는 데 사용됩니다.
사용자 정의 속성과 값도 포함될 수 있지만, 이를 인식하지 못하는 구현에서는 오류를 유발할 것으로 예상됩니다.
이 API 프로토콜을 사용해 exchange를 시작하려면, exchange client는
JSON 객체를 요청 본문으로 보내는 HTTP POST를 수행합니다. 가장 단순한 경우,
client가 exchange에 대해 자체 제약 조건을 가지고 있지 않을 때
— 즉, 상대방에게 요청할 것이 없을 때 —
JSON 객체는 비어 있습니다({}). workflow service는 응답 본문에서
자체 JSON 객체로 응답합니다.
해당 응답 객체가 비어 있으면 exchange가 완료된 것이며, exchange client에게
요청되거나 제공되는 것은 없습니다. 객체에 verifiablePresentationRequest가 포함되어 있으면,
exchange는 아직 완료되지 않았고, 연결된 verifiable presentation request의 내용에 지정된 대로
일부 추가 정보가 요청됩니다. 객체에 verifiablePresentation이 포함되어 있으면,
exchange client를 운영하는 holder에게 발급된 검증 가능한 자격 증명이나
exchange client의 요청을 기반으로 exchange server 운영자에 대한 정보를 담은 검증 가능한 자격 증명과 같은
일부 정보가 제공됩니다. 객체에 redirectUrl이 포함되어 있으면,
exchange가 완료되었으며 workflow service는 client가 다른 형식으로 상호작용을 계속하기 위해
다른 위치로 진행할 것을 권장합니다.
많은 검증 가능한 자격 증명 사용 사례는 이러한 기본 primitive를 사용해 구현할 수 있습니다.
exchange의 어느 당사자든 검증 가능한 presentation을 요청할 수 있고,
신뢰를 수립하고/하거나 authorization capability를 얻는 데 필요할 수 있는 하나 이상의
검증 가능한 자격 증명을 제공할 수 있으며, 어느 당사자든 자신이 보유하거나 발급한
credential을 제시할 수 있습니다. 특정 워크플로는 특정 presentation과 credential을 기대하도록
구성될 수 있으며, 예상되는 정보 흐름에서 벗어나는 것을 거부할 수 있습니다.
workflow service가 특정 메시지를 수락할 수 없다고 판단하면,
4xx HTTP 상태 메시지와 오류 정보를 표현하는 JSON 객체로 응답하여
오류를 발생시킵니다.
exchange 설계 접근 방식은 계층화되어 있습니다. 이는 최소한의 통신 메시지 계층과, 대부분의 사용 사례가 그 위의 계층에서 특정 verifiable presentation request와 verifiable credential을 통해 구현될 수 있도록 하는 primitive 집합을 제공하는 것을 목표로 합니다. 특정 verifiable presentation request와 verifiable credential을 사용하는 워크플로 및 exchange의 예는 뒤따르는 부록을 참조하십시오.
단계 및 credential template의 최소 실행 가능한 예와 더 복잡한 워크플로 template 몇 가지는 부록 워크플로 단계 및 Template 예제에서 찾을 수 있습니다.
exchange와의 특정 상호작용은 짧게 지속될 것으로 예상되지만, 더 길거나 다단계 상호작용을 가능하게 하기 위해 다른 메커니즘을 사용할 수 있습니다. 다른 상호작용 메커니즘의 예에는 SMS, 이메일, 웹 알림 또는 전화 통화가 포함됩니다. 이 접근 방식은 digital wallet 구현을 단순화하고, 이 API 안에서 재발명하지 않고 기존 메커니즘을 재사용할 수 있게 합니다. Web 또는 native platform은 애플리케이션(예: Web browser)이나 다른 platform 기능을 통해 추가 상호작용을 가능하게 할 것으로 예상됩니다. 예를 들어 비동기 발급에서, holder는 credential을 요청하지만 처리를 기다립니다. 이러한 경우 시스템 구성 요소 (예: issuer coordinator)는 credential을 수집할 준비가 되었을 때 holder에게 알리기 위해 이 API 외부의 메커니즘을 사용합니다.
신뢰 경계를 넘어야 하는 credential 사용 사례를 위해 워크플로와 exchange를 사용하는 다음 API가 정의됩니다.
| 엔드포인트 | 설명 |
|---|---|
| POST /workflows | 새 워크플로를 생성하고 응답 헤더에 워크플로 metadata의 위치를 반환합니다. |
| GET /workflows/{localWorkflowId} | 기존 워크플로의 구성을 가져와 응답 본문에 반환합니다. |
| POST /workflows/{localWorkflowId}/exchanges | 새 exchange를 생성하고 응답 헤더에 exchange metadata의 위치를 반환합니다. |
| GET /workflows/{localWorkflowId}/exchanges/{localExchangeId} | 기존 exchange의 상태를 가져와 응답 본문에 반환합니다. |
| POST /workflows/{localWorkflowId}/exchanges/{localExchangeId} | exchange에 참여합니다. 빈 본문을 POST하면 exchange가 시작되거나, 다음 단계를 완료하기 위해 exchange가 기대하는 내용을 반환합니다. Verifiable Presentation Request를 POST하면 4xx 오류 또는 다음 중 하나가 발생합니다. client의 요청에 부합하는 Verifiable Presentation 또는 Verifiable Presentation Request입니다. Verifiable Presentation이 전송되면, exchange를 계속하기 위해 추가 Verifiable Presentation Request도 전송될 수 있습니다. |
workflows and exchanges API에서 "local" ID는 service instance에 로컬인 ID를 의미합니다.
즉, exchangeId 또는 workflowId는 완전한 URL을 가리키는 반면,
localExchangeId 또는 localWorkflowId는 URL path의 특정 요소를 가리킵니다.
POST /workflows - 새 워크플로를 생성하고 응답 헤더에 워크플로 metadata의 위치를 반환합니다.
/workflows 엔드포인트는 POST를 받을 때 다음 스키마를 사용합니다.
| 속성 | 설명 |
|---|---|
id [string] |
생성된 워크플로에 사용될 ID입니다. ID 전달은 OPTIONAL입니다. |
initialStep [string] |
exchange가 시작되는 위 집합의 단계입니다. initialStep 전달은 REQUIRED입니다. |
controller [string] |
인스턴스의 root controller를 지정하는 OPTIONAL 속성입니다. 이는
object capability에 의존하는 Authorization Capabilities(ZCAPs) 같은
권한 부여 메커니즘을 지원하는 시스템에서 사용할 수 있습니다. 이 값은
authorization 속성과 함께 사용되어 다른 권한 부여 메커니즘도
동시에 허용할 수 있습니다.
|
authorization [object] |
OAuth2 구성과 같은 endpoint의 authorization scheme 정보를 지정하는
OPTIONAL 속성입니다. 다음 형식의 객체여야 MUST 합니다.
|
credentialTemplates [array] |
각 항목이 다음 형식의 객체여야 MUST 하는 배열입니다.
|
steps [object] |
워크플로에서 exchange를 완료하는 데 필요한 하나 이상의 단계입니다.
steps 객체 전달은 REQUIRED입니다. 키는 하나 이상의 단계 이름이며,
각 STEP_NAME은 단계 이름(예: request-employee-id)으로
대체되고, 값은 단계 구성입니다. 다음 형식의 객체여야
MUST 합니다.
|
/workflows 엔드포인트는 POST를 받을 때 다음 응답 중 하나를 생성할 수 있습니다.
| 응답 | 본문 |
|---|---|
| 201 | 워크플로가 성공적으로 생성되었습니다(데이터 포함) |
| 204 | 워크플로가 성공적으로 생성되었습니다(데이터 없음) |
| 400 | 잘못된 입력 |
| 401 | 권한이 없습니다 |
| 500 | 내부 오류 |
워크플로는 단계, credential template 및 authorization에 대한 정보를 포함할 수 있습니다.
경우에 따라 워크플로는 구성의 여러 지점(일반적으로 credential template)에서
예약된 results 변수를 참조하기도 합니다. 이 변수는
exchange 과정 전반에 걸쳐 workflow service가 client로부터 수신하는 데이터를 보유합니다.
다음은 DID Authentication 단계와 credential delivery 단계를 포함하는
기본 workflow 구성입니다.
단계는 하나 이상의 issue request 객체를 포함하는 issueRequests 배열을
포함할 수 있습니다. 각 issue request 객체는 사용할 credential template을 식별하며,
이는 식별자(credentialTemplateId) 또는 워크플로의
credentialTemplates 배열에서의 index(credentialTemplateIndex)로
지정됩니다. issue request 객체는 credential template을 평가할 때 사용할 값을 제공하기 위해
variables 속성을 포함할 수도 MAY 있습니다.
기본적으로 각 issue request의 결과는 동일 단계에서 exchange client에게 전송되는
verifiable
presentation에 포함됩니다. issue request 객체는 선택적 result 속성을
포함할 수도 MAY 있으며,
그 값은 exchange의 variables 객체에 있는 top-level variable의 이름이거나,
exchange의 variables 객체 안의 어떤 variable에 대한 JSON pointer여야
MUST 하며, issue request의 결과가 저장될 위치를 식별합니다.
이를 통해 더 큰 조합성이 가능해집니다. 후속 단계가 저장된 결과를 참조할 수 있거나,
exchange가 종료되고 exchange state에 접근할 수 있는 당사자가 다른 exchange 또는
다른 메커니즘에서 사용하기 위해 그 결과를 얻을 수 있습니다.
{
"id": "9fd3bc6d-4a04-4b3d-a983-3482d0586626",
"initialStep": "didAuthRequest",
"steps": {
"didAuthRequest": {
"createChallenge": true,
"verifiablePresentationRequest": {
"query": {
"type": "DIDAuthentication",
"acceptedMethods": [
{
"method": "key"
},
{
"method": "web"
}
],
"acceptedCryptosuites": [
{
"cryptosuite": "eddsa-rdfc-2022"
},
{
"cryptosuite": "ed25519-2020"
}
]
},
"domain": "https://issuer.example.com"
},
"nextStep": "credentialDelivery"
},
"credentialDelivery": {
"issueRequests": [
{
"credentialTemplateId": "caffb919-053a-4bfa-beba-80567904f842",
"variables": "sampleAchievementCredential"
}
]
}
},
"credentialTemplates": [
{
"id": "caffb919-053a-4bfa-beba-80567904f842",
"type": "jsonata",
"template": "{
\"credential\": {
\"@context\": [
\"https://www.w3.org/ns/credentials/v2\",
\"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json\",
\"https://purl.imsglobal.org/spec/ob/v3p0/extensions.json\"
],
\"id\": sampleAchievementCredential.id,
\"type\": [\"VerifiableCredential\", \"AchievementCredential\"],
\"issuer\": {
\"type\": [\"Profile\"],
\"name\": \"Example Issuer\",
\"image\": {
\"type\": \"Image\",
\"id\": \"https://issuer.example.com/logo.png\"
}
},
\"awardedDate\": sampleAchievementCredential.awardedDate,
\"validFrom\": sampleAchievementCredential.validFrom,
\"name\": \"Sample Achievement\",
\"credentialSubject\": {
\"id\": results.didAuthRequest.verifiablePresentation.holder,
\"type\": \"AchievementSubject\",
\"name\": sampleAchievementCredential.credentialSubject.name,
\"achievement\": {
\"id\": sampleAchievementCredential.credentialSubject.achievement.id,
\"type\": [\"Achievement\"],
\"achievementType\": sampleAchievementCredential.credentialSubject.achievement.achievementType,
\"name\": sampleAchievementCredential.credentialSubject.achievement.name,
\"description\": sampleAchievementCredential.credentialSubject.achievement.description,
\"alignment\": sampleAchievementCredential.credentialSubject.achievement.alignment
}
}
}
}"
}
],
"controller": "did:web:issuer.example.com"
}
단계는 해당 단계에서 사용될
verifiable
presentation을 명시적으로 표현하기 위해 verifiablePresentation을
포함할 수 MAY 있습니다. 이 presentation은
exchange의 다른 variable을 통해 구성될 수 있으며, 해당 단계 중 발급될 수 있는
추가 verifiable
credentials(issueRequests에 따라)로 보강될 수 있습니다.
이는 특정 verifiable
presentation 버전이 필요하거나, 특정 하위 type의
verifiable
presentations가 필요하거나, 이전에 out-of-band로 발급되어
workflow step에서 전달되어야 하는 verifiable
credentials를 포함해 특정
verifiable
presentation 내용이 필요한 사용 사례를 지원합니다.
단계는 다른 위치에서 상호작용을 계속하는 데 사용할 수 있도록 client에게 보낼 URL을
지정하기 위해 redirectUrl을 포함할 수
MAY 있습니다.
이 사용 사례 중 하나는 exchange가 완료된 후 exchange client의 사용자를
coordinator 웹사이트로 다시 보내는 것입니다. 또 다른 사용 사례는
client가 웹 브라우저로 이동할 필요 없이 계속되는 상호작용 중 server가
사용자 정의 비즈니스 규칙을 구현할 수 있도록 하는
interaction URL을 반환하는 것입니다.
예를 들어, 첫 번째 exchange가 사용자에게 정보를 요청한 뒤
redirectUrl을 통해
interaction URL을 반환할 수 있습니다. client
(예: digital wallet)는 그것이 interaction URL임을 판단할 수 있고
(예: URL이 ?iuv=1을 사용함), 이를 fetch하여 interaction server가
사용자 정의 비즈니스 로직을 실행한 다음 상호작용을 계속하기 위한 또 다른
exchange가 포함된 protocol object를 반환하도록 할 수 있습니다.
일부 워크플로는 하나 이상의 단계에서 사용자 정의 variable을 참조해야 합니다.
이 경우 coordinator는 exchange를 생성할 때 해당 variable에 적절한 값을
제공해야 합니다. 다음은 template화된 DID Authentication 단계가 있는
workflow 구성의 예입니다
(didAuthRequest 단계에서 참조되는 verifiablePresentationRequest와
callbackUrl variable에 주목하십시오).
{
"id": "9fd3bc6d-4a04-4b3d-a983-3482d0586626",
"initialStep": "didAuthRequest",
"steps": {
"didAuthRequest": {
"stepTemplate": {
"type": "jsonata",
"template": "{
"createChallenge": true,
"verifiablePresentationRequest": verifiablePresentationRequest,
"callback": {
"url": callbackUrl
},
"nextStep": "credentialDelivery"
}"
}
},
"credentialDelivery": {
"issueRequests": [
{
"credentialTemplateId": "caffb919-053a-4bfa-beba-80567904f842",
"variables": "sampleAchievementCredential"
}
]
}
},
"credentialTemplates": [
{
"id": "caffb919-053a-4bfa-beba-80567904f842",
"type": "jsonata",
"template": "{
\"credential\": {
\"@context\": [
\"https://www.w3.org/ns/credentials/v2\",
\"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json\",
\"https://purl.imsglobal.org/spec/ob/v3p0/extensions.json\"
],
\"id\": sampleAchievementCredential.id,
\"type\": [\"VerifiableCredential\", \"AchievementCredential\"],
\"issuer\": {
\"type\": [\"Profile\"],
\"name\": \"Example Issuer\",
\"image\": {
\"type\": \"Image\",
\"id\": \"https://issuer.example.com/logo.png\"
}
},
\"awardedDate\": sampleAchievementCredential.awardedDate,
\"validFrom\": sampleAchievementCredential.validFrom,
\"name\": \"Sample Achievement\",
\"credentialSubject\": {
\"id\": results.didAuthRequest.verifiablePresentation.holder,
\"type\": \"AchievementSubject\",
\"name\": sampleAchievementCredential.credentialSubject.name,
\"achievement\": {
\"id\": sampleAchievementCredential.credentialSubject.achievement.id,
\"type\": [\"Achievement\"],
\"achievementType\": sampleAchievementCredential.credentialSubject.achievement.achievementType,
\"name\": sampleAchievementCredential.credentialSubject.achievement.name,
\"description\": sampleAchievementCredential.credentialSubject.achievement.description,
\"alignment\": sampleAchievementCredential.credentialSubject.achievement.alignment
}
}
}
}"
}
],
"controller": "did:web:issuer.example.com"
}
openId 옵션, 특히 createAuthorizationRequest와
authorizationRequest 값에 대해, 개발자가 OID4VP Authorization Request가
어떻게 생겼는지 이해하는 데 도움을 주기 위해 아래 예제가 제공됩니다.
{
"response_type": "vp_token",
"presentation_definition": {
"id": "f1bd224a-0fed-469a-b64a-dad7cf63fd98",
"input_descriptors": [
{
"id": "77d50c71-95ef-442c-a372-f32e17634fab",
"constraints": {
"fields": [
{
"path": [
"$['@context']"
],
"filter": {
"type": "array",
"contains": {
"type": "string",
"const": "https://www.w3.org/ns/credentials/v2"
}
}
},
{
"path": [
"$['type']"
],
"filter": {
"type": "array",
"contains": {
"type": "string",
"const": "VerifiableCredential"
}
}
},
{
"path": [
"$['credentialSubject']['name']"
],
"filter": {
"type": "string"
}
}
]
},
"purpose": "We require a name credential to display your name when you post messages."
}
]
},
"response_mode": "direct_post",
"client_metadata": {
"vp_formats_supported": {
"ldp_vc": {
"proof_type_values": [
"DataIntegrityProof",
"Ed25519Signature2020"
],
"cryptosuite_values": [
"ecdsa-rdfc-2019",
"eddsa-rdfc-2022"
]
}
},
"vp_formats": {
"jwt_vp": {
"alg": [
"EdDSA",
"Ed25519",
"ES256",
"ES384"
]
},
"jwt_vp_json": {
"alg": [
"EdDSA",
"Ed25519",
"ES256",
"ES384"
]
},
"di_vp": {
"proof_type": [
"ecdsa-rdfc-2019",
"eddsa-rdfc-2022",
"Ed25519Signature2020"
]
},
"ldp_vp": {
"proof_type": [
"ecdsa-rdfc-2019",
"eddsa-rdfc-2022",
"Ed25519Signature2020"
]
}
}
},
"client_id": "https://some.example/workflows/z1A7ojitBF3pGpVzW17MgU7zm/exchanges/z1ACKwiBiXmuGjpKAdKMpBZXB/openid/client/authorization/response",
"client_id_scheme": "redirect_uri",
"response_uri": "https://some.example/workflows/z1A7ojitBF3pGpVzW17MgU7zm/exchanges/z1ACKwiBiXmuGjpKAdKMpBZXB/openid/client/authorization/response",
"nonce": "z1ACKwiBiXmuGjpKAdKMpBZXB"
}
GET /workflows/{localWorkflowId} - 기존 워크플로의 구성을 가져와 응답 본문에 반환합니다.
/workflows/{localWorkflowId} 엔드포인트는 GET을 받을 때 다음 응답 중 하나를 생성할 수 있습니다:
| 응답 | 본문 |
|---|---|
| 200 | 워크플로 구성이 검색되었습니다! content-type: application/json
워크플로에 대한 정보를 포함하는 객체입니다. 다음 형식의 객체여야
MUST 합니다.
|
| 400 | 잘못된 입력 |
| 401 | 권한이 없습니다 |
| 500 | 내부 오류 |
exchange에는 expires 속성이 연결되어 있으며, exchange의
만료 날짜와 시간을 나타냅니다. 이는
/workflows/{localWorkflowId}/exchanges 엔드포인트를 사용하여 생성됩니다. 이는
이러한 exchange와 연결된 challenge의 수명에 영향을 줍니다. challenge가
exchange에 바인딩되어 있다면, 해당 challenge는 exchange의
expires 속성이 참조하는 날짜에 유효하지 않게 됩니다.
POST /workflows/{localWorkflowId}/exchanges - 새 exchange를 생성하고 응답 헤더에 exchange metadata의 위치를 반환합니다.
/workflows/{localWorkflowId}/exchanges 엔드포인트는 POST를 받을 때 다음 스키마를 사용합니다:
| 속성 | 설명 |
|---|---|
expires [string] |
exchange가 만료되는 날짜와 시간(XML Schema dateTimeStamp로 표현됨)입니다. |
variables [object] |
객체 |
openId [object] |
{
"required": [
"createAuthorizationRequest"
],
"not": {
"required": [
"authorizationRequest"
]
}
} 또는
{
"required": [
"authorizationRequest"
],
"not": {
"required": [
"createAuthorizationRequest"
]
}
} 또는 다음 형식의 객체입니다.
|
/workflows/{localWorkflowId}/exchanges 엔드포인트는 POST를 받을 때 다음 응답 중 하나를 생성할 수 있습니다:
| 응답 | 본문 |
|---|---|
| 201 | Exchange가 성공적으로 생성되었습니다(데이터 포함) |
| 204 | Exchange가 성공적으로 생성되었습니다(데이터 없음) |
| 400 | 잘못된 입력 |
| 401 | 권한이 없습니다 |
| 500 | 내부 오류 |
이 엔드포인트는 client가 exchange에 대해 지원하는 모든 protocol을 쿼리할 수 있는 메커니즘을 제공합니다. 단일 exchange는 digital wallet로 검증 가능한 credential을 발급하는 것과 같이 exchange의 목표를 달성할 수 있는 많은 protocol을 지원할 수 있습니다.
GET /workflows/{localWorkflowId}/exchanges/{localExchangeId}/protocols - 특정 exchange와 상호작용하기 위해 지원되는 protocol을 가져옵니다.
/workflows/{localWorkflowId}/exchanges/{localExchangeId}/protocols 엔드포인트는 GET을 받을 때 다음 응답 중 하나를 생성할 수 있습니다:
| 응답 | 본문 |
|---|---|
| 200 | exchange가 이해하는 protocol입니다. content-type: application/json
특정 exchange를 수행하는 데 사용할 수 있는 protocol에 대한 정보를
포함하는 객체입니다. 다음 형식의 객체여야 MUST 합니다:
|
| 400 | 잘못된 입력 |
| 401 | 권한이 없습니다 |
| 500 | 내부 오류 |
이 엔드포인트는 website operator가 HTTPS domain을 통해 해당 trust를 위임함으로써,
service provider와 같은 제3자에게 exchange를 실행할 권한을 위임할 수도 있게 합니다.
예를 들어, website brand.example은 protocol 목록에서
saas.example domain을 사용하여 exchange의 운영을 partner
saas.example에게 위임할 수 있습니다.
이를 통해 client는 웹사이트가 웹 페이지를 렌더링하기 위해 다른 domain의 resource에
link하는 것과 같은 방식으로, brand.example에 대한 신뢰를 바탕으로
exchange 운영을 제3자에게 위임할 수 있습니다.
server는 exchange message에 referenceId 속성을 포함할
MAY 있습니다. client가 referenceId를 받으면,
server로 보내는 다음 message에 동일한 referenceId를 포함하는 것이
SHOULD 됩니다.
이는 debugging을 돕고, 잠재적으로 지연되거나 순서가 뒤바뀐
message가 올바른 request에 연결되도록 보장합니다.
referenceId 값은 urn:uuid: 값이어야
SHOULD 합니다.
POST /workflows/{localWorkflowId}/exchanges/{localExchangeId} - exchange에 참여합니다. 빈 본문을 Posting하면 exchange가 시작되거나, 다음 단계를 완료하기 위해 exchange가 기대하는 내용을 반환합니다. Verifiable Presentation Request를 Posting하면 4xx error 또는 다음 중 하나가 발생합니다. client의 request에 부합하는 Verifiable Presentation 또는 Verifiable Presentation Request입니다. Verifiable Presentation이 전송되면, exchange를 계속하기 위해 추가 Verifiable Presentation Request도 전송될 수 있습니다.
/workflows/{localWorkflowId}/exchanges/{localExchangeId} endpoint는 POST를 받을 때 다음 schema 중 하나를 사용합니다:
| 속성 | 설명 |
|---|
또는 /workflows/{localWorkflowId}/exchanges/{localExchangeId} endpoint는 다음 schema도 사용할 수 있습니다:
| 속성 | 설명 |
|---|---|
verifiablePresentationRequest [object]
|
Verifiable Presentation Request입니다. 다음 형식의 객체여야 MUST 합니다:
|
referenceId [string] |
server가 이전에 referenceId를 보냈을 때, client는 debugging과 message correlation을 돕기 위해 여기에 이를 포함하는 것이 SHOULD 됩니다. 값은 urn:uuid 값이어야 SHOULD 합니다. |
| 속성 | 설명 |
|---|---|
verifiablePresentation [object] |
다음 형식의 객체:
|
referenceId [string] |
server가 이전에 referenceId를 보냈을 때, client는 debugging과 message correlation을 돕기 위해 여기에 이를 포함하는 것이 SHOULD 됩니다. 값은 urn:uuid 값이어야 SHOULD 합니다. |
| 속성 | 설명 |
|---|---|
redirectUrl [string] |
client는 interaction URL을 redirectUrl로 server에 보낼 MAY 있으며, 해당 interaction URL로 시작하는 다른 관련 exchange에서 server가 client가 되도록 초대합니다. server는 이 redirectUrl과 상호작용할 MAY 있습니다. |
referenceId [string] |
server가 이전에 referenceId를 보냈을 때, client는 debugging과 message correlation을 돕기 위해 여기에 이를 포함하는 것이 SHOULD 됩니다. 값은 urn:uuid 값이어야 SHOULD 합니다. |
/workflows/{localWorkflowId}/exchanges/{localExchangeId} endpoint는 POST를 받을 때 다음 response 중 하나를 생성할 수 있습니다:
| 응답 | 본문 |
|---|---|
| 200 | Exchange가 진행되었습니다. content-type: application/json
다음 형식의 객체:
|
| 400 | 잘못된 입력 |
| 401 | 권한이 없습니다 |
| 500 | 내부 오류 |
GET /workflows/{localWorkflowId}/exchanges/{localExchangeId} - 기존 exchange의 상태를 가져와 response body에 반환합니다.
/workflows/{localWorkflowId}/exchanges/{localExchangeId} endpoint는 GET을 받을 때 다음 response 중 하나를 생성할 수 있습니다:
| 응답 | 본문 |
|---|---|
| 200 | Exchange 구성이 검색되었습니다! content-type: application/json
active exchange에 대한 정보를 포함하는 객체입니다. 주어진 exchange에 전송할
VP와 redirectUrl이 없는 경우 빈 객체일 수 있습니다.
다음 형식의 객체여야 MUST 합니다:
|
| 400 | 잘못된 입력 |
| 401 | 권한이 없습니다 |
| 500 | 내부 오류 |
POST /callbacks/{localCallbackId} - exchange step이 수행될 때 알림을 받을 수 있는 capability URL(즉, 추측하기 어려운 URL)일 수 있는 callback입니다. URL은 authorization token, 주기적 token refresh 또는 client registration 없이, URL을 공유받은 당사자만 사용할 수 있도록 capability URL이어야 SHOULD 합니다. "localCallbackId"가 있는 제안된 URL 형식이 사용되는 경우, 전체 callback URL을 capability URL로 취급할 수 있도록 "localCallbackId" 값은 최소 128-bit의 random information을 표현해야 합니다. exchange마다 새 capability URL을 생성하고 해당 exchange에서만 사용하는 것도 권장됩니다.
/callbacks/{localCallbackId} endpoint는 POST를 받을 때 다음 schema를 사용합니다:
| 속성 | 설명 |
|---|---|
event [object] |
callback과 연결된 event 정보입니다. 다음 형식의 객체여야
MUST 합니다:
|
/callbacks/{localCallbackId} endpoint는 POST를 받을 때 다음 response 중 하나를 생성할 수 있습니다:
| 응답 | 본문 |
|---|---|
| 200 | Callback data가 수신되었습니다. |
| 400 | Callback data가 수신되지 않았습니다. |
이 명세의 API는 중개되지 않은(자동화된, machine-to-machine) 또는 중개된(사람이 관여하는) exchange를 실행할 수 있게 합니다. 이러한 exchange는 holder coordinator가 시작하고, exchange를 구현하는 모든 Coordinator가 응답합니다. flow는 다음 step으로 구성됩니다:
holder coordinator는 실제로 exchange를 시작하기 전에, 특정 endpoint에서 holder coordinator가 Coordinator의 protocol requirements를 지원하는지 확인하기 위해 Coordinator의 exchange discovery endpoint를 호출할 MAY 있습니다.
위에서 설명한 step의 diagram은 아래에 제시되어 있습니다:
위의 일반적인 exchange는 완전히 자동화된 방식, 사람이 중개하는 방식, 또는 일부는 자동화되지만 특정 단계에서 사람의 interaction이 필요한 hybrid 방식으로 수행될 수 있습니다. 위의 두 번째 step은 다음 step이 자동화되는지 또는 개인의 개입이 필요한지에 대한 guidance를 제공하는 데 사용됩니다.
다음 diagram은 holder coordinator가 Verifiable Presentation Request로 시작하여, 진행하기 전에 수신 Coordinator의 credentials를 요구하는 exchange를 보여줍니다:
다음 diagram은 holder coordinator가 server의 initial request를 받은 뒤 counter-request를 보내는 exchange를 보여줍니다:
다음 예제는 exchange client가 허용할 cryptographic
proof format과 envelope type을 지정하는
verifiablePresentationRequest로 exchange를 시작하는 것을 보여줍니다. reason
속성이 없으면, exchange client는 지정된 형식과 일치하는 workflow service의 모든 credential(s)을
수락합니다.
{
"verifiablePresentationRequest": {
"query": [{
"type": "QueryByExample",
"credentialQuery": {
"acceptedCryptosuites": [
{"cryptosuite": "eddsa-rdfc-2022"},
{"cryptosuite": "ecdsa-rdfc-2019"},
{"cryptosuite": "bbs-2023"}
],
"acceptedEnvelopes": [
{"mediaType": "application/jwt"}
]
}
}]
}
}
다음 예제는 exchange client가 이후 request를 수행하기 전에 workflow service에 credentials를 요청하는 것을 보여줍니다. 이 scenario에서 exchange client는 personal information을 공유하기 전에 server operator가 registered business임을 증명하도록 요구합니다.
{
"verifiablePresentationRequest": {
"query": [{
"type": "QueryByExample",
"credentialQuery": {
"reason": "Please present your BusinessRegistrationCredential to complete the verification process.",
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2"
],
"type": ["BusinessRegistrationCredential"]
},
"acceptedCryptosuites": [
{"cryptosuite": "eddsa-rdfc-2022"}
]
}
}]
}
}
한 구현이 자신과 상호작용을 시작하는 방법을 다른 구현에 전달하는 것은 유용합니다. 이 bootstrapping process는 상호작용 시작이라고 하며, 각 구현이 어떤 protocol을 지원하는지와 특정 상호작용을 해당 구현과 어떻게 시작하는지를 전달합니다.
이 문서에는 여러 interaction specification이 포함되어 있지만, 일반적인 접근 방식은 use case, application 및 protocol에 구애받지 않습니다. 이 접근 방식은 웹 브라우저, QR Code(광학 매체), 또는 NFC(무선 매체)와 같은 어떤 전송 매체를 통해 특정 protocol로 bootstrapping하려는 두 개 이상의 application을 연결하는 데 사용할 수 있으며, 이때 해당 protocol이 이 API를 포함할 필요는 없습니다.
아래 sequence diagram은 issuer가 interaction
URL을 생성하고, QR Code를 사용하여 이를 holder와 공유한 다음,
vcapi protocol로 진행하는 과정을 요약합니다:
아래 sequence diagram은 verifier가 interaction
URL을 생성하고, QR Code를 사용하여 이를 holder와 공유한 다음,
vcapi protocol로 진행하는 과정을 요약합니다:
아래 sequence diagram은 holder가 interaction
URL을 생성하고,
QR Code를 사용하여 이를 verifier와 공유한 다음,
inviteRequest protocol로 진행하는 과정을 요약합니다:
interaction
URL의 형식은
URL
Standard의
syntax를 준수해야 MUST 하며,
interaction URL version number를 encoding하는 iuv query parameter를
포함해야 합니다. 이 API의 이 버전을 사용할 때 그 값은 1이어야
MUST 합니다. interaction URL은
interaction-specific identifier를 포함하는 HTTPS URL이어야
SHOULD 합니다. URL은 opaque해야 하며, 수신 system이 fetch하기 전에
URL syntax processing을 요구하지 않아야 SHOULD 합니다.
이러한 URL의 예는 아래에 표시되어 있습니다:
https://app.example/interactions/z8n38Dp7a?iuv=1
긴 protocol-specific information을 URL에 encoding하는 protocol은 software library가 URL의 최대 허용 길이에 두는 제한을 받습니다. 작성 시점에서 권장되는 URL 길이 제한은 대략 2,000자입니다. 구현자는 Section 3.7.4 Interaction Protocols Response에 정의된 interaction URL에 대한 GET request의 response로 표현될 수 있는 정보를 interaction URL의 query parameter에 넣지 않아야 SHOULD NOT 합니다.
coordinator는 interaction URL을 자신의 Web origin의 어느 위치에나 둘 자유가 있습니다.
consuming software가 이를 opaque한 것으로 간주할 것으로 예상되기 때문입니다
(iuv query parameter는 예외).
그러나 interaction URL이 coordinator에 hosted되고 workflow service에는 hosted되지 않는 것이
중요합니다. 이를 통해 coordinator의 Web origin(DNS domain name)을
consumer가 일관된 trust signal로 사용할 수 있으며,
action을 조정할 수 있는 business rule을 적용할 수 있습니다.
interaction QR Code는 ISO18004:2024: QR Code Bar Code Symbology Specification에 따라 QR code로 표현된 interaction URL이어야 MUST 합니다. 광범위한 interoperability를 보장하기 위해 interaction URL의 길이는 가능한 한 짧아야 SHOULD 하며, 400개의 alphanumeric character를 초과하지 않아야 SHOULD NOT 하고, 4,296개의 alphanumeric character를 초과해서는 안 됩니다 MUST NOT. interaction QR code의 예는 아래에서 확인할 수 있습니다:
https://app.example/interactions/z8n38Dp7a?iuv=1에 대한 interaction QR code
interaction URL을 처리할 수 있는 application을
호출하는 것은 유용할 수 있습니다. 이 section은 이러한 목적을 위해
interaction: protocol scheme
형식을 정의합니다. protocol scheme의 형식은 다음 syntax를 준수해야
MUST 합니다:
| Interaction Protocol Scheme |
|---|
scheme = "interaction:" interaction-url interaction-url = URL |
interaction-url은 URL Standard를
준수하고,
그 URL의 resource를 retrieve하면
interaction protocols response가 생성되는
모든 URL입니다.
interaction:https://app.example/interactions/z8n38Dp7a?iuv=1
interaction URL을 retrieve하면 remote system과 interaction을 시작하는 방법에 대한 지침이 생성됩니다.
interaction URL이
application/json의 Accept header를 사용하여 fetch되는 경우,
protocols map을 포함하는
단일 JSON object가 반환되어야 MUST 합니다.
여기서 각 key는
protocol identifier이고, 각
value는
interaction을 initiate하는 데 사용할 수 있는 URL입니다. 예를 들어
https://app.example/interactions/z8n38Dp7a?iuv=1 interaction
URL에 HTTP GET을 수행하면
다음 response 중 하나가 발생할 수 있습니다:
{
"protocols": {
"inviteRequest": "https://saas.example/workflows/123/exchanges/987/invite-request/response",
"vcapi": "https://saas.example/workflows/123/exchanges/987",
"OID4VP": "openid4vp://?client_id=https%3A%2F%2Fapp.example%2Fworkflows%2F123%2Fexchanges%2F987%2Fopenid%2Fclient%2Fauthorization%2Fresponse&request_uri=https%3A%2F%2Fapp.example%2Fworkflows%2F123%2Fexchanges%2F987%2Fopenid%2Fclient%2Fauthorization%2Frequest'"
}
}
{
"protocols": {
"inviteRequest": "https://saas.example/interactions/123/invite-request/response"
}
}
protocol response는
Exchange Protocols 가져오기 section에서 설명한
delegation mechanism과 유사하게, HTTPS domain trust model을 통해
protocol execution이 third-party service provider에게 위임될 수 있게 합니다.
예를 들어 website app.example은 protocol 목록에
saas.example domain을 포함하여 exchange의 operation을
partner saas.example에게 위임할 수 있습니다.
interaction URL이 인식되지 않는
Accept header를 사용하여 fetch되는 경우,
interaction URL을 처리하는 방법을 이해하는 특정 software를 사용하라고 사람에게 지시하는
text/html document가 반환되어야 MUST 합니다.
일부 coordinator 구현은 protocols endpoint를 exchange instance의 protocols endpoint로
pass-through하는 방식으로 구현할 것입니다. 예를 들어
https://app.example/interactions/z8n38Dp7a?iuv=1에 대한 GET은
https://app.example/workflows/123/exchanges/987/protocols에 대한 pass-through
GET을 발생시키며, 이는 위 response를 반환할 것입니다. 이러한 방식으로 interaction URL을 구현하면
더 쉬운 구현 경로를 제공할 수 있습니다.
inviteRequest interaction protocol은 local system이 remote system에게
특정 URL을 통해 remote system에 대한 invitation을 원한다는 신호를 보내는 데 사용됩니다.
예를 들어 개인이 use-case specific interaction에 참여할 수 있는 website가 해당 URL이 될 수 있습니다.
inviteRequest interaction protocol이 선택되면, local system은 HTTP POST를 사용하여
data를 전송하고 remote system에게 해당 개인을 어디로 보내야 하는지 지시합니다.
POST data의 몇 가지 예가 아래에 표시되어 있습니다.
이러한 예는 이 명세가 "url" field의 형식 지정 방식에 대한 요구사항을 명시하지 않지만,
이 interaction mechanism의 구현자가 unique ID를 사용할 것을 권장한다는 점을
강조하기 위한 것입니다:
{
"url": "https://website.example/checkout/8372974",
"purpose": "Checkout at ShopCo",
"referenceId": "417bcaf2-14d9-11f0-99d7-9f094678517b"
}
{
"url": "https://website.example/forms/7864165",
"purpose": "Fill out online form",
"referenceId": "d4a6e5b8-1715-4654-8e47-e68b311756d1"
}
vcapi interaction protocol은 Section 3.6.5
Exchange에 참여에서 설명한 특정 exchange를
initiate하는 데 사용됩니다.
{
"verifiablePresentationRequest": {
"query": [{
"type": "QueryByExample",
"credentialQuery": {
"reason": "Please provide your student ID.",
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2",
],
"type": "StudentIdCredential",
"credentialSubject": {
"studentId": ""
},
},
"trustedIssuer": [{
"issuer": "did:web:university.example"
}]
}
}],
"challenge": "5e34826e-14da-11f0-98a5-8b1c0a196728",
"domain": "university.example"
}
}
구현이 문서를 처리하는 동안 이상을 감지하면, ProblemDetails 객체를 사용하여 문제를 다른 software system에 보고할 수 있다. 이러한 객체의 interface는 data를 encoding하기 위해 [RFC9457]을 따른다. ProblemDetails map은 다음 속성으로 구성된다:
type key는
존재해야 MUST 하며, 그 값은 문제의 type을 식별하는 URL이어야
MUST 한다.
title key는
문제에 대한 짧지만 구체적인 사람이 읽을 수 있는
문자열을 제공해야 SHOULD 한다.
detail key는
문제에 대한
더 긴 사람이 읽을 수 있는 문자열을 제공해야
SHOULD 한다.
detail 및 instance와 같은
key를 활용하여,
security concern을 의식하고 민감한 정보를 공개하지 않으면서 error에 대한
더 많은 context feedback을 제공하는 것이 권장된다.
이 명세는 다음 problem description type을 정의한다:
구현이 보고할 수 있는 ProblemDetails의 추가 목록은 다음 명세에서 찾을 수 있다:
{
"type": "https://www.w3.org/TR/vc-data-model#CRYPTOGRAPHIC_SECURITY_ERROR",
"status": 400,
"title": "CRYPTOGRAPHIC_SECURITY_ERROR",
"detail": "The cryptographic security mechanism couldn't be verified. This is likely due to a malformed proof or an invalid verificationMethod."
}
위 예제의 type URL은 VCDM v2.0이 global standard가 된 이후
향후 동작할 것이다. error가 적절한 위치로 연결되도록 하기 위해, 당분간
https://www.w3.org/TR/vc-data-model의 base URL을
www.w3.org/TR/vc-data-model-2.0으로 바꿀 수 있다.
구현자는 production environment에서 모든 server error를 sanitize할 것을 강력히 권고받으며, 그렇게 하지 않으면 information disclosure로 이어질 수 있다.
verification을 수행하는 동안 error를 발생시키는 것을 피하고, 대신 verification result에 포함할 ProblemDetails 객체를 수집하는 것이 권장된다.
이 명세는 verification error와 verification warning의 구분을 정의한다.
Error는 cryptography, data model 및 malformed context와 관련된
ProblemDetails이며 복구할 수 없다. Warning은
status 및 validity period와 관련된 ProblemDetails이며,
복구할 수 있거나 후속 action을 application의 재량에 맡길 수 있다.
error가 포함되어 있으면 VerificationResponse 객체의 verified 속성은
false로 설정되어야 MUST 하며, error가 포함되어 있지 않으면
true로 설정되어야
MUST 한다.
{
"verified": false,
"document": verifiableCredential,
"mediaType": "application/vc",
"controller": issuer,
"controllerDocument": didDocument,
"warnings": [ProblemDetails],
"errors": [ProblemDetails]
}
검증 가능한 자격 증명 [VC-DATA-MODEL-2.0]은 오용과 사기의 위험을 완화하도록 설계된 표준 data model이다. data model로서 검증 가능한 자격 증명은 protocol-neutral이며 적어도 두 유형의 entity를 고려한다: issuer 및 subject. 검증 가능한 자격 증명의 subject가 자연인이거나 자연인과 연결되어 있는 경우, 표준화된 검증 가능한 자격 증명의 훨씬 더 효율적인 처리는 그 analog 선행물과 비교해 개인정보 보호와 인권에 영향을 미칠 수 있다.
검증 가능한 자격 증명을 발급하기 위한 표준화된 API와 protocol 형태의 기술은 검증 가능한 자격 증명 처리의 효율성을 더욱 향상시키고, 예기치 못한 개인정보 보호 및 인권 결과의 위험을 증가시킨다.
검증 가능한 자격 증명 발급에는 request phase와 delivery phase가 있다. request는 subject 또는 다른 role이 수행할 수 있으며, delivery는 subject가 제어할 수도 있고 제어하지 않을 수도 있는 client로 이루어질 수 있다. 위임은 두 phase 모두와 매우 관련이 깊다. issuer는 request 처리를 별도의 entity에 위임할 수 있다. subject도 자신의 측면에서 검증 가능한 자격 증명을 요청할 권한을 별도의 entity에 위임할 수 있다. subject가 항상 위임을 수행할 capability나 능력을 가지는 것은 아니라는 점에 유의하라. 예로는 갓 태어난 아기, 반려동물, 치매 환자가 있다. 따라서 request는 subject가 위임하지 않은 제3자가 수행할 수 있다. 위임할 수 있는 능력은 검증 가능한 자격 증명 처리의 향상된 효율성에서 세 번째 차원이며, 개인정보 보호와 인권에 영향을 미친다.
이 명세에 설명된 architecture는 효율성과 개인정보 보호 및 인권 존중의 조합을 통해 시장 수용을 위해 설계되었다. 검증 가능한 자격 증명을 처리하기 위한 API와 protocol은 subject role에 의한 위임보다 issuer role에 의한 위임을 선호하지 않는다.
verifier가 특정 issuer에게 특정 검증 가능한 자격 증명에 대해 연락하는 것은 나쁜 개인정보 보호 관행으로 간주된다. 이 관행은 "phoning home"으로 알려져 있으며, holder, issuer, verifier 및 검증 가능한 자격 증명에 표현된 다른 당사자 간의 개인정보 보호 기대가 일치하지 않는 결과를 초래할 수 있다. Phoning home은 issuer가 특정 검증 가능한 자격 증명의 사용과 이를 의심하지 않는 당사자를 correlate할 수 있게 하며, 이는 해당 credentials의 사용과 관련해 각 entity가 가질 수 있는 개인정보 보호 기대를 위반할 수 있다. 예를 들어 holder가 자신과 verifier 사이의 private interaction으로 기대한 것이, issuer에게 해당 interaction이 통지되는 상황이 된다.
issuer에게 개인정보 보호 방식으로 연락하는 것이 holder의 개인정보 보호 기대를 지키는 interaction도 일부 있다. 예를 들어 group privacy를 제공하는 status list를 통해 privacy-respecting manner로 revocation status information을 얻기 위해 issuer에게 연락하는 것은, status list의 retrieval을 기반으로 issuer가 어떤 검증 가능한 자격 증명이 query되고 있는지 특정할 수 없는 한 허용될 수 있다. 그러한 mechanism 중 하나에 대한 자세한 내용은 Bitstring Status List v1.0 명세를 참조하라.
Verifier는 개인정보 보호 위반을 만들 수 있는 방식으로 "phone home"하지 말 것을 촉구받는다. 검증 가능한 자격 증명에서 연결된 content를 retrieve할 때, Oblivious HTTP와 같은 mechanism을 사용하고 result를 적극적으로 caching하면 ecosystem의 개인정보 보호 특성을 개선할 수 있다.
digital wallet software와 같은 Holder coordinator 구현은 software가 이해하지 못하는 proof를 포함하는 검증 가능한 자격 증명을 수신하고 저장할 수 있지만, 이러한 proof는 구현에 의해 presented되어서는 안 된다. 여러 proof를 가진 검증 가능한 자격 증명은, 그중 일부를 구현이 이해하고 다른 일부는 이해하지 못하는 경우, 선택한 proof가 구현이 이해하는 것이고 다른 proof가 presentation 전에 제거된다면 구현에 의해 presented될 수 있다. 구현은 이해하는 proof의 allow list를 유지하고, 존재하지 않는 proof가 presentation 전에 제거되도록 보장한다.
구현은 알 수 없는 proof의 존재를 decentralized ecosystem에서 잠재적인 adoption signal로 사용할 수 있다. 또한 구현자는 three party model에서 holder coordinator가 issuer와 verifier 사이의 conduit로 작동하여, holder coordinator가 특정 verification을 반드시 구현하지 않더라도/않는 경우에도 두 당사자 간의 interoperability를 가능하게 한다는 점을 이해하는 것이 중요하다. 다른 영역의 예로: "Web browser는 자체 PDF-reader 기능을 추가하기 전에 PDF file을 download하고 저장할 수 있었다" — 이러한 종류의 decentralized innovation, interoperability 및 progressive enhancement는 three party model에서, 그리고 보다 일반적으로 scalable, decentralized ecosystem에서 중요하다. 또한 현재 software가 아직 이해하지 못하는 proof를 적어도 하나 포함한 검증 가능한 자격 증명을 저장하기 위해서만 사람들이 특정한 새롭고 다른 software를 채택하도록 강제하지 않음으로써 centralization을 줄이는 데 도움이 되는 것도 중요하다.
holder coordinator는 verify할 software가 없더라도 일부
proof를 present할 수
있을지도 모르지만, 이는 추측이 아니라 확실히 이해되어야 한다. 즉,
저장된 검증
가능한 자격 증명의
copy를 presentation에 추가할 때,
holder
software는
안전하게 present할 수 있음을 명시적으로 알지 못하는 모든
proof를
제거해야 한다. software가 안전하게 present할 수 있음을 명시적으로 아는
proof는 남아 있을 수 있다.
예를 들어 digital wallet이 ecdsa-rdfc-2019
proof는 verify할 수
있지만
ecdsa-jcs-2019 proof는 verify할 수
없다면,
여전히 둘 중 하나를 present할 수 있다. proof 중
selective
disclosure
및/또는 unlinkable
disclosure
기능을 제공하는 것은
transformation이 필요하다
(즉, base proof가 derived proof와 "reveal document"로 변환됨). 따라서
wallet이 proof를 derive하는 절차를 구현하지 않았다면 이러한
proof를
present할 수 없다.
wallet이 실수로 base proof를 present하지 않는 것이 매우 중요하다. 이는
holder에게 비밀인
정보를
포함할 수 있기 때문이다.
이 명세는 다음 이유로 interaction URL에 HTTPS를 사용할 것을 강력히 제안한다:
HTTPS trust model에 rooted되지 않은 protocol scheme을 사용하려면 별도의 encryption protocol, key management 및 trust model을 사용해야 하며, 이는 대개 덜 광범위하게 개발되고 배포되어 있고, threat 및 privacy model을 결정하기 위해 훨씬 더 많은 개발과 분석이 필요하다.
이 명세에서 제공하는 API는 검증 가능한 자격 증명과 검증 가능한 presentation을 storage service에서 삭제할 수 있게 한다. 이러한 삭제의 결과와 그로 인해 발생할 수 있는 side-effect는 이 명세의 범위를 벗어난다. 그러나 구현자는 deletion을 구현할 수 있는 다양한 방식을 이해할 것을 권고받는다. 이 명세에서 고려되는 deletion 유형은 적어도 두 가지가 있다.
부분 삭제는 record를 deletion 대상으로 표시하지만 원래 information의 일부 또는 전부를 계속 저장한다. 이 operation mode는 특정 기간 동안 모든 credentials 및/또는 presentations에 대한 audit requirement가 있거나, 원래 credential을 복구하는 것이 제공할 만한 유용한 feature일 수 있는 경우 유용할 수 있다.
완전 삭제는 주어진 검증 가능한 자격 증명 또는 검증 가능한 presentation과 관련된 모든 information을 복구할 수 없는 방식으로 purge한다. 이 operation mode는 outdated되어 audit 필요를 벗어난 information을 제거하거나 어떤 종류의 "잊힐 권리" request에 응답할 때 유용할 수 있다.
검증 가능한 자격 증명을 삭제할 때는 그 status information의 처리를 고려해야 한다. 일부 use case에서는 특정 검증 가능한 자격 증명의 deletion이 해당 검증 가능한 자격 증명의 revocation 및 suspension bit도 설정하도록 요구할 수 있으며, 그 결과 삭제된 credential에 대한 모든 종류의 status check가 실패하고 credential의 사용이 중단된다.
위 scenario를 고려할 때, 구현자는 delete 후 발생하는 system action을 configurable하게 허용하여 system flexibility가 모든 검증 가능한 자격 증명 use case를 처리하기에 충분하도록 할 것을 권고받는다.
더 큰 transaction은 DoS incident를 유발할 수 있다. endpoint가 수락하는 payload size를 instance level에서 configure하는 것이 권장된다.
대부분의 경우, 단순히 proof를 verifying하는 것만으로는 수신한 data를 적절히 처리하기에 충분하지 않을 수 있다. Verifier service는 use case에 기반하여 추가 validation step을 configure할 것으로 예상된다. 이러한 추가 validation을 정의하기 위해 구현자는 Section 2.3: Resource Integrity 및 Section 2.4: Contexts and Vocabularies와 같은 명세를 참조할 수 있으며, Verifiable Credential Data Integrity 1.0 명세에서 context handling과 integrity verification에 대한 추가 정보를 찾을 수 있다.
부적절한 validation은 종종 security vulnerability로 이어진다.
추가 validation step은 problem details를 통해 verification response object를 반환할 때 반영될 수 있다.
구현자는 이 명세를 구현할 때 industry standard secure coding practice를 사용할 것을 촉구받는다. 매우 경험이 많은 software developer도 실수할 수 있으며, secure coding checklist와 vulnerability scanning software를 사용하면 security compromise를 초래할 수 있는 error를 포착할 수 있다. OWASP Secure Coding Practices Checklist 및 OWASP Web Security Testing Guide와 같은 checklist와 guide를 따르면 insecure implementation의 가능성을 줄이는 데 도움이 될 수 있다.
이 명세에 설명된 검증 가능한 자격 증명의 lifecycle을 관리하기 위한 interface는 generalized nature를 가지므로, 그 사용의 security implication이 독자에게 즉시 명백하지 않을 수 있다. complete software system에서 고려해야 할 security concern의 종류를 이해하기 위해, 구현자는 이 기술이 Verifiable Credentials Data Model v2.0 명세(특히 Verifiable Credential Security Considerations 섹션)와 Verifiable Credential Data Integrity 1.0 명세(특히 Data Integrity Security Considerations 섹션)에서 어떻게 사용될 수 있는지 읽을 것을 촉구받는다.
status service는 status list 관리를 위한 세 가지 주요 operation을 제공한다:
이 명세에 설명된 status list operation(create list, get list, set status)은 non-normative이며 권장되는 implementation approach를 나타낸다. Status list creation 및 management는 다음과 같이 이 명세에서 고려하지 않은 다양한 factor에 의존할 수 있다:
구현자는 결과 status information이 사용 중인 status mechanism specification, 예를 들어 Bitstring Status List v1.0 명세에 따라 verify될 수 있는 한, 자신의 specific need에 따라 status list management system을 자유롭게 설계할 수 있다.
privacy를 극대화하기 위해, verifier는 status service를 직접 query하기보다 holder로부터 status information을 얻는 것이 권장된다. holder가 검증 가능한 자격 증명을 present할 때, 그들은 corresponding status list credential 또는 충분한 status information을 포함하여 verifier가 issuer에게 연락하지 않고도 verification을 수행할 수 있게 하는 것이 권장된다. 이 approach는 status check가 특정 verifier 또는 검증 가능한 자격 증명과 correlate되는 것을 방지한다.
이 endpoint는 검증 가능한 자격 증명의 status를 추적하는 데 사용할 수 있는 새 status list credential을 생성하는 데 사용된다. status list 자체는 여러 credentials에 대한 status information을 포함하는 검증 가능한 자격 증명이며, privacy-preserving status check를 가능하게 한다. status list credential은 response로 반환되며 verification 목적을 위해 publicly accessible하게 만들 수 있다.
verification process의 consistency를 위해, status list credential은 일반적으로 연결될 검증 가능한 자격 증명과 동일한 securing mechanism(proof type 및 cryptographic suite)을 사용한다. 이를 통해 verifier는 동일한 verification method를 사용하여 credentials와 그 associated status list를 모두 verify할 수 있다.
검증 가능한 자격 증명 status를 관리하는 specific mechanism에 대해서는, 구현자가 [VC-BITSTRING-STATUS-LIST] 명세와 같은 well-known external specification을 참조하는 것이 권장된다. 이 명세는 status list credential을 구현하는 방법의 normative example을 제공한다.
POST /status-lists - 새 status list를 생성한다
/status-lists endpoint는 POST를 받을 때 다음 schema를 사용한다:
| 속성 | 설명 |
|---|---|
statusPurpose [string] |
status list의 목적(예: "revocation", "suspension")이다. 이는 list가 추적할 status information의 type을 결정한다. |
id [string] |
status list의 선택적 identifier이다. 제공되지 않으면 service가 생성한다. |
options [object] |
객체 |
/status-lists endpoint는 POST를 받을 때 다음 response 중 하나를 생성할 수 있다:
| 응답 | 본문 |
|---|---|
| 201 | Status list가 성공적으로 생성됨 content-type: application/json
다음 형식의 객체:
|
| 400 | Bad Request |
이 endpoint는 publicly accessible한 status list credential을 retrieve한다. 이 endpoint는 일반적으로 authentication 없이 publicly accessible하여 verifier와 holder가 status information을 retrieve할 수 있게 한다.
endpoint는 요청된 media type 또는 service에 configure된 default format에 기반하여
적절한 format으로 status list credential을 반환한다.
response는 일반적으로 VerifiableCredential 또는
EnvelopedVerifiableCredential이며, 이 status list를 참조하는
검증
가능한 자격 증명에서
사용되는 format과 consistent하다. 이를 통해
verifier는 associated credentials를 verifying할 때 사용하는 동일한 mechanism을 사용하여
status list를 process할 수 있다.
privacy-preserving status mechanism의 경우, verifier는 이 endpoint를
직접 query하기보다 holder로부터
status information을 얻는 것이 권장된다. holder가
status information(예: credentialStatus 속성)을 포함하는
검증
가능한
자격 증명을 present할 때, holder는
verification을 가능하게 하기 위해 corresponding status list credential 또는 충분한
status information도 제공하는 것이 권장된다. 이 approach는
issuer가
status check를
특정 verifier
또는 검증 가능한
자격 증명과 correlate하는 것을 방지하여
privacy를 보존한다.
verifier가 검증 가능한 자격 증명의 status를 check해야 할 때 권장 flow는 다음과 같다:
이 endpoint는 presentation에 포함할 status list credential을 retrieve해야 하는 holder에게도 유용할 수 있으며, 또는 privacy 관점에서 direct issuer contact가 허용되는 경우에도 유용할 수 있다.
GET /status-lists/{id} - status list credential을 retrieve한다
/status-lists/{id} endpoint는 GET을 받을 때 다음 response 중 하나를 생성할 수 있다:
| 응답 | 본문 |
|---|---|
| 200 | Status list credential이 성공적으로 retrieve됨 content-type: application/json
다음 형식의 객체:
|
| 404 | Status list를 찾을 수 없음 |
이 endpoint는 status list 내에서 발급된 검증 가능한 자격 증명의 status를 update하는 데 사용된다. credential의 status가 변경되어야 하는 경우(예: revoked 또는 suspended), 이 endpoint는 status list credential의 corresponding entry를 update한다.
request는 일반적으로 update할 credential, status list entry information(status list credential identifier 및 해당 list 내 index 포함), 그리고 새 status value를 지정한다. status service는 status list credential을 그에 따라 update한다.
POST /credentials/status - 발급된 credential의 status를 update한다
/credentials/status endpoint는 POST를 받을 때 다음 schema를 사용한다:
| 속성 | 설명 |
|---|---|
credentialId [string] |
credential을 식별한다(identifier는 VC 자체에 나타날 필요는 없다). |
credentialStatus [object] |
update할 특정 status list entry를 식별한다. 다음 형식의 객체여야
MUST 한다:
|
status [boolean] |
새 status를 지정한다. |
indexAllocator [string] |
service가 VC에 어떤 index가 사용/할당되고 있는지 사용하기 위한 것. |
/credentials/status endpoint는 POST를 받을 때 다음 response 중 하나를 생성할 수 있다:
| 응답 | 본문 |
|---|---|
| 200 | Credential status가 성공적으로 update됨 |
| 400 | Bad Request |
| 404 | Credential을 찾을 수 없음 |
아래는 단일 step을 포함하는 최소 workflow로 간주될 수 있는 template의 예와, 그 뒤에 최소 credential의 예를 제시한다. 이러한 두 "minimum" template은 여전히 각 예에서 이루어진 authorization 및 variable choice에 의존한다는 점에 유의하라.
{
"id": "https://localhost:18443/workflows/z19nXMUSyXawSMK6j65Vs4jb1",
"sequence": 0,
"controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"steps": {
"verify": {
"stepTemplate": {
"type": "jsonata",
"template": "{\"verifiablePresentationRequest\": verifiablePresentationRequest}"
}
}
},
"initialStep": "verify",
"zcaps": {...}
}
{
"id": "https://localhost:18443/workflows/z19mYrRgRuwN9PnezmhoJhBoV",
"sequence": 0,
"controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"credentialTemplates": [
{
"type": "jsonata",
"template": "{\"@context\": [\"https://www.w3.org/ns/credentials/v2\", \"https://www.w3.org/ns/credentials/examples/v2\"],\"type\": [\"VerifiableCredential\",\"ExampleNameCredential\"],\"credentialSubject\": {\"name\": name}}"
}
],
"steps": {
"issue": {
"issueRequests": [
{
"credentialTemplateIndex": 0,
"result": "issuedExampleNameCredentialResult"
}
]
}
},
"initialStep": "issue",
"zcaps": {...}
}
아래는 더 복잡한 workflow의 예이다.
이 첫 번째 예는 여러 step을 가지고, verification과 issuance를 포함하며, ZCAP과 OAuth2
authorization을 모두 지원하고,
custom variable의 유무와 관계없이 credential template을 재사용하는 것을 보여주며,
presentation schema check를 가진다.
이 예는 Verifiable Credentials Data Model 2.0(validFrom,
https://www.w3.org/ns/credentials/v2)을 사용한다.
{
"id": "https://localhost:18443/workflows/z19mYrRgRuwN9PnezmhoJhBoV",
"sequence": 0,
"controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"meterId": "https://localhost:18443/meters/z1AG3Ud3apFhGaTBfRm7KZPRY",
"credentialTemplates": [
{
"id": "urn:credential-template-1",
"type": "jsonata",
"template": "\n {\n \"@context\": [\n \"https://www.w3.org/ns/credentials/v2\",\n 'https://www.w3.org/ns/credentials/examples/v2'\n ],\n \"id\": credentialId,\n \"type\": [\n \"VerifiableCredential\",\n \"UniversityDegreeCredential\"\n ],\n \"validFrom\": validFrom,\n \"credentialSubject\": {\n \"id\": results.verify.did,\n \"degree\": {\n \"type\": \"BachelorDegree\",\n \"name\": \"Bachelor of Science and Arts\"\n }\n }\n }\n"
}
],
"steps": {
"verify": {
"createChallenge": true,
"verifiablePresentationRequest": {
"query": [
{
"type": "DIDAuthentication",
"acceptedMethods": [
{
"method": "key"
}
]
},
{
"type": "QueryByExample",
"credentialQuery": [
{
"reason": "We require a verifiable credential to pass this test",
"example": {
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2"
],
"type": "UniversityDegreeCredential"
}
}
]
}
],
"domain": "https://localhost:18443"
},
"presentationSchema": {
"type": "JsonSchema",
"jsonSchema": {
"title": "Presentation",
"type": "object",
"required": [
"@context",
"type",
"verifiableCredential"
],
"additionalProperties": false,
"properties": {
"@context": {
"type": "array"
},
"holder": {
"type": "string"
},
"type": {
"type": "array"
},
"proof": {
"oneOf": [
{
"type": "object"
},
{
"type": "array"
}
]
},
"verifiableCredential": {
"oneOf": [
{
"title": "Strict Degree Credential",
"type": "object",
"required": [
"@context",
"type",
"issuer",
"credentialSubject"
],
"additionalProperties": false,
"properties": {
"@context": {
"type": "array",
"items": [
{
"const": "https://www.w3.org/ns/credentials/v2"
},
{
"const": "https://www.w3.org/ns/credentials/examples/v2"
}
]
},
"id": {
"type": "string"
},
"issuer": {
"const": "did:key:z6Mkjc99Z627zYQTJXTXP5ohoFnjyGP74ooyRmRYabxz8ozo"
},
"type": {
"type": "array",
"items": [
{
"const": "VerifiableCredential"
},
{
"const": "UniversityDegreeCredential"
}
]
},
"validFrom": {
"type": "string"
},
"credentialSubject": {
"type": "object",
"required": [
"degree"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"degree": {
"type": "object",
"required": [
"type",
"name"
],
"additionalProperties": false,
"properties": {
"type": {
"const": "BachelorDegree"
},
"name": {
"const": "Bachelor of Science and Arts"
}
}
}
}
},
"proof": {
"oneOf": [
{
"type": "object"
},
{
"type": "array"
}
]
}
}
},
{
"type": "array",
"minItems": 1,
"items": {
"title": "Strict Degree Credential",
"type": "object",
"required": [
"@context",
"type",
"issuer",
"credentialSubject"
],
"additionalProperties": false,
"properties": {
"@context": {
"type": "array",
"items": [
{
"const": "https://www.w3.org/ns/credentials/v2"
},
{
"const": "https://www.w3.org/ns/credentials/examples/v2"
}
]
},
"id": {
"type": "string"
},
"issuer": {
"const": "did:key:z6Mkjc99Z627zYQTJXTXP5ohoFnjyGP74ooyRmRYabxz8ozo"
},
"type": {
"type": "array",
"items": [
{
"const": "VerifiableCredential"
},
{
"const": "UniversityDegreeCredential"
}
]
},
"validFrom": {
"type": "string"
},
"credentialSubject": {
"type": "object",
"required": [
"degree"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"degree": {
"type": "object",
"required": [
"type",
"name"
],
"additionalProperties": false,
"properties": {
"type": {
"const": "BachelorDegree"
},
"name": {
"const": "Bachelor of Science and Arts"
}
}
}
}
},
"proof": {
"oneOf": [
{
"type": "object"
},
{
"type": "array"
}
]
}
}
}
}
]
}
}
}
},
"nextStep": "issue"
},
"issue": {
"issueRequests": [
{
"credentialTemplateId": "urn:credential-template-1"
},
{
"credentialTemplateId": "urn:credential-template-1",
"variables": {
"credentialId": "urn:different",
"validFrom": "2024-01-01T00:00:00Z",
"results": {
"verify": {
"did": "did:example:1"
}
}
}
}
]
}
},
"initialStep": "verify",
"zcaps": {
"issue": {
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:560e68a8-6c39-454d-8a54-b16c7d1e35fe",
"controller": "did:key:z6MkrFmv97wsVfa7sseVctxAEAoyUL4fpLAGMfGUbtSoC3G3",
"parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fissuers%2Fz1A9Aay1eLcMPnBYEFkkqhZev",
"invocationTarget": "https://localhost:18443/issuers/z1A9Aay1eLcMPnBYEFkkqhZev/credentials/issue",
"expires": "2025-12-01T21:28:44Z",
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-12-01T21:23:44Z",
"verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fissuers%2Fz1A9Aay1eLcMPnBYEFkkqhZev"
],
"proofValue": "z4ubKiW87sRfEqSWRwoLhPGLTMuR7VnYuGyunPkWCbc6oCqUQDQUEz4bWw3zYBWACTywWj4NyBoUJwyH9VVBYZTKY"
}
},
"createChallenge": {
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:07537e74-25d7-49fa-9d30-28728bbb4838",
"controller": "did:key:z6MkrFmv97wsVfa7sseVctxAEAoyUL4fpLAGMfGUbtSoC3G3",
"parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa",
"invocationTarget": "https://localhost:18443/verifiers/z1A2cLHcMzzuGT7sBZiU7AtYa/challenges",
"expires": "2025-12-01T21:28:44Z",
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-12-01T21:23:44Z",
"verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa"
],
"proofValue": "zydEXjYSYFVAVkoHvET2QMqsHgVqxRQoYViU6DDPRncjdSj2VAW19dAFUPBrpYBTt1kwYHeVB9HNZhoHtQL7DJ2A"
}
},
"verifyPresentation": {
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:4f495517-f6bd-488f-b662-fa2f761ccd03",
"controller": "did:key:z6MkrFmv97wsVfa7sseVctxAEAoyUL4fpLAGMfGUbtSoC3G3",
"parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa",
"invocationTarget": "https://localhost:18443/verifiers/z1A2cLHcMzzuGT7sBZiU7AtYa/presentations/verify",
"expires": "2025-12-01T21:28:44Z",
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-12-01T21:23:44Z",
"verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1A2cLHcMzzuGT7sBZiU7AtYa"
],
"proofValue": "z3NmKFcY2o146jTgpoLi6hD6TwRV7uC2SzEQrvTQSi4Sg33xCm3jE2QtYoa5MBGFvax8DCpjpjWdzzdhXUxijXLUG"
}
}
},
"authorization": {
"oauth2": {
"issuerConfigUrl": "https://localhost:18443/.well-known/oauth-authorization-server"
}
}
}
이 두 번째 예는 stepTemplate feature를 사용한다.
exchange를 생성할 때 verifiablePresentationRequest가 variable로 전체 제공될 것을
기대하며,
callback feature를 demonstrate하기 위한 callbackUrl을 포함한다.
{
"id": "https://localhost:18443/workflows/z19nXMUSyXawSMK6j65Vs4jb1",
"sequence": 0,
"controller": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"meterId": "https://localhost:18443/meters/z1A7quFpnVP4NdDURjUv78JVj",
"steps": {
"verify": {
"stepTemplate": {
"type": "jsonata",
"template": "\n {\n \"createChallenge\": true,\n \"verifiablePresentationRequest\": verifiablePresentationRequest,\n \"callback\": {\n \"url\": callbackUrl\n }\n }"
}
}
},
"initialStep": "verify",
"zcaps": {
"createChallenge": {
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:103c3199-ae29-48c0-a848-61752093909c",
"controller": "did:key:z6MkezKzgnoN3fxvdnsNhyf8wacUTLt22gg6PpXi2DRFkdBA",
"parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp",
"invocationTarget": "https://localhost:18443/verifiers/z1AG62DcvrFkaszuQmcvZ1tjp/challenges",
"expires": "2025-12-01T21:32:04Z",
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-12-01T21:27:04Z",
"verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp"
],
"proofValue": "z21ZcYeG7wPae2kvznuqH9V6S3bb3M2Zfs1cEGf4KdYnHB12AAe1to6scLCgdjyLdLM1E3uWWUupkE6xGaNzVnJis"
}
},
"verifyPresentation": {
"@context": [
"https://w3id.org/zcap/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:14b5563a-1f73-4c3b-9fbb-a93b11e1084d",
"controller": "did:key:z6MkezKzgnoN3fxvdnsNhyf8wacUTLt22gg6PpXi2DRFkdBA",
"parentCapability": "urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp",
"invocationTarget": "https://localhost:18443/verifiers/z1AG62DcvrFkaszuQmcvZ1tjp/presentations/verify",
"expires": "2025-12-01T21:32:04Z",
"proof": {
"type": "Ed25519Signature2020",
"created": "2025-12-01T21:27:04Z",
"verificationMethod": "did:key:z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ#z6Mko4QbcRSTBUFiPMU1PfrNM1KWK8qoSef263DfngFohXgZ",
"proofPurpose": "capabilityDelegation",
"capabilityChain": [
"urn:zcap:root:https%3A%2F%2Flocalhost%3A18443%2Fverifiers%2Fz1AG62DcvrFkaszuQmcvZ1tjp"
],
"proofValue": "z5pHj7SvNzB8GamN77kYLCjt66J98pHr5dqVgXpZJ7zHKnA6A2RMgVMvPAc3xxCADbuYsCgioGDPAQjvYzF9XF33u"
}
}
}
}
검증 가능한 자격 증명의 lifecycle에는 workflow의 생성, exchange에 참여하기 위한 initial interaction, issuance, status management, local credential administration, presentation, verification 및 validation이 포함된다. 이 명세는 검증 가능한 자격 증명 lifecycle management를 위한 HTTP-based API를 정의하며, 이는 issuer, holder 및 verifier가 사용할 수 있다. Digital Credential API, OpenID for Verifiable Credential Issuance v1.0, 및 OpenID for Verifiable Presentations v1.0와 같이 이 명세와 유사한 functionality를 제공하는 것처럼 보일 수 있는 다른 명세가 있다. 이 section은 이 명세의 standardization 전에 어떤 다른 명세가 고려되었는지, 그리고 이 명세가 ecosystem의 다른 명세와 어떻게 다른지를 설명한다.
근본적으로, 이 명세는 검증 가능한 자격 증명의 전체 lifecycle management에 초점을 맞춘 유일한 명세이다. 이 명세는 credential format, credential query language 및 credential delivery protocol에 구애받지 않는다. 검증 가능한 자격 증명 또는 enveloped verifiable credential로 표현 가능한 모든 credential format은 이 명세와 함께 사용할 수 있다. 마찬가지로, OpenID for Verifiable Credential Issuance v1.0 또는 OpenID for Verifiable Presentations v1.0와 같은 credential delivery protocol은 이 명세가 정의한 interaction 및 exchange에서 사용할 수 있다. 마지막으로, 이 명세는 technology가 향상되고 market vertical이 specialize됨에 따라 flexibility를 제공하기 위해 여러 credential query language를 지원한다.
이 명세는 그렇게 하지 않으면 vendor lock-in의 기회가 생기기 때문에 검증 가능한 자격 증명 lifecycle management 전체를 위한 API를 정의한다. 검증 가능한 자격 증명의 lifecycle management 전반에서 vendor lock을 방지하는 interface를 제공하는 다른 명세는 존재하지 않는다.
이 section은 이 명세가 W3C Proposed Recommendation이 될 때 review, approval 및 IANA 등록을 위해 Internet Engineering Steering Group (IESG)에 제출될 것이다.
Working Group은 이 명세에 기여한 다음 개인들에게 감사를 표한다: acknowledgement의 최종 목록은 Candidate Recommendation phase가 끝날 때 compilation될 것이다.
이 명세 작업의 일부는 United States Department of Homeland Security의 Silicon Valley Innovation Program이 다음 contract로 funding하였다: 70RSAT20T00000003, 70RSAT20T00000010, 70RSAT20T00000029, 70RSAT20T00000031, 70RSAT20T00000033, and 70RSAT20T00000043. 이 명세의 content는 반드시 U.S. Government의 입장이나 정책을 반영하지 않으며, official endorsement가 inferred되어서는 안 된다.
이 명세의 개발은 또한 W3C Credentials Community Group의 지원을 받았으며, 그 incubation 기간 동안 다음 개인들의 조합이 이전에 chair를 맡았다: Kim Hamilton Duffy, Heather Vescent, Wayne Chang, Mike Prorock, Harrison Tang, Will Abramson, Mahmoud Alkhraishi, and Denken Chen.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: