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
Support DID in generated Gaia-X Credentials #70
Comments
My first task will be to investigate DID, VCs and Gaia-X Compliance (defined by PRC Documnet in more detail and figure out, how these concepts relate to each other. I will document results of my investigations below. |
Here are the Key results of my investigations
A good starting point to play around with Gaia-X Credentials is Gaia-X Wizard offered by Gaia-X Lab. There is also a good tech theater, explaining the concepts behind Gaia-X on-boarding. |
Task 1: Implement DID generatorGaia-X Lab offers a DID generator. This generator supports did:web method specification only. There is also free python demo, how to generate DIDs. Additional python skeleton with respect to DID handling are published by Gaia-X Lab. I will have a closer look into these scripts... The first thing, we need is a public-private key pair and a x509 certificate (chain). According to Gaia-X Trust Framework, for development purpose let's encrypt is sufficent, in production, we need at least an eIDAS certificate or EV SSL certificate . I created a python script to generate did documents for a given DID. Files are stored in #88 and should be moved to its own repo. |
Task 2: Add cluster's and provider's DID to GX Credential GeneratorGaia-X uses DIDs to identity Participants (CSP) Service Offerings and Resources. Each CSP must have a DID and each SCS cluster offered as Service in Gaia-X needs a DID, too. These DIDs have to be placed in GX Credentials. SCS GX Credential Generator is configured by config file. I will place DIDs there. |
Task 3: Create Gaia-X compliant credential for CSP's and Cloud Service's propertiesGaia-X published an ontology containing several classes and attributes to describe CSP's and service's properties. Some of them are mandatory and not discoverable from Cloud. Furthermore, some properties must be provided in a temper.proof way as Verifiable Credential issued by a Gaia-X Clearing House. This is, e.g. the case for CSP's registration number. We have two options to handle these challenges
I go for option 1, first and limit data in configuration file to mandatory attributes of Legal Person (= GX Credential for CSP) and Service Offering. According to Trust Framework, these are:
Source code can be found in #89 ChallengesInconsistency of shapes in Gaia-X Clearing House and WG Service Characteristics GitLab I summarized my investigations in bug reports within the appropriate Gaia-X repositories:
Misleading/Inconsistent definition of Gaia-X Credential Gaia-X dictates to publish all properties of CSPs and services as Gaia-X Credential. Gaia-X Credentials "... are W3C Verifiable Credentials with claims expressed in RDF [Gaia-X Architecture Framework, section Conceptual Model The same document says in section "Operating Model", "Gaia-X Self-Descriptions ... refers to a self-signed set of claims. This is equivalent to a Verifiable Credential where the holder is the issuer. In general, the term “Gaia-X Self Description” is replaced by “Gaia-X Credential”" [Architecture Document - section Operating Model] Wheres the first definition says a Gaia-X Credential is a Verifiable Credential, the second limits this to a Verifiable Credential, where the holder is the same entity as the issuer. IMO, both definitions are incorrect, as a Gaia-X Credential is a Verifiable Presentation, as defined by W3C. Furthermore, W3C VC Spec does allow several viable proof mechanisms. However, Gaia-X does not mention, which proof they prefer or support, giving the impression all viable proof mechanisms are supported. But this is not he case. I summarizes my findings in an issue waiting for clarification. Non-conform usage of Verifiable Credentials There is an example on how to create compliance Gaia-X Credentials in python. The example sets JSONWebSignature2020 as proof mechanism and uses the python library jwcrypto to create proof object. Gaia-X hashes credential and uses this hash as payload for calculation of signature. However, jwcrypto calculates hash for payload as input for signature, hence hash of hash is calculated. I neither know, if this is intended nor the side effects of this behavior. I opened an issue to raise this question. Gaia-X uses a compact serialization as JWS, which is a string consisting of protected header, payload and signature. However, Gaia-X omit payload part. Instead of Verifying compact JWS fails |
Task 4: Put all credentials in a VP, sign it and retrieve Gaia-X Compliance Credential |
I looked into this and figured out how to verify the JWS retrieved by the Legal Registration Number request from the Notary. After receiving the response from the "https://registrationnumber.notary.lab.gaia-x.eu/v1/registrationNumberVC" API: lrn_response = requests.post(...)
lrn = lrn_response.json()
# Certificate used as public key to verify the JWS
verification_cert_url = "https://registry.lab.gaia-x.eu/main/x509CertificateChain.pem"
verify_credential(json.dumps(lrn), verification_cert_url) The import requests
import json
from jwcrypto import jwk, jws
# utils refers to https://gitlab.com/gaia-x/lab/workshops/gaia-x-101/-/blob/master/utils.py?ref_type=heads
from utils import sha256_normalized_vc, normalize
def verify_credential(credential_json_str, cert_url):
verifiable_credential = json.loads(credential_json_str)
# Retrieve the registry certificate which serves as the verification
# public key (JWK) for the JWS later
reg_cert_response = requests.get(cert_url)
if reg_cert_response.status_code != 200:
raise Exception(
f"Unable to retrieve verification certificate "
f"from: {cert_url}"
)
verification_cert_pem = reg_cert_response.text.encode('UTF-8')
verification_key = jwk.JWK.from_pem(verification_cert_pem)
# The proof object is part of the credential response, however
# it resembles JWS data applicable to the response without the
# proof object. Hence, we need to strip the proof object from
# the response.
proof = verifiable_credential.pop("proof")
# The remaining structure is the actual credential data that
# JWS was created for. The signature was applied to its
# normalized and hashed form, which we need to recreate here
# in order to verify the signature.
normalized_credential = normalize(verifiable_credential)
hashed_credential = sha256_normalized_vc(normalized_credential)
# Instantiate a JWS object based on the jws attribute of the
# proof object, which contains a base64 representation of the JWS.
received_jws_token = jws.JWS()
received_jws_token.deserialize(proof["jws"])
# Finally, use the verification key (Gaia X registry public cert)
# and the hashed credential (which is the JWS' detached payload)
# in conjunction with the JWS token to verify the credential.
# This method will throw an exception if verification fails.
received_jws_token.verify(
verification_key,
detached_payload=hashed_credential.hexdigest()
) |
I added comments to both issues12. I think neither is actually a mistake. I can see some ambiguity regarding the double hashing topic but I lean towards the opinion that it is correctly implemented. The omitted payload seems perfectly valid according to an appendix of the referenced RFC specifying this exact behavior. Footnotes |
GX Credential Generator generates one huge json-ld file with ALL information about SCS cluster, currently. In favor to flexibility and maintenance, each credential should be serialized in its own file and referenced by its DID in other credentials.
This issue contains two tasks:
The text was updated successfully, but these errors were encountered: