# OpenID connect with self issued open provider siop v2 ### Spec * https://github.com/Sphereon-Opensource/SIOP-OID4VP * https://openid.net/specs/openid-connect-self-issued-v2-1_0.html * https://openid.net/specs/openid-4-verifiable-presentations-1_0.html ### Example Implementations * https://github.com/Sphereon-Opensource/SIOP-OID4VP # OpenID for Verifiable Credential Issuance (OIDC4VC) ### Spec pre auth flow - https://openid.github.io/OpenID4VCI/openid-4-verifiable-credential-issuance-wg-draft.html#name-pre-authorized-code-flow https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html https://identity.foundation/jwt-vc-presentation-profile/ https://identity.foundation/jwt-vc-issuance-profile/ ### Example Implementations Implementations may test conformance of the wallets to this profile using the following verification websites: Libraries: https://openid.net/sg/openid4vc/libraries/ https://github.com/spruceid/oidc4vci-issuer Verification: https://vcinteroptesting.azurewebsites.net/verifier - `openid-vc://` https://app.vp.interop.spruceid.xyz/ - `mdoc-openid4vp://` https://vc.ping-eng.com/verifier.html - `openid-vc://` https://demo-rp.stg.trustbloc.dev/verifierqr - `openid-vc://` https://verifiablecredentials.dev/presentation https://github.com/TBD54566975/ssi-service/blob/main/cmd/authserver/main.go # Use Case ### Wallet Initiated Issuance during Presentation An End-User comes across a verifier app that is requesting the End-User to present a Credential, e.g., a driving license. The Wallet determines the requested Credential type(s) from the presentation request and notifies the End-User that there is currently no matching Credential in the Wallet. The Wallet selects a Credential Issuer capable of issuing the lacking Credential and, upon End-User consent, sends the End-User to the Credential Issuer's End-User experience (Web site or app). Upon being authenticated and providing consent to issue the Credential into her Wallet, the End-User is sent back to the Wallet. The Wallet informs the End-User that Credential was successfully issued into the Wallet and is ready to be presented to the verifier app that originally requested presentation of that Credential. ### Cred Offer The End-User is starting a job at a new employer. An employer has requested the End-User to upload certain documents to the employee portal. A few days later, the End-User receives an email from the employer notifying her that the employee Credential is ready and asking her to scan a QR code to retrieve it. The End-User scans the QR code with her smartphone, which opens her Wallet. Meanwhile, the End-User has received a text message with a PIN code to her smartphone. After entering that PIN code in the Wallet for security reasons, the End-User confirms the Credential issuance, and receives Credential into the Wallet. # Flow Let's break down the communication flow between the Google backend, the client frontend, and your Verifiable Credential (VC) issuance service in the context of OAuth 2.0 authentication. This process involves several steps where these entities interact to authenticate a user and potentially issue a VC. 1. User Initiates Authentication (Client Frontend → Google Backend) Step 1: The user clicks on "Login with Google" in your application's frontend. Step 2: The client frontend initiates the OAuth 2.0 flow by redirecting the user to the Google OAuth 2.0 authorization endpoint. This URL includes parameters such as your application's client ID, the requested scope, and a redirect URI. 2. User Authenticates with Google (User ↔ Google Backend) Step 3: The user is presented with a Google login page in their browser. After entering their credentials, Google asks the user to grant the requested permissions to your application. Step 4: Upon successful authentication and consent, Google redirects the user back to the specified redirect URI of your application. This redirect includes an authorization code as a query parameter. 3. Backend Exchanges Code for Token (Your VC Issuance Service Backend → Google Backend) Step 5: The client frontend sends the received authorization code to your VC issuance service's backend. Step 6: Your backend server makes a POST request to Google's token endpoint, sending the authorization code and your application's client secret. This is to exchange the authorization code for an access token (and possibly a refresh token). 4. Google Responds with Tokens (Google Backend → Your VC Issuance Service Backend) Step 7: Google validates the provided authorization code, client ID, and client secret. If valid, Google responds with an access token (and a refresh token, if requested). 5. Your Service Uses the Token (Your VC Issuance Service Backend) Step 8: Your backend server can now use the access token to access Google APIs on behalf of the user, within the scope of the granted permissions. For instance, it might retrieve the user's profile information. 6. VC Issuance Logic (Your VC Issuance Service Backend) Step 9: After obtaining necessary user information from Google and completing any additional checks or user data processing, your VC issuance service may create a Verifiable Credential for the user. This step is specific to your application logic and the nature of the credentials being issued. Step 10: The Verifiable Credential is then sent back to the client frontend, either directly or through a process where the client fetches it from your server. 7. Final Step (Your VC Issuance Service Backend → Client Frontend) Step 11: Your client frontend can now use or display the Verifiable Credential as required by your application's functionality. Summary This flow involves interactions between the user's browser (client frontend), Google's authentication services (Google backend), and your application's server (your VC issuance service backend). OAuth 2.0 provides the framework for authentication, while your backend handles the VC issuance logic. Each step in this flow is crucial for securely authenticating the user and ensuring that the VC issuance is based on verified user data. # Example Endpoints # 1. WebFinger Endpoint The client discovers the issuer (OpenID Provider) URL using the WebFinger endpoint. The request includes the user's identifier, such as an email address. ```bash curl -G http://localhost:3000/.well-known/webfinger --data-urlencode "resource=user@example.com" ``` # 2. OpenID Configuration Endpoint Once the issuer URL is known, the client fetches the OP's configuration. ```bash curl http://localhost:3000/.well-known/openid-configuration ``` # 3. Client Registration Endpoint The client registers with the OP and receives client credentials. Here's an example using a simple JSON payload: ```bash curl -X POST http://localhost:3000/op/registration \ -H "Content-Type: application/json" \ -d '{"client_name": "My Client", "redirect_uris": ["https://myclient/callback"]}' ``` # 4. Authorization Endpoint The client redirects the user's browser to the authorization endpoint. This step is typically done through a browser redirect, but for curl: ```bash curl -G http://localhost:3000/op/authorization \ --data-urlencode "response_type=code" \ --data-urlencode "client_id=YOUR_CLIENT_ID" \ --data-urlencode "redirect_uri=https://myclient/callback" \ --data-urlencode "scope=openid" \ --data-urlencode "state=1234" ``` # 5. Token Endpoint After the user consents and the authorization code is received, the client exchanges the code for tokens: ``` bash curl -X POST http://localhost:3000/op/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=https://myclient/callback&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET" ``` # 6. Userinfo Endpoint The client can retrieve user information using the access token: ```bash curl http://localhost:3000/op/userinfo \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` 7. Verifiable Credential Issuance Endpoint Finally, the client requests a verifiable credential: ```bash curl -X POST http://localhost:3000/op/vc-issuance \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` # OIDC4VCI flow * Authorization Server: validates the user's identity (ie. Google for "Sign in with Google") * Credential Issuer Server: issues VCs to users who have been identified by authorization server. * `GET /.well-known/openid-credential-issuer` - returns JSON doc with specific metadata ([spec](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#name-credential-issuer-metadata-p)) * Wallet: client to both servers ```mermaid sequenceDiagram autonumber participant Wallet participant Authorization Server participant Credential Issuer Server Credential Issuer Server ->> Wallet: launch `openid-vc://` URL with pre-auth code ``` <!-- Dignal (desktop) ->> User: display `web5-connect://` qr code User ->> IDA (mobile): Launch IDA IDA (mobile) ->> Dignal (desktop): Send IDA public key Dignal (desktop) ->> Dignal (desktop): Generate 6 word seed Connect Key + encrypt 6 word seed with IDA public key Dignal (desktop) ->> Connect Server: Sends encrypted App DID + requested permissions Dignal (desktop) ->> IDA (mobile): Raises DID-controlling app with Connect Key'd URL and encrypted 6 word seed IDA (mobile) ->> Connect Server: Fetches the encrypted connect request IDA (mobile) ->> IDA (mobile): Decrypts 6 word seed IDA (mobile) ->> IDA (mobile): Decrypts the connect request payload IDA (mobile) ->> IDA (mobile): Presents user with permissions request IDA (mobile) ->> IDA (mobile): User selects DIDs and accepts permissions IDA (mobile) ->> IDA (mobile): Derive App DIDs and create permissions for each IDA (mobile) ->> Connect Server: Sends DIDs + permissions back to app IDA (mobile) ->> Dignal (desktop): Send user back to Dignal Dignal (desktop) ->> Connect Server: Fetches encrypted DIDs + permissions -->