-
Notifications
You must be signed in to change notification settings - Fork 2
Implement multiple credential issuance #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @Ogenbertrand - I checked your implementation and quickly realized it is essentially disconnected from the specification. Please take more time to immerse yourself into the new requirements at the credential endpoint and update your implementation accordingly.
services/src/main/java/org/keycloak/protocol/oid4vc/issuance/OID4VCIssuerEndpoint.java
Outdated
Show resolved
Hide resolved
services/src/main/java/org/keycloak/protocol/oid4vc/issuance/OID4VCIssuerEndpoint.java
Outdated
Show resolved
Hide resolved
services/src/main/java/org/keycloak/protocol/oid4vc/issuance/OID4VCIssuerEndpoint.java
Outdated
Show resolved
Hide resolved
services/src/main/java/org/keycloak/protocol/oid4vc/issuance/OID4VCIssuerEndpoint.java
Outdated
Show resolved
Hide resolved
services/src/main/java/org/keycloak/protocol/oid4vc/model/BatchCredentialRequest.java
Outdated
Show resolved
Hide resolved
services/src/main/java/org/keycloak/protocol/oid4vc/issuance/OID4VCIssuerEndpoint.java
Outdated
Show resolved
Hide resolved
Thanka for the comments @IngridPuppet, I'll review them and get back to you. |
Hello @IngridPuppet can u check this again please? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some comments. Please, could you check?
Reminder to myself: You'll still have to review the whole PR.
/** | ||
* Returns the credential format supported by the builder. | ||
* Returns the format supported by this builder. | ||
*/ | ||
String getSupportedFormat(); | ||
|
||
/** | ||
* Builds a verifiable credential of a specific format from the basis of | ||
* an internal representation of the credential. | ||
* | ||
* <p> | ||
* The credential is built incompletely, intended that it would be signed externally. | ||
* </p> | ||
* | ||
* @param verifiableCredential an internal representation of the credential | ||
* @param credentialBuildConfig additional configurations for building the credential | ||
* @return the built verifiable credential of the specific format, ready to be signed | ||
* Builds a credential body from a VerifiableCredential and configuration. | ||
*/ | ||
CredentialBody buildCredentialBody(VerifiableCredential verifiableCredential, CredentialBuildConfig credentialBuildConfig) | ||
throws CredentialBuilderException; | ||
|
||
/** | ||
* Builds a credential body with an optional proof for key binding, used for multiple credential issuance. | ||
*/ | ||
CredentialBody buildCredentialBody( | ||
VerifiableCredential verifiableCredential, | ||
CredentialBuildConfig credentialBuildConfig | ||
) throws CredentialBuilderException; | ||
default CredentialBody buildCredentialBody(VerifiableCredential verifiableCredential, CredentialBuildConfig credentialBuildConfig, Proof proof) | ||
throws CredentialBuilderException { | ||
// Default implementation for backward compatibility: ignore proof and call the original method | ||
return buildCredentialBody(verifiableCredential, credentialBuildConfig); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the goal of this conceptual change?
public JwtCredentialBody buildCredentialBody( | ||
VerifiableCredential verifiableCredential, | ||
CredentialBuildConfig credentialBuildConfig | ||
) throws CredentialBuilderException { | ||
return buildCredentialBody(verifiableCredential, credentialBuildConfig, null); | ||
} | ||
|
||
@Override | ||
public JwtCredentialBody buildCredentialBody( | ||
VerifiableCredential verifiableCredential, | ||
CredentialBuildConfig credentialBuildConfig, | ||
Proof proof | ||
) throws CredentialBuilderException { | ||
// Populate the issuer field of the VC | ||
verifiableCredential.setIssuer(URI.create(credentialIssuer)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You update the CredentialBuilder interface, inject a proof here, but do not anything with. You even add a comment:
// Key binding is handled by ProofValidator, which adds the JWK to the credential body
Could you communicate the rationale for these updates?
import org.keycloak.jose.jwk.JWK; | ||
import org.keycloak.protocol.oid4vc.issuance.VCIssuanceContext; | ||
import org.keycloak.protocol.oid4vc.issuance.VCIssuerException; | ||
import org.keycloak.protocol.oid4vc.model.Proof; | ||
import org.keycloak.provider.Provider; | ||
|
||
/** | ||
* Interface for validating proofs provided in credential requests. | ||
* | ||
* @author <a href="https://github.com/wistefan">Stefan Wiedemann</a> | ||
*/ | ||
public interface ProofValidator extends Provider { | ||
|
||
@Override | ||
default void close() { | ||
} | ||
|
||
/** | ||
* Validates a client-provided key binding proof. | ||
* | ||
* @param vcIssuanceContext the issuance context with credential request and config | ||
* @return the JWK to bind to the credential | ||
* Validates a proof in the issuance context and returns the JWK for key binding. | ||
*/ | ||
JWK validateProof(VCIssuanceContext vcIssuanceContext) throws VCIssuerException; | ||
|
||
/** | ||
* Validates a specific proof and returns the JWK for key binding, used for multiple credential issuance. | ||
*/ | ||
default JWK validateProof(VCIssuanceContext vcIssuanceContext, Proof proof) throws VCIssuerException { | ||
// Default implementation for backward compatibility: use the original method | ||
return validateProof(vcIssuanceContext); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A vcIssuanceContext already embeds a proof. What is the need for these changes?
* @author <a href="https://github.com/wistefan">Stefan Wiedemann</a> | ||
*/ | ||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
public class CredentialRequest { | ||
|
||
@JsonProperty("credential_specs") | ||
private List<CredentialSpec> credentialSpecs; | ||
|
||
// Backward compatibility fields for single credential requests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A Credential Request has a structure defined by the spec, carrying a vision of mutiple credential issuance that we must comply with. Please consider reading this section of the spec and update this structure accordingly: https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0-15.html#name-credential-request
I implemented the multiple credential insuance in kc, that's updating credential endpoint to understand the request of multiple credential instances. please review and leave your thoughts.