[java-idp-plugin-vci] branch dev/READMEDOCS updated: Advertize capabilities more accurately in examples
Codeberg
noreply at shibboleth.net
Fri Oct 2 05:40:51 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch dev/READMEDOCS
in repository java-idp-plugin-vci.
View the commit online:
https://codeberg.org/Shibboleth/java-idp-plugin-vci/commit/31dfdb436ffa2a9c08016f55e33f3faab8876e1a
The following commit(s) were added to refs/heads/dev/READMEDOCS by this push:
new 31dfdb4 Advertize capabilities more accurately in examples
31dfdb4 is described below
commit 31dfdb436ffa2a9c08016f55e33f3faab8876e1a
Author: Janne Lauros <janne.lauros at csc.fi>
AuthorDate: Fri Oct 2 08:40:43 2026 +0300
Advertize capabilities more accurately in examples
---
README.md | 1903 +++++++++++++++++---
.../step-1/metadata/verifiable-credentials.json | 10 +-
.../step-2/metadata/verifiable-credentials.json | 15 +-
.../step-3/metadata/verifiable-credentials.json | 20 +-
.../step-4/metadata/verifiable-credentials.json | 20 +-
.../step-5/metadata/verifiable-credentials.json | 27 +-
6 files changed, 1731 insertions(+), 264 deletions(-)
diff --git a/README.md b/README.md
index 7f9f051..f394b40 100644
--- a/README.md
+++ b/README.md
@@ -279,7 +279,7 @@ The content of the file is defined in
of the specification, per credential format. Below only the members that need explaining.
<details>
-<summary>Example contents of metadata/verifiable-credentials.json</summary>
+<summary>metadata/verifiable-credentials.json</summary>
```json
{
@@ -288,10 +288,11 @@ of the specification, per credential format. Below only the members that need ex
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_SDJWT",
"scope": "GeantIncubatorDiploma_SDJWT",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_metadata": {
@@ -315,10 +316,11 @@ of the specification, per credential format. Below only the members that need ex
"GeantIncubatorDiploma_W3C": {
"format": "vc+sd-jwt",
"scope": "GeantIncubatorDiploma_W3C",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_definition": {
@@ -370,7 +372,7 @@ the second one is yours, you publish it yourself as a static file. The terms of
in it:
<details>
-<summary>Example contents of webapps/root/credentials/GeantIncubatorDiploma_W3C.json</summary>
+<summary>webapps/root/credentials/GeantIncubatorDiploma_W3C.json</summary>
```json
{
@@ -486,10 +488,22 @@ for a nonce. A verifier reads the Status List. None of them is a registered clie
endpoints go to the anonymous relying party. Both flows below need it:
<details>
-<summary>Example snippet of conf/relying-party.xml</summary>
+<summary>conf/relying-party.xml</summary>
```xml
-...
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
<bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
<property name="profileConfigurations">
<list>
@@ -510,7 +524,19 @@ endpoints go to the anonymous relying party. Both flows below need it:
</list>
</property>
</bean>
-...
+
+ <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ </list>
+ </property>
+ </bean>
+
+ <util:list id="shibboleth.RelyingPartyOverrides">
+
+ </util:list>
+
+</beans>
```
Full file: [conf/relying-party.xml](docs/example/step-1/conf/relying-party.xml)
@@ -522,30 +548,65 @@ You do not need to write your host name into the templates of *static/*. They us
One thing you need to add is the credential scopes in `scopes_supported` of
*static/oauth-authorization-server.json*, a wallet of the code flow asks a credential by scope:
-```json
-{
- ...
- "scopes_supported":[
- "openid",
- "GeantIncubatorDiploma_SDJWT",
- "GeantIncubatorDiploma_W3C"
- ],
- ...
-}
+<details>
+<summary>static/oauth-authorization-server.json</summary>
+
+```diff
+ {
+ "issuer":"$issuer",
+ "authorization_endpoint":"$baseUrl/idp/profile/oidc/authorize",
+ "pushed_authorization_request_endpoint":"$baseUrl/idp/profile/oauth2/pushed-authorization",
+ "require_pushed_authorization_requests":true,
+ "token_endpoint":"$baseUrl/idp/profile/openid/vci/token",
+ "jwks_uri":"$baseUrl/idp/profile/oidc/keyset",
+ "token_endpoint_auth_methods_supported":[
+ "none"
+ ],
+ "response_types_supported":[
+ "code"
+ ],
+ "grant_types_supported":[
+ "authorization_code",
+ "urn:ietf:params:oauth:grant-type:pre-authorized_code"
+ ],
+ "code_challenge_methods_supported":[
+ "S256"
+ ],
+ "dpop_signing_alg_values_supported":[
+ "ES256",
+ "ES384",
+ "ES512",
+ "PS256",
+ "PS384",
+ "PS512"
+ ],
+ "scopes_supported":[
+- "openid"
++ "openid",
++ "GeantIncubatorDiploma_SDJWT",
++ "GeantIncubatorDiploma_W3C"
+ ],
+ "authorization_details_types_supported":[
+ "openid_credential"
+ ]
+ }
```
Full file: [static/oauth-authorization-server.json](docs/example/step-1/static/oauth-authorization-server.json)
-The `/.well-known/` locations are not IdP paths, you wire them in Jetty. For this step you need
-these rules in *etc/jetty-rewrite-rules.xml*. The later steps add one rule each and the whole
-file is in [Discovery documents](#discovery-documents).
+</details>
+
+The `/.well-known/` locations are not IdP paths, you wire them in Jetty, in
+*etc/jetty-rewrite-rules.xml*. The later steps add one rule each.
<details>
-<summary>Example snippet of etc/jetty-rewrite-rules.xml</summary>
+<summary>etc/jetty-rewrite-rules.xml</summary>
```xml
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
- ...
+ <!-- Credential Issuer metadata -->
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
@@ -554,6 +615,7 @@ file is in [Discovery documents](#discovery-documents).
</New>
</Arg>
</Call>
+ <!-- Authorization server metadata -->
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
@@ -562,6 +624,7 @@ file is in [Discovery documents](#discovery-documents).
</New>
</Arg>
</Call>
+ <!-- OP metadata, of the OP plugin -->
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
@@ -570,6 +633,7 @@ file is in [Discovery documents](#discovery-documents).
</New>
</Arg>
</Call>
+ <!-- The JSON-LD context of the vc+sd-jwt credential is a static file of Jetty -->
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
@@ -578,6 +642,16 @@ file is in [Discovery documents](#discovery-documents).
</New>
</Arg>
</Call>
+ <!-- Wallets running in a browser need this -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
+ <Set name="pattern">/*</Set>
+ <Set name="headerName">Access-Control-Allow-Origin</Set>
+ <Set name="headerValue">*</Set>
+ </New>
+ </Arg>
+ </Call>
</Configure>
```
@@ -585,9 +659,6 @@ Full file: [etc/jetty-rewrite-rules.xml](docs/example/step-1/etc/jetty-rewrite-r
</details>
-Wallets running in a browser need also the `Access-Control-Allow-Origin` rule of the whole file in
-[Discovery documents](#discovery-documents).
-
#### Pre-authorized code flow
**File(s):** *metadata/oidc-client.json*, *conf/relying-party.xml*
@@ -601,7 +672,7 @@ The caller is a confidential client. The wallet that redeems the code is a *seco
different identity. You register both:
<details>
-<summary>Example contents of metadata/oidc-client.json</summary>
+<summary>metadata/oidc-client.json</summary>
```json
[
@@ -631,34 +702,79 @@ Then one relying party for the party that creates the content for credential and
wallet that redeems the code:
<details>
-<summary>Example snippet of conf/relying-party.xml</summary>
-
-```xml
-...
- <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller">
- <property name="profileConfigurations">
- <list>
- <bean parent="OpenID.VCI.CredentialOffer"
- p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
- <bean parent="OAuth.StatusList.Revoke"
- p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
- <bean parent="OAuth.StatusList.Assignments"
- p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
- </list>
- </property>
- </bean>
+<summary>conf/relying-party.xml</summary>
- <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller/wallet">
- <property name="profileConfigurations">
- <list>
- <bean parent="OpenID.VCI.Token"
- p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
- p:tokenEndpointAuthMethods="#{{'none'}}" />
- <bean parent="OpenID.VCI.Credentials" />
- </list>
- </property>
- </bean>
-...
+```diff
+ <?xml version="1.0" encoding="UTF-8"?>
+ <beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ <!-- The wallet reads the Credential Issuer metadata -->
+ <ref bean="OpenID.VCI.IssuerMetadata" />
+ <!-- The wallet finds the token endpoint through this one -->
+ <ref bean="OAuth.AuthorizationServer" />
+ <!-- The wallet asks for the nonce its key proof has to carry -->
+ <ref bean="OpenID.VCI.Nonce" />
+ <!-- A verifier reads the Status List -->
+ <ref bean="OAuth.StatusList" />
+ <!-- Of the OP plugin. Publishes the keys of the OP as a keyset -->
+ <ref bean="OIDC.Keyset" />
+ <!-- Of the OP plugin. Serves /.well-known/openid-configuration -->
+ <ref bean="OIDC.Configuration" />
+ <!-- Of the OP plugin. Needed for the audience values of the wallet -->
+ <ref bean="OAUTH2.TokenAudience" />
+ </list>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ </list>
+ </property>
+ </bean>
+
+ <util:list id="shibboleth.RelyingPartyOverrides">
+
++ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller">
++ <property name="profileConfigurations">
++ <list>
++ <bean parent="OpenID.VCI.CredentialOffer"
++ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
++ <bean parent="OAuth.StatusList.Revoke"
++ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
++ <bean parent="OAuth.StatusList.Assignments"
++ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
++ </list>
++ </property>
++ </bean>
++
++ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller/wallet">
++ <property name="profileConfigurations">
++ <list>
++ <bean parent="OpenID.VCI.Token"
++ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
++ p:tokenEndpointAuthMethods="#{{'none'}}" />
++ <bean parent="OpenID.VCI.Credentials" />
++ </list>
++ </property>
++ </bean>
++
+ </util:list>
+
+ </beans>
```
Full file: [conf/relying-party.xml](docs/example/step-1/conf/relying-party.xml)
@@ -751,28 +867,38 @@ pre-authorized code flow. You register it with the client metadata resolver of t
in the same *metadata/oidc-client.json* as the clients above:
<details>
-<summary>Example snippet of metadata/oidc-client.json</summary>
+<summary>metadata/oidc-client.json</summary>
-```json
-[
- ...
- {
- "client_id": "id.animo.paradym",
- "client_name": "Paradym Wallet",
- "redirect_uris": ["https://paradym.id/invitation/redirect"],
- "scope": "openid GeantIncubatorDiploma_SDJWT GeantIncubatorDiploma_W3C",
- "audience": [
- "credentials",
- "urn:shibboleth.oidc.op.resource:https://issuer.example.org"
- ],
- "token_endpoint_auth_method": "none",
- "response_types": ["code"],
- "grant_types": [
- "authorization_code",
- "urn:ietf:params:oauth:grant-type:pre-authorized_code"
- ]
- }
-]
+```diff
+ [
+ {
+ "client_id": "offer-caller",
+ "client_name": "Credential offer caller",
+ "client_secret": "CHANGE-ME"
+ },
+ {
+ "client_id": "offer-caller/wallet",
+ "client_name": "Wallets redeeming a pre-authorized code minted by offer-caller",
+ "token_endpoint_auth_method": "none",
+ "grant_types": ["urn:ietf:params:oauth:grant-type:pre-authorized_code"]
++ },
++ {
++ "client_id": "id.animo.paradym",
++ "client_name": "Paradym Wallet",
++ "redirect_uris": ["https://paradym.id/invitation/redirect"],
++ "scope": "openid GeantIncubatorDiploma_SDJWT GeantIncubatorDiploma_W3C",
++ "audience": [
++ "credentials",
++ "urn:shibboleth.oidc.op.resource:https://issuer.example.org"
++ ],
++ "token_endpoint_auth_method": "none",
++ "response_types": ["code"],
++ "grant_types": [
++ "authorization_code",
++ "urn:ietf:params:oauth:grant-type:pre-authorized_code"
++ ]
+ }
+ ]
```
Full file: [metadata/oidc-client.json](docs/example/step-1/metadata/oidc-client.json)
@@ -790,32 +916,97 @@ The relying party override needs four profiles, authorize, token, credential and
authorization request:
<details>
-<summary>Example snippet of conf/relying-party.xml</summary>
-
-```xml
-...
- <util:list id="shibboleth.RelyingPartyOverrides">
-
- <bean parent="RelyingPartyByName"
- c:relyingPartyIds="#{{'id.animo.paradym'}}">
- <property name="profileConfigurations">
- <list>
- <bean parent="OIDC.SSO"
- p:authorizationCodeClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
- p:forcePKCE="true"
- p:requirePushedAuthorizationRequest="true" />
- <bean parent="OpenID.VCI.Token"
- p:tokenEndpointAuthMethods="#{{'none'}}"
- p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy" />
- <bean parent="OpenID.VCI.Credentials" />
- <bean parent="OAUTH2.PAR" p:tokenEndpointAuthMethods="#{{'none'}}"
- p:requestUriClaimsSetManipulationStrategy-ref="openidvci.PushedAuthorizationDPoPJktManipulationStrategy" />
- </list>
- </property>
- </bean>
+<summary>conf/relying-party.xml</summary>
- </util:list>
-...
+```diff
+ <?xml version="1.0" encoding="UTF-8"?>
+ <beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ <!-- The wallet reads the Credential Issuer metadata -->
+ <ref bean="OpenID.VCI.IssuerMetadata" />
+ <!-- The wallet finds the token endpoint through this one -->
+ <ref bean="OAuth.AuthorizationServer" />
+ <!-- The wallet asks for the nonce its key proof has to carry -->
+ <ref bean="OpenID.VCI.Nonce" />
+ <!-- A verifier reads the Status List -->
+ <ref bean="OAuth.StatusList" />
+ <!-- Of the OP plugin. Publishes the keys of the OP as a keyset -->
+ <ref bean="OIDC.Keyset" />
+ <!-- Of the OP plugin. Serves /.well-known/openid-configuration -->
+ <ref bean="OIDC.Configuration" />
+ <!-- Of the OP plugin. Needed for the audience values of the wallet -->
+ <ref bean="OAUTH2.TokenAudience" />
+ </list>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ </list>
+ </property>
+ </bean>
+
+ <util:list id="shibboleth.RelyingPartyOverrides">
+
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OpenID.VCI.CredentialOffer"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ <bean parent="OAuth.StatusList.Revoke"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ <bean parent="OAuth.StatusList.Assignments"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ </list>
+ </property>
+ </bean>
+
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller/wallet">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OpenID.VCI.Token"
+ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
+ p:tokenEndpointAuthMethods="#{{'none'}}" />
+ <bean parent="OpenID.VCI.Credentials" />
+ </list>
+ </property>
+ </bean>
+
++ <bean parent="RelyingPartyByName"
++ c:relyingPartyIds="#{{'id.animo.paradym'}}">
++ <property name="profileConfigurations">
++ <list>
++ <bean parent="OIDC.SSO"
++ p:authorizationCodeClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
++ p:forcePKCE="true"
++ p:requirePushedAuthorizationRequest="true" />
++ <bean parent="OpenID.VCI.Token"
++ p:tokenEndpointAuthMethods="#{{'none'}}"
++ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy" />
++ <bean parent="OpenID.VCI.Credentials" />
++ <bean parent="OAUTH2.PAR" p:tokenEndpointAuthMethods="#{{'none'}}"
++ p:requestUriClaimsSetManipulationStrategy-ref="openidvci.PushedAuthorizationDPoPJktManipulationStrategy" />
++ </list>
++ </property>
++ </bean>
++
+ </util:list>
+
+ </beans>
```
Full file: [conf/relying-party.xml](docs/example/step-1/conf/relying-party.xml)
@@ -827,7 +1018,7 @@ same array the Credential Offer API takes. You define it as a `ScriptedAttribute
read the real attributes of the user:
<details>
-<summary>Example snippet of conf/attribute-resolver.xml</summary>
+<summary>conf/attribute-resolver.xml</summary>
```xml
<AttributeDefinition id="GeantIncubatorDiploma" xsi:type="ScriptedAttribute">
@@ -871,16 +1062,24 @@ And you release it to the wallet in *conf/attribute-filter.xml*. This flow reads
**filtered** attribute set, so an attribute that is not released reaches nothing:
<details>
-<summary>Example snippet of conf/attribute-filter.xml</summary>
+<summary>conf/attribute-filter.xml</summary>
```xml
-<AttributeFilterPolicy id="GeantIncubatorDiplomaToWallets">
- <PolicyRequirementRule xsi:type="Requester"
- value="id.animo.paradym" />
- <AttributeRule attributeID="GeantIncubatorDiploma">
- <PermitValueRule xsi:type="ANY" />
- </AttributeRule>
-</AttributeFilterPolicy>
+<?xml version="1.0" encoding="UTF-8"?>
+<AttributeFilterPolicyGroup id="ShibbolethFilterPolicy"
+ xmlns="urn:mace:shibboleth:2.0:afp"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd">
+
+ <AttributeFilterPolicy id="GeantIncubatorDiplomaToWallets">
+ <PolicyRequirementRule xsi:type="Requester"
+ value="id.animo.paradym" />
+ <AttributeRule attributeID="GeantIncubatorDiploma">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ </AttributeFilterPolicy>
+
+</AttributeFilterPolicyGroup>
```
Full file: [conf/attribute-filter.xml](docs/example/step-1/conf/attribute-filter.xml)
@@ -1091,13 +1290,78 @@ What is new:
- the Status List url of the credential ends with `~did-web`
- the plugin gets a signing key list of its own, with the EC key of the OP only
-The changes per file, each with a link to the whole file after this step:
+Each file as it is after this step, the changes marked:
<details>
<summary>metadata/verifiable-credentials.json</summary>
```diff
- ...
+ {
+ "credential_configurations_supported": {
+ "GeantIncubatorDiploma_SDJWT": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_SDJWT",
+ "scope": "GeantIncubatorDiploma_SDJWT",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "credential_metadata": {
+ "display": [
+ {
+ "name": "Incubator Diploma",
+ "locale": "en",
+ "description": "Diploma issued by the Trust and Identity Incubator"
+ }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_W3C": {
+ "format": "vc+sd-jwt",
+ "scope": "GeantIncubatorDiploma_W3C",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "credential_definition": {
+ "@context": [
+ "https://www.w3.org/ns/credentials/v2",
+ "https://issuer.example.org/credentials/GeantIncubatorDiploma_W3C"
+ ],
+ "type": [
+ "VerifiableCredential",
+ "GeantIncubatorDiploma_W3C"
+ ]
+ },
+ "credential_metadata": {
+ "display": [
+ {
+ "name": "Incubator Diploma, W3C",
+ "locale": "en",
+ "description": "Diploma issued by the Trust and Identity Incubator"
+ }
+ ],
+ "claims": [
+ { "path": ["credentialSubject","diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["credentialSubject","mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["credentialSubject","eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["credentialSubject","givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["credentialSubject","familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["credentialSubject","affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
]
}
+ },
@@ -1105,10 +1369,11 @@ The changes per file, each with a link to the whole file after this step:
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_DIDWEB",
+ "scope": "GeantIncubatorDiploma_DIDWEB",
-+ "cryptographic_binding_methods_supported": ["did:jwk"],
++ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
++ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
-+ "proof_signing_alg_values_supported": ["ES256"]
++ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "_issuance_configuration": {
@@ -1129,6 +1394,7 @@ The changes per file, each with a link to the whole file after this step:
+ }
}
}
+ }
```
Full file: [metadata/verifiable-credentials.json](docs/example/step-2/metadata/verifiable-credentials.json)
@@ -1143,13 +1409,96 @@ and state it per credential.
<summary>conf/relying-party.xml</summary>
```diff
- ...
+ <?xml version="1.0" encoding="UTF-8"?>
+ <beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ <!-- The wallet reads the Credential Issuer metadata -->
+ <ref bean="OpenID.VCI.IssuerMetadata" />
+ <!-- The wallet finds the token endpoint through this one -->
+ <ref bean="OAuth.AuthorizationServer" />
+ <!-- The wallet asks for the nonce its key proof has to carry -->
+ <ref bean="OpenID.VCI.Nonce" />
+ <!-- A verifier reads the Status List -->
+ <ref bean="OAuth.StatusList" />
+ <!-- Of the OP plugin. Publishes the keys of the OP as a keyset -->
+ <ref bean="OIDC.Keyset" />
+ <!-- Of the OP plugin. Serves /.well-known/openid-configuration -->
+ <ref bean="OIDC.Configuration" />
<!-- Of the OP plugin. Needed for the audience values of the wallet -->
<ref bean="OAUTH2.TokenAudience" />
+ <!-- A verifier resolves the did:web identifier from this -->
+ <ref bean="DID.Document" />
</list>
</property>
+ </bean>
+
+ <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ </list>
+ </property>
+ </bean>
+
+ <util:list id="shibboleth.RelyingPartyOverrides">
+
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OpenID.VCI.CredentialOffer"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ <bean parent="OAuth.StatusList.Revoke"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ <bean parent="OAuth.StatusList.Assignments"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ </list>
+ </property>
+ </bean>
+
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller/wallet">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OpenID.VCI.Token"
+ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
+ p:tokenEndpointAuthMethods="#{{'none'}}" />
+ <bean parent="OpenID.VCI.Credentials" />
+ </list>
+ </property>
+ </bean>
+
+ <bean parent="RelyingPartyByName"
+ c:relyingPartyIds="#{{'id.animo.paradym'}}">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OIDC.SSO"
+ p:authorizationCodeClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
+ p:forcePKCE="true"
+ p:requirePushedAuthorizationRequest="true" />
+ <bean parent="OpenID.VCI.Token"
+ p:tokenEndpointAuthMethods="#{{'none'}}"
+ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy" />
+ <bean parent="OpenID.VCI.Credentials" />
+ <bean parent="OAUTH2.PAR" p:tokenEndpointAuthMethods="#{{'none'}}"
+ p:requestUriClaimsSetManipulationStrategy-ref="openidvci.PushedAuthorizationDPoPJktManipulationStrategy" />
+ </list>
+ </property>
+ </bean>
+
+ </util:list>
+
+ </beans>
```
Full file: [conf/relying-party.xml](docs/example/step-2/conf/relying-party.xml)
@@ -1160,7 +1509,43 @@ Full file: [conf/relying-party.xml](docs/example/step-2/conf/relying-party.xml)
<summary>etc/jetty-rewrite-rules.xml</summary>
```diff
- ...
+ <?xml version="1.0"?>
+ <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
+ <Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
+ <!-- Credential Issuer metadata -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/openid-credential-issuer</Set>
+ <Set name="replacement">/idp/profile/openid/vci/issuer-metadata</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- Authorization server metadata -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/oauth-authorization-server</Set>
+ <Set name="replacement">/idp/profile/oauth/authorization-server</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- OP metadata, of the OP plugin -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/openid-configuration</Set>
+ <Set name="replacement">/idp/profile/oidc/configuration</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- The JSON-LD context of the vc+sd-jwt credential is a static file of Jetty -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/credentials/GeantIncubatorDiploma_W3C</Set>
+ <Set name="replacement">/credentials/GeantIncubatorDiploma_W3C.json</Set>
+ </New>
</Arg>
</Call>
+ <!-- The did:web document -->
@@ -1174,6 +1559,15 @@ Full file: [conf/relying-party.xml](docs/example/step-2/conf/relying-party.xml)
+ </Call>
<!-- Wallets running in a browser need this -->
<Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
+ <Set name="pattern">/*</Set>
+ <Set name="headerName">Access-Control-Allow-Origin</Set>
+ <Set name="headerValue">*</Set>
+ </New>
+ </Arg>
+ </Call>
+ </Configure>
```
Full file: [etc/jetty-rewrite-rules.xml](docs/example/step-2/etc/jetty-rewrite-rules.xml)
@@ -1184,13 +1578,36 @@ Full file: [etc/jetty-rewrite-rules.xml](docs/example/step-2/etc/jetty-rewrite-r
<summary>metadata/oidc-client.json</summary>
```diff
- ...
+ [
+ {
+ "client_id": "offer-caller",
+ "client_name": "Credential offer caller",
+ "client_secret": "CHANGE-ME"
+ },
+ {
+ "client_id": "offer-caller/wallet",
+ "client_name": "Wallets redeeming a pre-authorized code minted by offer-caller",
+ "token_endpoint_auth_method": "none",
+ "grant_types": ["urn:ietf:params:oauth:grant-type:pre-authorized_code"]
+ },
+ {
+ "client_id": "id.animo.paradym",
"client_name": "Paradym Wallet",
"redirect_uris": ["https://paradym.id/invitation/redirect"],
- "scope": "openid GeantIncubatorDiploma_SDJWT GeantIncubatorDiploma_W3C",
+ "scope": "openid GeantIncubatorDiploma_SDJWT GeantIncubatorDiploma_W3C GeantIncubatorDiploma_DIDWEB",
"audience": [
"credentials",
+ "urn:shibboleth.oidc.op.resource:https://issuer.example.org"
+ ],
+ "token_endpoint_auth_method": "none",
+ "response_types": ["code"],
+ "grant_types": [
+ "authorization_code",
+ "urn:ietf:params:oauth:grant-type:pre-authorized_code"
+ ]
+ }
+ ]
```
Full file: [metadata/oidc-client.json](docs/example/step-2/metadata/oidc-client.json)
@@ -1201,7 +1618,35 @@ Full file: [metadata/oidc-client.json](docs/example/step-2/metadata/oidc-client.
<summary>static/oauth-authorization-server.json</summary>
```diff
- ...
+ {
+ "issuer":"$issuer",
+ "authorization_endpoint":"$baseUrl/idp/profile/oidc/authorize",
+ "pushed_authorization_request_endpoint":"$baseUrl/idp/profile/oauth2/pushed-authorization",
+ "require_pushed_authorization_requests":true,
+ "token_endpoint":"$baseUrl/idp/profile/openid/vci/token",
+ "jwks_uri":"$baseUrl/idp/profile/oidc/keyset",
+ "token_endpoint_auth_methods_supported":[
+ "none"
+ ],
+ "response_types_supported":[
+ "code"
+ ],
+ "grant_types_supported":[
+ "authorization_code",
+ "urn:ietf:params:oauth:grant-type:pre-authorized_code"
+ ],
+ "code_challenge_methods_supported":[
+ "S256"
+ ],
+ "dpop_signing_alg_values_supported":[
+ "ES256",
+ "ES384",
+ "ES512",
+ "PS256",
+ "PS384",
+ "PS512"
+ ],
+ "scopes_supported":[
"openid",
"GeantIncubatorDiploma_SDJWT",
- "GeantIncubatorDiploma_W3C"
@@ -1209,6 +1654,9 @@ Full file: [metadata/oidc-client.json](docs/example/step-2/metadata/oidc-client.
+ "GeantIncubatorDiploma_DIDWEB"
],
"authorization_details_types_supported":[
+ "openid_credential"
+ ]
+ }
```
Full file: [static/oauth-authorization-server.json](docs/example/step-2/static/oauth-authorization-server.json)
@@ -1326,13 +1774,106 @@ What is new:
- the credential header `kid` is the plain name of the key, as in the keyset of the OP
- the Status List url of the credential ends with `~url`
-The changes per file, each with a link to the whole file after this step:
+Each file as it is after this step, the changes marked:
<details>
<summary>metadata/verifiable-credentials.json</summary>
```diff
- ...
+ {
+ "credential_configurations_supported": {
+ "GeantIncubatorDiploma_SDJWT": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_SDJWT",
+ "scope": "GeantIncubatorDiploma_SDJWT",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "credential_metadata": {
+ "display": [
+ {
+ "name": "Incubator Diploma",
+ "locale": "en",
+ "description": "Diploma issued by the Trust and Identity Incubator"
+ }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_W3C": {
+ "format": "vc+sd-jwt",
+ "scope": "GeantIncubatorDiploma_W3C",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "credential_definition": {
+ "@context": [
+ "https://www.w3.org/ns/credentials/v2",
+ "https://issuer.example.org/credentials/GeantIncubatorDiploma_W3C"
+ ],
+ "type": [
+ "VerifiableCredential",
+ "GeantIncubatorDiploma_W3C"
+ ]
+ },
+ "credential_metadata": {
+ "display": [
+ {
+ "name": "Incubator Diploma, W3C",
+ "locale": "en",
+ "description": "Diploma issued by the Trust and Identity Incubator"
+ }
+ ],
+ "claims": [
+ { "path": ["credentialSubject","diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["credentialSubject","mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["credentialSubject","eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["credentialSubject","givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["credentialSubject","familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["credentialSubject","affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_DIDWEB": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_DIDWEB",
+ "scope": "GeantIncubatorDiploma_DIDWEB",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "_issuance_configuration": {
+ "issuer": "did:web"
+ },
+ "credential_metadata": {
+ "display": [
+ { "name": "Incubator Diploma, did:web", "locale": "en" }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
]
}
+ },
@@ -1340,10 +1881,11 @@ The changes per file, each with a link to the whole file after this step:
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_URL",
+ "scope": "GeantIncubatorDiploma_URL",
-+ "cryptographic_binding_methods_supported": ["did:jwk"],
++ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
++ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
-+ "proof_signing_alg_values_supported": ["ES256"]
++ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "_issuance_configuration": {
@@ -1364,6 +1906,7 @@ The changes per file, each with a link to the whole file after this step:
+ }
}
}
+ }
```
Full file: [metadata/verifiable-credentials.json](docs/example/step-3/metadata/verifiable-credentials.json)
@@ -1376,13 +1919,98 @@ Full file: [metadata/verifiable-credentials.json](docs/example/step-3/metadata/v
<summary>conf/relying-party.xml</summary>
```diff
- ...
+ <?xml version="1.0" encoding="UTF-8"?>
+ <beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ <!-- The wallet reads the Credential Issuer metadata -->
+ <ref bean="OpenID.VCI.IssuerMetadata" />
+ <!-- The wallet finds the token endpoint through this one -->
+ <ref bean="OAuth.AuthorizationServer" />
+ <!-- The wallet asks for the nonce its key proof has to carry -->
+ <ref bean="OpenID.VCI.Nonce" />
+ <!-- A verifier reads the Status List -->
+ <ref bean="OAuth.StatusList" />
+ <!-- Of the OP plugin. Publishes the keys of the OP as a keyset -->
+ <ref bean="OIDC.Keyset" />
+ <!-- Of the OP plugin. Serves /.well-known/openid-configuration -->
+ <ref bean="OIDC.Configuration" />
+ <!-- Of the OP plugin. Needed for the audience values of the wallet -->
+ <ref bean="OAUTH2.TokenAudience" />
<!-- A verifier resolves the did:web identifier from this -->
<ref bean="DID.Document" />
+ <!-- A verifier finds the key of a url issuer through this -->
+ <ref bean="OAuth.JWTVCIssuer" />
</list>
</property>
+ </bean>
+
+ <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ </list>
+ </property>
+ </bean>
+
+ <util:list id="shibboleth.RelyingPartyOverrides">
+
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OpenID.VCI.CredentialOffer"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ <bean parent="OAuth.StatusList.Revoke"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ <bean parent="OAuth.StatusList.Assignments"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ </list>
+ </property>
+ </bean>
+
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller/wallet">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OpenID.VCI.Token"
+ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
+ p:tokenEndpointAuthMethods="#{{'none'}}" />
+ <bean parent="OpenID.VCI.Credentials" />
+ </list>
+ </property>
+ </bean>
+
+ <bean parent="RelyingPartyByName"
+ c:relyingPartyIds="#{{'id.animo.paradym'}}">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OIDC.SSO"
+ p:authorizationCodeClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
+ p:forcePKCE="true"
+ p:requirePushedAuthorizationRequest="true" />
+ <bean parent="OpenID.VCI.Token"
+ p:tokenEndpointAuthMethods="#{{'none'}}"
+ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy" />
+ <bean parent="OpenID.VCI.Credentials" />
+ <bean parent="OAUTH2.PAR" p:tokenEndpointAuthMethods="#{{'none'}}"
+ p:requestUriClaimsSetManipulationStrategy-ref="openidvci.PushedAuthorizationDPoPJktManipulationStrategy" />
+ </list>
+ </property>
+ </bean>
+
+ </util:list>
+
+ </beans>
```
Full file: [conf/relying-party.xml](docs/example/step-3/conf/relying-party.xml)
@@ -1393,7 +2021,52 @@ Full file: [conf/relying-party.xml](docs/example/step-3/conf/relying-party.xml)
<summary>etc/jetty-rewrite-rules.xml</summary>
```diff
- ...
+ <?xml version="1.0"?>
+ <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
+ <Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
+ <!-- Credential Issuer metadata -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/openid-credential-issuer</Set>
+ <Set name="replacement">/idp/profile/openid/vci/issuer-metadata</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- Authorization server metadata -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/oauth-authorization-server</Set>
+ <Set name="replacement">/idp/profile/oauth/authorization-server</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- OP metadata, of the OP plugin -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/openid-configuration</Set>
+ <Set name="replacement">/idp/profile/oidc/configuration</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- The JSON-LD context of the vc+sd-jwt credential is a static file of Jetty -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/credentials/GeantIncubatorDiploma_W3C</Set>
+ <Set name="replacement">/credentials/GeantIncubatorDiploma_W3C.json</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- The did:web document -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/did.json</Set>
+ <Set name="replacement">/idp/profile/did/document</Set>
+ </New>
</Arg>
</Call>
+ <!-- JWT VC issuer metadata -->
@@ -1407,6 +2080,15 @@ Full file: [conf/relying-party.xml](docs/example/step-3/conf/relying-party.xml)
+ </Call>
<!-- Wallets running in a browser need this -->
<Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
+ <Set name="pattern">/*</Set>
+ <Set name="headerName">Access-Control-Allow-Origin</Set>
+ <Set name="headerValue">*</Set>
+ </New>
+ </Arg>
+ </Call>
+ </Configure>
```
Full file: [etc/jetty-rewrite-rules.xml](docs/example/step-3/etc/jetty-rewrite-rules.xml)
@@ -1417,15 +2099,38 @@ Full file: [etc/jetty-rewrite-rules.xml](docs/example/step-3/etc/jetty-rewrite-r
<summary>metadata/oidc-client.json</summary>
```diff
- ...
+ [
+ {
+ "client_id": "offer-caller",
+ "client_name": "Credential offer caller",
+ "client_secret": "CHANGE-ME"
+ },
+ {
+ "client_id": "offer-caller/wallet",
+ "client_name": "Wallets redeeming a pre-authorized code minted by offer-caller",
+ "token_endpoint_auth_method": "none",
+ "grant_types": ["urn:ietf:params:oauth:grant-type:pre-authorized_code"]
+ },
+ {
+ "client_id": "id.animo.paradym",
"client_name": "Paradym Wallet",
"redirect_uris": ["https://paradym.id/invitation/redirect"],
- "scope": "openid GeantIncubatorDiploma_SDJWT GeantIncubatorDiploma_W3C GeantIncubatorDiploma_DIDWEB",
+ "scope": "openid GeantIncubatorDiploma_SDJWT GeantIncubatorDiploma_W3C GeantIncubatorDiploma_DIDWEB GeantIncubatorDiploma_URL",
"audience": [
"credentials",
-```
-
+ "urn:shibboleth.oidc.op.resource:https://issuer.example.org"
+ ],
+ "token_endpoint_auth_method": "none",
+ "response_types": ["code"],
+ "grant_types": [
+ "authorization_code",
+ "urn:ietf:params:oauth:grant-type:pre-authorized_code"
+ ]
+ }
+ ]
+```
+
Full file: [metadata/oidc-client.json](docs/example/step-3/metadata/oidc-client.json)
</details>
@@ -1434,7 +2139,36 @@ Full file: [metadata/oidc-client.json](docs/example/step-3/metadata/oidc-client.
<summary>static/oauth-authorization-server.json</summary>
```diff
- ...
+ {
+ "issuer":"$issuer",
+ "authorization_endpoint":"$baseUrl/idp/profile/oidc/authorize",
+ "pushed_authorization_request_endpoint":"$baseUrl/idp/profile/oauth2/pushed-authorization",
+ "require_pushed_authorization_requests":true,
+ "token_endpoint":"$baseUrl/idp/profile/openid/vci/token",
+ "jwks_uri":"$baseUrl/idp/profile/oidc/keyset",
+ "token_endpoint_auth_methods_supported":[
+ "none"
+ ],
+ "response_types_supported":[
+ "code"
+ ],
+ "grant_types_supported":[
+ "authorization_code",
+ "urn:ietf:params:oauth:grant-type:pre-authorized_code"
+ ],
+ "code_challenge_methods_supported":[
+ "S256"
+ ],
+ "dpop_signing_alg_values_supported":[
+ "ES256",
+ "ES384",
+ "ES512",
+ "PS256",
+ "PS384",
+ "PS512"
+ ],
+ "scopes_supported":[
+ "openid",
"GeantIncubatorDiploma_SDJWT",
"GeantIncubatorDiploma_W3C",
- "GeantIncubatorDiploma_DIDWEB"
@@ -1442,6 +2176,9 @@ Full file: [metadata/oidc-client.json](docs/example/step-3/metadata/oidc-client.
+ "GeantIncubatorDiploma_URL"
],
"authorization_details_types_supported":[
+ "openid_credential"
+ ]
+ }
```
Full file: [static/oauth-authorization-server.json](docs/example/step-3/static/oauth-authorization-server.json)
@@ -1496,23 +2233,91 @@ Once the import is there every credential states the Entity Identifier, unless i
<summary>metadata/verifiable-credentials.json</summary>
```diff
- ...
+ {
+ "credential_configurations_supported": {
+ "GeantIncubatorDiploma_SDJWT": {
+ "format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_SDJWT",
"scope": "GeantIncubatorDiploma_SDJWT",
+ "_issuance_configuration": {
+ "oidfed": false
+ },
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
- ...
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "credential_metadata": {
+ "display": [
+ {
+ "name": "Incubator Diploma",
+ "locale": "en",
+ "description": "Diploma issued by the Trust and Identity Incubator"
+ }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_W3C": {
"format": "vc+sd-jwt",
"scope": "GeantIncubatorDiploma_W3C",
+ "_issuance_configuration": {
+ "oidfed": false
+ },
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
- ...
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "credential_definition": {
+ "@context": [
+ "https://www.w3.org/ns/credentials/v2",
+ "https://issuer.example.org/credentials/GeantIncubatorDiploma_W3C"
+ ],
+ "type": [
+ "VerifiableCredential",
+ "GeantIncubatorDiploma_W3C"
+ ]
+ },
+ "credential_metadata": {
+ "display": [
+ {
+ "name": "Incubator Diploma, W3C",
+ "locale": "en",
+ "description": "Diploma issued by the Trust and Identity Incubator"
+ }
+ ],
+ "claims": [
+ { "path": ["credentialSubject","diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["credentialSubject","mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["credentialSubject","eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["credentialSubject","givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["credentialSubject","familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["credentialSubject","affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_DIDWEB": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_DIDWEB",
+ "scope": "GeantIncubatorDiploma_DIDWEB",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
},
"_issuance_configuration": {
- "issuer": "did:web"
@@ -1520,6 +2325,49 @@ Once the import is there every credential states the Entity Identifier, unless i
+ "oidfed": false
},
"credential_metadata": {
+ "display": [
+ { "name": "Incubator Diploma, did:web", "locale": "en" }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_URL": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_URL",
+ "scope": "GeantIncubatorDiploma_URL",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "_issuance_configuration": {
+ "issuer": "url"
+ },
+ "credential_metadata": {
+ "display": [
+ { "name": "Incubator Diploma, url", "locale": "en" }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ }
+ }
+ }
```
Full file: [metadata/verifiable-credentials.json](docs/example/step-4/metadata/verifiable-credentials.json)
@@ -1533,13 +2381,100 @@ Full file: [metadata/verifiable-credentials.json](docs/example/step-4/metadata/v
<summary>conf/relying-party.xml</summary>
```diff
- ...
+ <?xml version="1.0" encoding="UTF-8"?>
+ <beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ <!-- The wallet reads the Credential Issuer metadata -->
+ <ref bean="OpenID.VCI.IssuerMetadata" />
+ <!-- The wallet finds the token endpoint through this one -->
+ <ref bean="OAuth.AuthorizationServer" />
+ <!-- The wallet asks for the nonce its key proof has to carry -->
+ <ref bean="OpenID.VCI.Nonce" />
+ <!-- A verifier reads the Status List -->
+ <ref bean="OAuth.StatusList" />
+ <!-- Of the OP plugin. Publishes the keys of the OP as a keyset -->
+ <ref bean="OIDC.Keyset" />
+ <!-- Of the OP plugin. Serves /.well-known/openid-configuration -->
+ <ref bean="OIDC.Configuration" />
+ <!-- Of the OP plugin. Needed for the audience values of the wallet -->
+ <ref bean="OAUTH2.TokenAudience" />
+ <!-- A verifier resolves the did:web identifier from this -->
+ <ref bean="DID.Document" />
<!-- A verifier finds the key of a url issuer through this -->
<ref bean="OAuth.JWTVCIssuer" />
+ <!-- Of the federation plugin. Serves the Entity Configuration -->
+ <ref bean="OIDFED.Configuration" />
</list>
</property>
+ </bean>
+
+ <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ </list>
+ </property>
+ </bean>
+
+ <util:list id="shibboleth.RelyingPartyOverrides">
+
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OpenID.VCI.CredentialOffer"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ <bean parent="OAuth.StatusList.Revoke"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ <bean parent="OAuth.StatusList.Assignments"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ </list>
+ </property>
+ </bean>
+
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller/wallet">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OpenID.VCI.Token"
+ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
+ p:tokenEndpointAuthMethods="#{{'none'}}" />
+ <bean parent="OpenID.VCI.Credentials" />
+ </list>
+ </property>
+ </bean>
+
+ <bean parent="RelyingPartyByName"
+ c:relyingPartyIds="#{{'id.animo.paradym'}}">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OIDC.SSO"
+ p:authorizationCodeClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
+ p:forcePKCE="true"
+ p:requirePushedAuthorizationRequest="true" />
+ <bean parent="OpenID.VCI.Token"
+ p:tokenEndpointAuthMethods="#{{'none'}}"
+ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy" />
+ <bean parent="OpenID.VCI.Credentials" />
+ <bean parent="OAUTH2.PAR" p:tokenEndpointAuthMethods="#{{'none'}}"
+ p:requestUriClaimsSetManipulationStrategy-ref="openidvci.PushedAuthorizationDPoPJktManipulationStrategy" />
+ </list>
+ </property>
+ </bean>
+
+ </util:list>
+
+ </beans>
```
Full file: [conf/relying-party.xml](docs/example/step-4/conf/relying-party.xml)
@@ -1550,7 +2485,61 @@ Full file: [conf/relying-party.xml](docs/example/step-4/conf/relying-party.xml)
<summary>etc/jetty-rewrite-rules.xml</summary>
```diff
- ...
+ <?xml version="1.0"?>
+ <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
+ <Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
+ <!-- Credential Issuer metadata -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/openid-credential-issuer</Set>
+ <Set name="replacement">/idp/profile/openid/vci/issuer-metadata</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- Authorization server metadata -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/oauth-authorization-server</Set>
+ <Set name="replacement">/idp/profile/oauth/authorization-server</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- OP metadata, of the OP plugin -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/openid-configuration</Set>
+ <Set name="replacement">/idp/profile/oidc/configuration</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- The JSON-LD context of the vc+sd-jwt credential is a static file of Jetty -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/credentials/GeantIncubatorDiploma_W3C</Set>
+ <Set name="replacement">/credentials/GeantIncubatorDiploma_W3C.json</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- The did:web document -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/did.json</Set>
+ <Set name="replacement">/idp/profile/did/document</Set>
+ </New>
+ </Arg>
+ </Call>
+ <!-- JWT VC issuer metadata -->
+ <Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
+ <Set name="pattern">/.well-known/jwt-vc-issuer</Set>
+ <Set name="replacement">/idp/profile/oauth/jwt-vc-issuer</Set>
+ </New>
</Arg>
</Call>
+ <!-- Entity Configuration, of the federation plugin -->
@@ -1564,6 +2553,15 @@ Full file: [conf/relying-party.xml](docs/example/step-4/conf/relying-party.xml)
+ </Call>
<!-- Wallets running in a browser need this -->
<Call name="addRule">
+ <Arg>
+ <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
+ <Set name="pattern">/*</Set>
+ <Set name="headerName">Access-Control-Allow-Origin</Set>
+ <Set name="headerValue">*</Set>
+ </New>
+ </Arg>
+ </Call>
+ </Configure>
```
Full file: [etc/jetty-rewrite-rules.xml](docs/example/step-4/etc/jetty-rewrite-rules.xml)
@@ -1631,7 +2629,17 @@ document:
<summary>conf/openid-vci-credentials.xml</summary>
```diff
- ...
+ <?xml version="1.0" encoding="UTF-8"?>
+ <beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="openidvci.OPESSigningCredential" parent="shibboleth.JWKCredential"
p:resource="%{idp.signing.oidc.es.key}" />
+ <bean id="openidvci.X509ESSigningCredential" parent="shibboleth.BasicX509CredentialFactoryBean"
@@ -1689,48 +2697,176 @@ rollover, see [Step 6](#step-6-rolling-the-signing-key).
attestation required:
<details>
-<summary>Example snippet of metadata/verifiable-credentials.json</summary>
+<summary>metadata/verifiable-credentials.json</summary>
-```json
-{
- "credential_configurations_supported": {
- "GeantIncubatorDiploma_SDJWT": { "...": "..." },
- "GeantIncubatorDiploma_W3C": { "...": "..." },
- ...
- "GeantIncubatorDiploma_HAIP": {
- "format": "dc+sd-jwt",
- "vct": "GeantIncubatorDiploma_HAIP",
- "scope": "GeantIncubatorDiploma_HAIP",
- "cryptographic_binding_methods_supported": ["jwk"],
- "proof_types_supported": {
- "jwt": {
- "proof_signing_alg_values_supported": ["ES256"],
- "key_attestations_required": {
- "key_storage": ["iso_18045_moderate"],
- "user_authentication": ["iso_18045_moderate"]
- }
- }
- },
- "_issuance_configuration": {
- "issuer": "url",
- "oidfed": false
- },
- "credential_metadata": {
- "display": [
- { "name": "Incubator Diploma, HAIP", "locale": "en" }
- ],
- "claims": [
- { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
- { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
- { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
- { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
- { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
- { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
- ]
- }
- }
- }
-}
+```diff
+ {
+ "credential_configurations_supported": {
+ "GeantIncubatorDiploma_SDJWT": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_SDJWT",
+ "scope": "GeantIncubatorDiploma_SDJWT",
+ "_issuance_configuration": {
+ "oidfed": false
+ },
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "credential_metadata": {
+ "display": [
+ {
+ "name": "Incubator Diploma",
+ "locale": "en",
+ "description": "Diploma issued by the Trust and Identity Incubator"
+ }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_W3C": {
+ "format": "vc+sd-jwt",
+ "scope": "GeantIncubatorDiploma_W3C",
+ "_issuance_configuration": {
+ "oidfed": false
+ },
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "credential_definition": {
+ "@context": [
+ "https://www.w3.org/ns/credentials/v2",
+ "https://issuer.example.org/credentials/GeantIncubatorDiploma_W3C"
+ ],
+ "type": [
+ "VerifiableCredential",
+ "GeantIncubatorDiploma_W3C"
+ ]
+ },
+ "credential_metadata": {
+ "display": [
+ {
+ "name": "Incubator Diploma, W3C",
+ "locale": "en",
+ "description": "Diploma issued by the Trust and Identity Incubator"
+ }
+ ],
+ "claims": [
+ { "path": ["credentialSubject","diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["credentialSubject","mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["credentialSubject","eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["credentialSubject","givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["credentialSubject","familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["credentialSubject","affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_DIDWEB": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_DIDWEB",
+ "scope": "GeantIncubatorDiploma_DIDWEB",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "_issuance_configuration": {
+ "issuer": "did:web",
+ "oidfed": false
+ },
+ "credential_metadata": {
+ "display": [
+ { "name": "Incubator Diploma, did:web", "locale": "en" }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_URL": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_URL",
+ "scope": "GeantIncubatorDiploma_URL",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "_issuance_configuration": {
+ "issuer": "url"
+ },
+ "credential_metadata": {
+ "display": [
+ { "name": "Incubator Diploma, url", "locale": "en" }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
++ },
++ "GeantIncubatorDiploma_HAIP": {
++ "format": "dc+sd-jwt",
++ "vct": "GeantIncubatorDiploma_HAIP",
++ "scope": "GeantIncubatorDiploma_HAIP",
++ "cryptographic_binding_methods_supported": ["jwk"],
++ "credential_signing_alg_values_supported": ["ES256"],
++ "proof_types_supported": {
++ "jwt": {
++ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"],
++ "key_attestations_required": {
++ "key_storage": ["iso_18045_moderate"],
++ "user_authentication": ["iso_18045_moderate"]
++ }
++ }
++ },
++ "_issuance_configuration": {
++ "issuer": "url",
++ "oidfed": false
++ },
++ "credential_metadata": {
++ "display": [
++ { "name": "Incubator Diploma, HAIP", "locale": "en" }
++ ],
++ "claims": [
++ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
++ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
++ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
++ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
++ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
++ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
++ ]
++ }
+ }
+ }
+ }
```
Full file: [metadata/verifiable-credentials.json](docs/example/step-5/metadata/verifiable-credentials.json)
@@ -1752,49 +2888,211 @@ An mdoc carries the certificate chain of its signing key in the `x5chain` header
Issuer identifier is not used.
<details>
-<summary>Example snippet of metadata/verifiable-credentials.json</summary>
+<summary>metadata/verifiable-credentials.json</summary>
-```json
-{
- "credential_configurations_supported": {
- ...
- "GeantIncubatorDiploma_MDOC": {
- "format": "mso_mdoc",
- "doctype": "org.geant.incubator.diploma.1",
- "scope": "GeantIncubatorDiploma_MDOC",
- "cryptographic_binding_methods_supported": ["cose_key"],
- "credential_signing_alg_values_supported": [-7],
- "proof_types_supported": {
- "jwt": {
- "proof_signing_alg_values_supported": ["ES256"],
- "key_attestations_required": {
- "key_storage": ["iso_18045_moderate"],
- "user_authentication": ["iso_18045_moderate"]
- }
- }
- },
- "_issuance_configuration": {
- "issuer": "url",
- "lifetime": "P45D",
- "claim_types": [
- { "path": ["org.geant.incubator.1", "issue_date"], "type": "full-date" }
- ]
- },
- "credential_metadata": {
- "display": [
- { "name": "Incubator Diploma, mdoc", "locale": "en" }
- ],
- "claims": [
- { "path": ["org.geant.incubator.1", "diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
- { "path": ["org.geant.incubator.1", "issue_date"], "display": [{ "name": "Issued", "locale": "en" }] },
- { "path": ["org.geant.incubator.1", "mail"], "display": [{ "name": "Email", "locale": "en" }] },
- { "path": ["org.geant.incubator.1", "given_name"], "display": [{ "name": "Given names", "locale": "en" }] },
- { "path": ["org.geant.incubator.1", "family_name"], "display": [{ "name": "Family name", "locale": "en" }] }
- ]
- }
- }
- }
-}
+```diff
+ {
+ "credential_configurations_supported": {
+ "GeantIncubatorDiploma_SDJWT": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_SDJWT",
+ "scope": "GeantIncubatorDiploma_SDJWT",
+ "_issuance_configuration": {
+ "oidfed": false
+ },
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "credential_metadata": {
+ "display": [
+ {
+ "name": "Incubator Diploma",
+ "locale": "en",
+ "description": "Diploma issued by the Trust and Identity Incubator"
+ }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_W3C": {
+ "format": "vc+sd-jwt",
+ "scope": "GeantIncubatorDiploma_W3C",
+ "_issuance_configuration": {
+ "oidfed": false
+ },
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "credential_definition": {
+ "@context": [
+ "https://www.w3.org/ns/credentials/v2",
+ "https://issuer.example.org/credentials/GeantIncubatorDiploma_W3C"
+ ],
+ "type": [
+ "VerifiableCredential",
+ "GeantIncubatorDiploma_W3C"
+ ]
+ },
+ "credential_metadata": {
+ "display": [
+ {
+ "name": "Incubator Diploma, W3C",
+ "locale": "en",
+ "description": "Diploma issued by the Trust and Identity Incubator"
+ }
+ ],
+ "claims": [
+ { "path": ["credentialSubject","diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["credentialSubject","mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["credentialSubject","eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["credentialSubject","givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["credentialSubject","familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["credentialSubject","affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_DIDWEB": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_DIDWEB",
+ "scope": "GeantIncubatorDiploma_DIDWEB",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "_issuance_configuration": {
+ "issuer": "did:web",
+ "oidfed": false
+ },
+ "credential_metadata": {
+ "display": [
+ { "name": "Incubator Diploma, did:web", "locale": "en" }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_URL": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_URL",
+ "scope": "GeantIncubatorDiploma_URL",
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
+ }
+ },
+ "_issuance_configuration": {
+ "issuer": "url"
+ },
+ "credential_metadata": {
+ "display": [
+ { "name": "Incubator Diploma, url", "locale": "en" }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
+ },
+ "GeantIncubatorDiploma_HAIP": {
+ "format": "dc+sd-jwt",
+ "vct": "GeantIncubatorDiploma_HAIP",
+ "scope": "GeantIncubatorDiploma_HAIP",
+ "cryptographic_binding_methods_supported": ["jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
+ "proof_types_supported": {
+ "jwt": {
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"],
+ "key_attestations_required": {
+ "key_storage": ["iso_18045_moderate"],
+ "user_authentication": ["iso_18045_moderate"]
+ }
+ }
+ },
+ "_issuance_configuration": {
+ "issuer": "url",
+ "oidfed": false
+ },
+ "credential_metadata": {
+ "display": [
+ { "name": "Incubator Diploma, HAIP", "locale": "en" }
+ ],
+ "claims": [
+ { "path": ["diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
+ { "path": ["mail"], "display": [{ "name": "Email", "locale": "en" }] },
+ { "path": ["eppn"], "display": [{ "name": "Principal name", "locale": "en" }] },
+ { "path": ["givenName"], "display": [{ "name": "Given names", "locale": "en" }] },
+ { "path": ["familyName"], "display": [{ "name": "Family name", "locale": "en" }] },
+ { "path": ["affiliation"], "display": [{ "name": "Affiliation", "locale": "en" }] }
+ ]
+ }
++ },
++ "GeantIncubatorDiploma_MDOC": {
++ "format": "mso_mdoc",
++ "doctype": "org.geant.incubator.diploma.1",
++ "scope": "GeantIncubatorDiploma_MDOC",
++ "cryptographic_binding_methods_supported": ["cose_key"],
++ "credential_signing_alg_values_supported": [-7, -9],
++ "proof_types_supported": {
++ "jwt": {
++ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"],
++ "key_attestations_required": {
++ "key_storage": ["iso_18045_moderate"],
++ "user_authentication": ["iso_18045_moderate"]
++ }
++ }
++ },
++ "_issuance_configuration": {
++ "issuer": "url",
++ "lifetime": "P45D",
++ "claim_types": [
++ { "path": ["org.geant.incubator.1", "issue_date"], "type": "full-date" }
++ ]
++ },
++ "credential_metadata": {
++ "display": [
++ { "name": "Incubator Diploma, mdoc", "locale": "en" }
++ ],
++ "claims": [
++ { "path": ["org.geant.incubator.1", "diploma"], "display": [{ "name": "Diploma", "locale": "en" }] },
++ { "path": ["org.geant.incubator.1", "issue_date"], "display": [{ "name": "Issued", "locale": "en" }] },
++ { "path": ["org.geant.incubator.1", "mail"], "display": [{ "name": "Email", "locale": "en" }] },
++ { "path": ["org.geant.incubator.1", "given_name"], "display": [{ "name": "Given names", "locale": "en" }] },
++ { "path": ["org.geant.incubator.1", "family_name"], "display": [{ "name": "Family name", "locale": "en" }] }
++ ]
++ }
+ }
+ }
+ }
```
Full file: [metadata/verifiable-credentials.json](docs/example/step-5/metadata/verifiable-credentials.json)
@@ -1829,7 +3127,7 @@ for an mDL [ISO/IEC 18013-5](https://www.iso.org/standard/69084.html):
The paths differ from the SD-JWT VC credentials, so the content is an attribute of its own:
<details>
-<summary>Example snippet of conf/attribute-resolver.xml</summary>
+<summary>conf/attribute-resolver.xml</summary>
```xml
<AttributeDefinition id="GeantIncubatorDiplomaMdoc" xsi:type="ScriptedAttribute">
@@ -1860,7 +3158,18 @@ release it to the HAIP wallet in *conf/attribute-filter.xml*.
<summary>conf/attribute-filter.xml</summary>
```diff
- ...
+ <?xml version="1.0" encoding="UTF-8"?>
+ <AttributeFilterPolicyGroup id="ShibbolethFilterPolicy"
+ xmlns="urn:mace:shibboleth:2.0:afp"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd">
+
+ <AttributeFilterPolicy id="GeantIncubatorDiplomaToWallets">
+ <PolicyRequirementRule xsi:type="Requester"
+ value="id.animo.paradym" />
+ <AttributeRule attributeID="GeantIncubatorDiploma">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
</AttributeFilterPolicy>
+ <AttributeFilterPolicy id="GeantIncubatorDiplomaToHAIPWallets">
@@ -1936,7 +3245,31 @@ The client id is the `sub` of the Wallet Attestation of the wallet. In *metadata
<summary>metadata/oidc-client.json</summary>
```diff
- ...
+ [
+ {
+ "client_id": "offer-caller",
+ "client_name": "Credential offer caller",
+ "client_secret": "CHANGE-ME"
+ },
+ {
+ "client_id": "offer-caller/wallet",
+ "client_name": "Wallets redeeming a pre-authorized code minted by offer-caller",
+ "token_endpoint_auth_method": "none",
+ "grant_types": ["urn:ietf:params:oauth:grant-type:pre-authorized_code"]
+ },
+ {
+ "client_id": "id.animo.paradym",
+ "client_name": "Paradym Wallet",
+ "redirect_uris": ["https://paradym.id/invitation/redirect"],
+ "scope": "openid GeantIncubatorDiploma_SDJWT GeantIncubatorDiploma_W3C GeantIncubatorDiploma_DIDWEB GeantIncubatorDiploma_URL",
+ "audience": [
+ "credentials",
+ "urn:shibboleth.oidc.op.resource:https://issuer.example.org"
+ ],
+ "token_endpoint_auth_method": "none",
+ "response_types": ["code"],
+ "grant_types": [
+ "authorization_code",
"urn:ietf:params:oauth:grant-type:pre-authorized_code"
]
+ },
@@ -1966,7 +3299,95 @@ and both token and PAR endpoints take the Wallet Attestation:
<summary>conf/relying-party.xml</summary>
```diff
- ...
+ <?xml version="1.0" encoding="UTF-8"?>
+ <beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ <!-- The wallet reads the Credential Issuer metadata -->
+ <ref bean="OpenID.VCI.IssuerMetadata" />
+ <!-- The wallet finds the token endpoint through this one -->
+ <ref bean="OAuth.AuthorizationServer" />
+ <!-- The wallet asks for the nonce its key proof has to carry -->
+ <ref bean="OpenID.VCI.Nonce" />
+ <!-- A verifier reads the Status List -->
+ <ref bean="OAuth.StatusList" />
+ <!-- Of the OP plugin. Publishes the keys of the OP as a keyset -->
+ <ref bean="OIDC.Keyset" />
+ <!-- Of the OP plugin. Serves /.well-known/openid-configuration -->
+ <ref bean="OIDC.Configuration" />
+ <!-- Of the OP plugin. Needed for the audience values of the wallet -->
+ <ref bean="OAUTH2.TokenAudience" />
+ <!-- A verifier resolves the did:web identifier from this -->
+ <ref bean="DID.Document" />
+ <!-- A verifier finds the key of a url issuer through this -->
+ <ref bean="OAuth.JWTVCIssuer" />
+ <!-- Of the federation plugin. Serves the Entity Configuration -->
+ <ref bean="OIDFED.Configuration" />
+ </list>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ </list>
+ </property>
+ </bean>
+
+ <util:list id="shibboleth.RelyingPartyOverrides">
+
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OpenID.VCI.CredentialOffer"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ <bean parent="OAuth.StatusList.Revoke"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ <bean parent="OAuth.StatusList.Assignments"
+ p:tokenEndpointAuthMethods="#{{'client_secret_basic'}}" />
+ </list>
+ </property>
+ </bean>
+
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="offer-caller/wallet">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OpenID.VCI.Token"
+ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
+ p:tokenEndpointAuthMethods="#{{'none'}}" />
+ <bean parent="OpenID.VCI.Credentials" />
+ </list>
+ </property>
+ </bean>
+
+ <bean parent="RelyingPartyByName"
+ c:relyingPartyIds="#{{'id.animo.paradym'}}">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OIDC.SSO"
+ p:authorizationCodeClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy"
+ p:forcePKCE="true"
+ p:requirePushedAuthorizationRequest="true" />
+ <bean parent="OpenID.VCI.Token"
+ p:tokenEndpointAuthMethods="#{{'none'}}"
+ p:accessTokenClaimsSetManipulationStrategy-ref="openidvci.TokenManipulationStrategy" />
+ <bean parent="OpenID.VCI.Credentials" />
+ <bean parent="OAUTH2.PAR" p:tokenEndpointAuthMethods="#{{'none'}}"
+ p:requestUriClaimsSetManipulationStrategy-ref="openidvci.PushedAuthorizationDPoPJktManipulationStrategy" />
+ </list>
+ </property>
</bean>
+ <bean parent="RelyingPartyByName"
@@ -1989,6 +3410,7 @@ and both token and PAR endpoints take the Wallet Attestation:
+
</util:list>
+ </beans>
```
Full file: [conf/relying-party.xml](docs/example/step-5/conf/relying-party.xml)
@@ -2008,7 +3430,12 @@ Paradym and `attest_jwt_client_auth` for the HAIP wallet:
<summary>static/oauth-authorization-server.json</summary>
```diff
- ...
+ {
+ "issuer":"$issuer",
+ "authorization_endpoint":"$baseUrl/idp/profile/oidc/authorize",
+ "pushed_authorization_request_endpoint":"$baseUrl/idp/profile/oauth2/pushed-authorization",
+ "require_pushed_authorization_requests":true,
+ "token_endpoint":"$baseUrl/idp/profile/openid/vci/token",
"jwks_uri":"$baseUrl/idp/profile/oidc/keyset",
"token_endpoint_auth_methods_supported":[
- "none"
@@ -2024,7 +3451,25 @@ Paradym and `attest_jwt_client_auth` for the HAIP wallet:
+ "authorization_response_iss_parameter_supported":true,
"response_types_supported":[
"code"
- ...
+ ],
+ "grant_types_supported":[
+ "authorization_code",
+ "urn:ietf:params:oauth:grant-type:pre-authorized_code"
+ ],
+ "code_challenge_methods_supported":[
+ "S256"
+ ],
+ "dpop_signing_alg_values_supported":[
+ "ES256",
+ "ES384",
+ "ES512",
+ "PS256",
+ "PS384",
+ "PS512"
+ ],
+ "scopes_supported":[
+ "openid",
+ "GeantIncubatorDiploma_SDJWT",
"GeantIncubatorDiploma_W3C",
"GeantIncubatorDiploma_DIDWEB",
- "GeantIncubatorDiploma_URL"
@@ -2033,6 +3478,9 @@ Paradym and `attest_jwt_client_auth` for the HAIP wallet:
+ "GeantIncubatorDiploma_MDOC"
],
"authorization_details_types_supported":[
+ "openid_credential"
+ ]
+ }
```
Full file: [static/oauth-authorization-server.json](docs/example/step-5/static/oauth-authorization-server.json)
@@ -2167,10 +3615,11 @@ Master of Science in Computer Science and another in Mathematics gets two creden
"format": "dc+sd-jwt",
"vct": "UniversityDegree",
"scope": "UniversityDegree",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_metadata": {
diff --git a/docs/example/step-1/metadata/verifiable-credentials.json b/docs/example/step-1/metadata/verifiable-credentials.json
index f1df0c1..009ed64 100644
--- a/docs/example/step-1/metadata/verifiable-credentials.json
+++ b/docs/example/step-1/metadata/verifiable-credentials.json
@@ -4,10 +4,11 @@
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_SDJWT",
"scope": "GeantIncubatorDiploma_SDJWT",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_metadata": {
@@ -31,10 +32,11 @@
"GeantIncubatorDiploma_W3C": {
"format": "vc+sd-jwt",
"scope": "GeantIncubatorDiploma_W3C",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_definition": {
diff --git a/docs/example/step-2/metadata/verifiable-credentials.json b/docs/example/step-2/metadata/verifiable-credentials.json
index ab0a926..eae9cc8 100644
--- a/docs/example/step-2/metadata/verifiable-credentials.json
+++ b/docs/example/step-2/metadata/verifiable-credentials.json
@@ -4,10 +4,11 @@
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_SDJWT",
"scope": "GeantIncubatorDiploma_SDJWT",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_metadata": {
@@ -31,10 +32,11 @@
"GeantIncubatorDiploma_W3C": {
"format": "vc+sd-jwt",
"scope": "GeantIncubatorDiploma_W3C",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_definition": {
@@ -69,10 +71,11 @@
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_DIDWEB",
"scope": "GeantIncubatorDiploma_DIDWEB",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"_issuance_configuration": {
diff --git a/docs/example/step-3/metadata/verifiable-credentials.json b/docs/example/step-3/metadata/verifiable-credentials.json
index d76ae38..ddc2950 100644
--- a/docs/example/step-3/metadata/verifiable-credentials.json
+++ b/docs/example/step-3/metadata/verifiable-credentials.json
@@ -4,10 +4,11 @@
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_SDJWT",
"scope": "GeantIncubatorDiploma_SDJWT",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_metadata": {
@@ -31,10 +32,11 @@
"GeantIncubatorDiploma_W3C": {
"format": "vc+sd-jwt",
"scope": "GeantIncubatorDiploma_W3C",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_definition": {
@@ -69,10 +71,11 @@
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_DIDWEB",
"scope": "GeantIncubatorDiploma_DIDWEB",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"_issuance_configuration": {
@@ -96,10 +99,11 @@
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_URL",
"scope": "GeantIncubatorDiploma_URL",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"_issuance_configuration": {
diff --git a/docs/example/step-4/metadata/verifiable-credentials.json b/docs/example/step-4/metadata/verifiable-credentials.json
index b13d335..3811ba8 100644
--- a/docs/example/step-4/metadata/verifiable-credentials.json
+++ b/docs/example/step-4/metadata/verifiable-credentials.json
@@ -7,10 +7,11 @@
"_issuance_configuration": {
"oidfed": false
},
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_metadata": {
@@ -37,10 +38,11 @@
"_issuance_configuration": {
"oidfed": false
},
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_definition": {
@@ -75,10 +77,11 @@
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_DIDWEB",
"scope": "GeantIncubatorDiploma_DIDWEB",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"_issuance_configuration": {
@@ -103,10 +106,11 @@
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_URL",
"scope": "GeantIncubatorDiploma_URL",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"_issuance_configuration": {
diff --git a/docs/example/step-5/metadata/verifiable-credentials.json b/docs/example/step-5/metadata/verifiable-credentials.json
index 8fcfaf1..ef969b5 100644
--- a/docs/example/step-5/metadata/verifiable-credentials.json
+++ b/docs/example/step-5/metadata/verifiable-credentials.json
@@ -7,10 +7,11 @@
"_issuance_configuration": {
"oidfed": false
},
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_metadata": {
@@ -37,10 +38,11 @@
"_issuance_configuration": {
"oidfed": false
},
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"credential_definition": {
@@ -75,10 +77,11 @@
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_DIDWEB",
"scope": "GeantIncubatorDiploma_DIDWEB",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"_issuance_configuration": {
@@ -103,10 +106,11 @@
"format": "dc+sd-jwt",
"vct": "GeantIncubatorDiploma_URL",
"scope": "GeantIncubatorDiploma_URL",
- "cryptographic_binding_methods_supported": ["did:jwk"],
+ "cryptographic_binding_methods_supported": ["did:jwk", "jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"]
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"]
}
},
"_issuance_configuration": {
@@ -131,9 +135,10 @@
"vct": "GeantIncubatorDiploma_HAIP",
"scope": "GeantIncubatorDiploma_HAIP",
"cryptographic_binding_methods_supported": ["jwk"],
+ "credential_signing_alg_values_supported": ["ES256"],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"],
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"],
"key_attestations_required": {
"key_storage": ["iso_18045_moderate"],
"user_authentication": ["iso_18045_moderate"]
@@ -163,10 +168,10 @@
"doctype": "org.geant.incubator.diploma.1",
"scope": "GeantIncubatorDiploma_MDOC",
"cryptographic_binding_methods_supported": ["cose_key"],
- "credential_signing_alg_values_supported": [-7],
+ "credential_signing_alg_values_supported": [-7, -9],
"proof_types_supported": {
"jwt": {
- "proof_signing_alg_values_supported": ["ES256"],
+ "proof_signing_alg_values_supported": ["ES256", "ES384", "ES512"],
"key_attestations_required": {
"key_storage": ["iso_18045_moderate"],
"user_authentication": ["iso_18045_moderate"]
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list