Swiss Profile Issuance
Status: draft - technically complete, but might to be reformulated
Summary
This profile defines the capabilities required to issue Verifiable Credentials (VCs) to a holder’s wallet. It deliberately does not cover the structure or semantics of the credentials themselves, nor does it address trust establishment between wallets, issuers, or other ecosystem entities.
All underlying specifications referenced by the included standards are considered fully supported unless explicitly noted otherwise.
| Contained Specifications | Version | Link to referenced Specification |
|---|---|---|
| OpenID4VCI | 1.0 | OpenID for Verifiable Credential Issuance (OID4VCI) v1.0 |
| OAuth 2.0 DPoP | RFC-9449 | RFC9449 - Demonstrating Proof of Possession (DPoP) |
Cryptography
To decrease complexity, initially the cryptographic options are limited to following algorithms.
- JWS algorithm MUST be ES256.
- Encryption MUST uses only ECDH-ES with P-256 Keys with A128GCM or A256GCM algorithm.
- If zipping is possible, Deflate (DEF) MUST be used.
- If using encryption is possible, it MUST be used.
OpenID for Verifiable Credential Issuance (OID4VCI) v1.0
This section details the implementation notes and gaps pertaining to the supported specifications.
The specifications are fully supported by this profile (and components adhering to it) except for the specific cases mentioned in the following subsections.
3. Overview
3.3. Core Concepts
3.3.1. Credential Formats and Credential Format Profiles
Swiss Profile Issuance only supports IETF SD-JWT VC (see Swiss Profile VC)
Credential Format Profiles “ISO mdoc” and “W3C VCDM” are not supported.
3.3.3 Issuance Flow Variations
Pre-Authorized Code Flow MUST be supported.
Authorization Code Flow and Wallet initiated communication are not supported.
3.3.4. Identifying Credentials Being Issued Throughout the Issuance Flow
authorization_details is not used. It is expected that the credential issuer links the credential to be issued to the wallet through the pre-authorized_code.
scope is NOT used.
3.4. Authorization Code Flow
Authorization Code Flow is NOT SUPPORTED.
3.5. Pre-Authorized Code Flow
(4) Token Request requires use of Demonstrating Proof of Possession (DPoP)
Registering a DPoP key MUST come with a key attestation (with the same security level as allowed by the issuer for the holder binding key) in case where a hardware-bound credential is requested.
Transaction Code tx_code MUST be supported. The use of Transaction Code is optional, but recommended.
Wallets MUST support 6 digit tx_codes. Issuers SHOULD invalidate a credential offer after 5 failed retries.
Credential
4.1. Credential Offer
credential_offer MUST be supported.
credential_offer_uri is NOT SUPPORTED.
4.1.1.Credential Offer Parameters
Grant Type authorization_code is NOT SUPPORTED
authorization_server is NOT SUPPORTED. It is expected that the Credential Issuer Server is also the authorization server.
The array credential_configuration_ids SHOULD have only one (1) entry. If there are more than one entries the wallet SHOULD only use the first.
4.1.2. Sending Credential Offer by Value Using credential_offer Parameter
Both URL schemes openid-credential-offer:// and swiyu:// MUST be supported by wallets.
5. Authorization Endpoint
Authorization Endpoint is NOT SUPPORTED.
6. Token Endpoint
Issuers and Wallets MUST support pre-authorized_code.
For Verifiable Credential Lifecycle such as renewal, Wallets MUST support refresh_token. Issuers MAY support refresh_tokens.
Requests to the token endpoint MUST be sent with a DPoP Header.
6.1.1 Request Credential Issuance using authorization_details Parameter
authorization_details are NOT supported
6.2. Successful Token Response
Authorization server MUST NOT return authorization_details
7. Nonce Endpoint
It is RECOMMENDED that the nonce is a a self contained nonce, which the issuer can decern to be not valid without registering every nonce which has been requested from this public endpoint.
A self-contained nonce refers to a single-use string or number that carries all necessary information for its validation within itself, eliminating the need for storing possible valid nonces which have not been used.
7.2. Nonce Response
Issuers MUST provide a DPoP nonce.
8. Credential Endpoint
Wallets MUST support key attestation.
8.2. Credential Request
Requests MUST be sent with a DPoP Header.
credential_identifier is NOT supported.
credential_configuration_id MUST be set to credential_configuration_id from the credential offer.
credential_response_encryption MUST be used.
8.3. Credential Response
The number of elements in the credentials array MUST match the exact number of keys that the Wallet has provided via the proofs parameter of the Credential Request.
notification_id is NOT supported.
9. Deferred Credential Endpoint
Requests MUST be sent with a DPoP Header.
11. Notification Endpoint
Notification Endpoint MUST NOT be supported by the wallet for privacy reasons.
12. Metadata
12.1. Client Metadata
Client Metadata is NOT SUPPORTED.
12.2. Credential Issuer Metadata
12.2.2. Credential Issuer Metadata Retrieval
Issuers and Wallets MUST support well-known URIs as described in OID Connect Discovery (OIDC) with appended .well-known path.
Example for OIDC style .well-known URI: https://example.com/issuer1 will lead to an HTTP call:
GET https://example.com/issuer1/.well-known/openid-configuration
Wallets MUST support well-known URIs as described in IETF RFC 5785 where the well-known URI is inserted at the beginning of the path component of an URI.
Issuers SHOULD support these well-known URIs.
Example for RFC 5785 style .well-known URI: https://example.com/issuer1 will lead to an HTTP call:
GET https://example.com/.well-known/openid-configuration/issuer1
12.2.3. Signed Metadata
Issuers MUST also provide Signed Metadata.
The wallet MUST request signed metadata.
Signed Metadata MUST be used.
The signed metadata MUST be verified according swiss trust system.
The kid header claim is REQUIRED and must be a absolute fragment containing a DID as described in swiss-profile-anchor.
Swiss Profile version indication with parameter profile_version in Credential Issuer Metadata JWT header is REQUIRED.
{
// header
"typ":"openidvci-issuer-metadata+jwt",
"alg":"ES256",
"profile_version": "swiss-profile-issuance:1.0.0"
}
.
{
// payload
}
12.2.4. Credential Issuer Metadata Parameters
authorization_serversis NOT SUPPORTED.notification_endpointis NOT SUPPORTED.nonce_endpointis REQUIREDcredential_request_encryptionis REQUIRED.credential_response_encryptionis REQUIRED.batch_credential_issuanceis RECOMMENDED for privacy relevant use-cases.batch_sizeis REQUIRED. Integer value MUST be at least 10 specifying the maximum array size for the proofs parameter in a Credential Request. The wallet MAY send fewer proofs than defined in the batch size. The Issuer MUST create as many Credentials as proofs received.
displayis RECOMMEND to properly display issuer information to walletslogoremains OPTIONALuriMUST be a Data-URL (data URI schema) with MIME-type (media type) image/jpeg or image/png and be base64 encoded. This means theurimust begin withdata:image/png;base64ordata:image/jpeg;base64
credential_configurations_supportedscopeis NOT SUPPORTEDcryptographic_binding_methods_supportedMUST bejwkas only JWK format for holder bindings are supported.proof_types_supportedMUST bejwtas only JWT format is supported.key_attestations_requiredMUST be supported by wallets, and MAY be used by issuers.
credential_metadatadisplayMAY be used as fallback to OCAlogoremains OPTIONALuriMUST be a Data-URL (data URI schema) with MIME-type (media type)image/jpegorimage/pngand be base64 encoded. This means theurimust begin withdata:image/png;base64ordata:image/jpeg;base64
background_imageis NOT SUPPORTEDtext_coloris NOT SUPPORTED
claimsremains OPTIONALmandatoryis NOT SUPPORTED
Swiss Profile version indication with parameter profile_version in Credential Issuer Metadata JSON body is REQUIRED.
{
"profile_version": "swiss-profile-issuance:1.0.0"
...
}
12.3. OAuth 2.0 Authorization Server Metadata
The OAuth 2.0 Authorization Server Metadata are provided signed the same way as defined in 12.2.3. Signed Metadata for credential issuer metadata as application/jwt.
13. Security Considerations
13.6. Pre-Authorized Code Flow
Issuer SHOULD accept pre-authorized codes only once.
When providing the Pre-Authorized Code as QR code, issuers SHOULD use the transaction code (tx_code) and provide it though a secondary channel (text message or email).
13.11. Application-Layer Encryption
Application-Layer encryption MUST be used for request and response.
Encryption JWK MUST include the alg claim. The alg claim MUST be ECDH-ES.
14. Implementation Considerations
14.5. Refreshing Issued Credentials
Wallets can refresh Credentials by re-requesting them at the Credential Endpoint with a valid Access Token and DPoP.
Issuers can always refuse the refresh.
If refused because a refresh is already in progress, Issuer MUST respond with error code 429 (Too Many Requests).
14.6. Batch Issuing Credentials
The Wallet MUST send at maximums the amount of proofs defined in the issuer metadata batch_size.
The Issuer MUST send exactly as many credentials as proofs received.
The Issuer should only use Batch Issuing if unlinkability of Verifiers is desired.
Batch Issuance should not be used for credentials that rely on use cases where the data itself can be used to link different presentations.
There is no guarantee that any wallet uses a credential of a batch only once. Issuers and Verifiers should not rely on the fact that a credential in a batch is only shown once in the wallet. Batch issuing is therefore not suited for a batch of credentials like e.g., day passes, multi ride tickets or loyalty cards as the content of a credential in a batch is required to be equal.
14.A Batch Issuance - Batch Size
The batch size MUST be at least 10, to ensure holder privacy. If holder were to refresh credentials often due to a small batch size, issuers could easily gather telemetry data.
Wallets SHOULD define a limit how many credentials can be issued in one batch, to prevent being overloaded by exceedingly large batch sizes. This can be done by limiting the amount of proof of possessions being created.
Appendix A. Credential Format Profiles
Only Supported Credential Format Profile is IETF SD-JWT VC
A.3. IETF SD-JWT VC
A.3.2. Credential Issuer Metadata
The following additional Credential Issuer metadata parameters are defined for this Credential Format for use in the credential_configurations_supported parameter, in addition to those defined in Section 12.2.4.
vctREQUIRED- vct_extends OPTIONAL - If used in the Credential being issued RECOMMENDED todo!
vct_metadata_uriOPTIONAL - If used in the Credential being issued RECOMMENDED
Appendix D. Key Attestations
Wallets MUST support key attestations.
D.1. Key Attestation in JWT format
Swiss Profile version indication with parameter profile_version in the key attestation JWT header is REQUIRED.
{
// header
"typ":"key-attestation+jwt",
"alg":"ES256",
"profile_version": "swiss-profile-issuance:1.0.0"
}
.
{
// payload
}
OAuth 2.0 Demonstrating Proof of Possession (DPoP) - RFC 9449
The specifications are fully supported by this profile (and components adhering to it) except for the specific cases mentioned in the following subsections.
4. DPoP Proof JWTs
4.2. DPoP Proof JWT Syntax
Swiss Profile version indication with parameter profile_version in DPoP JWT header is REQUIRED.
{
// header
"typ":"dpop+jwt",
"alg":"ES256",
"profile_version": "swiss-profile-issuance:1.0.0"
}
.
{
// payload
}
5. DPoP Access Token Request
5.1. Authorization Server Metadata
If dpop_signing_alg_values_supported is missing it MUST be assumed that the list of supported JWS alg values are the ones listed in this profile under Cryptography.
5.2. Client Registration Metadata
Client Registration Metadata is NOT SUPPORTED. dpop_bound_access_tokens are always presumed to be true.
6. Public Key Confirmation
NOT SUPPORTED. It is assumed that both roles of resource server and authorization server will be fulfilled by the credential issuer.
8. Authorization Server-Provided Nonce
Credential Issuers MUST provide DPoP-Nonces.
Fresh DPoP Nonces MUST be provided in the response of the OID4VCI Nonce Endpoint.
10. Authorization Code Binding to a DPoP Key
Credential Issuer MUST bind Authorization Code to the Holder’s DPoP key.
Appendix
DPoP is expanded with the additional features
Key Attestation
When the one of the credentials offered by the issuer require a key attestation for a hardware bound key (iso_18045_high) , the key used for DPoP has the same requirement. In this case, the wallet MUST provide a Key Attestation JWT as described in OID4VCI Appendix D as part of the DPoP used when registering the public key with the first DPoP Access Token Request. The Issuer MUST validate this first key attestation. If the key attestation is not valid, the Issuer MUST reject the whole DPoP.
In further requests using the same key, the wallet SHOULD NOT include the key attestation in the DPoP. The issuer MUST treat these additional key attestations as unknown parameters.
The key attestation is included in the JWT-Header of the DPoP as the claim key_attestation.
{
"typ": "dpop+jwt",
"alg": "ES256",
"jwk": {
"kty": "EC",
"crv": "P-256",
"x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
"y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
},
"key_attestation": "eyJ0eXAiOiJrZXktYXR0ZXN0YXRpb24rand0IiwiYWxnIjoiRVMyNTYiLCJraWQiOiJkaWQ6d2Vidmg6ZXhhbXBsZS5jb20ja2V5LTEiLCJwcm9maWxlX3ZlcnNpb24iOiJzd2lzcy1wcm9maWxlLWlzc3VhbmNlOjEuMC4wIn0.eyJpc3MiOiJkaWQ6d2Vidmg6ZXhhbXBsZS5jb20iLCJpYXQiOjE1MTYyNDcwMjIsImV4cCI6MTU0MTQ5MzcyNCwia2V5X3N0b3JhZ2UiOlsiaXNvXzE4MDQ1X2hpZ2giXSwiYXR0ZXN0ZWRfa2V5cyI6W3sia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwieSI6Ilp4amlXV2JaTVFHSFZXS1ZRNGhiU0lpcnNWZnVlY0NFNnQ0alQ5RjJIWlEifV19.sj4ulKVk8Xm-Nd-9aODEXI_YpVqPv7llM2fJqZz9R279QN-2g08Rw6U-Dy3u84BVXPYi9B1Wki7mcubO21RrXw",
"profile_version": "swiss-profile-issuance:1.0.0"
}.{
"jti": "-BwC3ESc6acc2lTc",
"htm": "POST",
"htu": "https://server.example.com/token",
"iat": 1562262616
}
Example DPoP Access Token Request with key attestation:
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiVENBRVIxOVp2dTNPSEY0ajRXNHZmU1ZvSElQMUlMaWxEbHM3dkNlR2VtYyIsInkiOiJaeGppV1diWk1RR0hWV0tWUTRoYlNJaXJzVmZ1ZWNDRTZ0NGpUOUYySFpRIn0sImtleV9hdHRlc3RhdGlvbiI6ImV5SjBlWEFpT2lKclpYa3RZWFIwWlhOMFlYUnBiMjRyYW5kMElpd2lZV3huSWpvaVJWTXlOVFlpTENKcmFXUWlPaUprYVdRNmQyVmlkbWc2WlhoaGJYQnNaUzVqYjIwamEyVjVMVEVpTENKd2NtOW1hV3hsWDNabGNuTnBiMjRpT2lKemQybHpjeTF3Y205bWFXeGxMV2x6YzNWaGJtTmxPakV1TUM0d0luMC5leUpwYzNNaU9pSmthV1E2ZDJWaWRtZzZaWGhoYlhCc1pTNWpiMjBpTENKcFlYUWlPakUxTVRZeU5EY3dNaklzSW1WNGNDSTZNVFUwTVRRNU16Y3lOQ3dpYTJWNVgzTjBiM0poWjJVaU9sc2lhWE52WHpFNE1EUTFYMmhwWjJnaVhTd2lZWFIwWlhOMFpXUmZhMlY1Y3lJNlczc2lhM1I1SWpvaVJVTWlMQ0pqY25ZaU9pSlFMVEkxTmlJc0luZ2lPaUpVUTBGRlVqRTVXbloxTTA5SVJqUnFORmMwZG1aVFZtOUlTVkF4U1V4cGJFUnNjemQyUTJWSFpXMWpJaXdpZVNJNklscDRhbWxYVjJKYVRWRkhTRlpYUzFaUk5HaGlVMGxwY25OV1puVmxZME5GTm5RMGFsUTVSakpJV2xFaWZWMTkuc2o0dWxLVms4WG0tTmQtOWFPREVYSV9ZcFZxUHY3bGxNMmZKcVp6OVIyNzlRTi0yZzA4Unc2VS1EeTN1ODRCVlhQWWk5QjFXa2k3bWN1Yk8yMVJyWHciLCJwcm9maWxlX3ZlcnNpb24iOiJzd2lzcy1wcm9maWxlLWlzc3VhbmNlOjEuMC4wIn0.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIjoiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwiaWF0IjoxNTYyMjYyNjE2fQ.wWQJzvfLCFqsEWN2UoiavFf_taZv33sRFFc5WuPYKn4WsJ2HKE3bppWXtkPHh20WIZiYkjH4GRW_VQAJQF9huQ