[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