...
This guide explains how to connect your Issuer to the Trust Infrastructure, including detailed instructions on configuring the setup with specific values provided for the interoperability lab.
Prerequisites
Before proceeding, ensure the following are in place:
- An understanding of your Trust Infrastructure's structure and the required credential types.
- Network access from the Issuer to the Trust Anchor (TA).
- HTTPS is properly set up for your Issuer and is externally accessible.
...
Key Configuration Points
Entity Configuration Information
The configuration endpoint publishes the Entity Configuration document, which provides the Issuer’s configuration details for participants in the Trust Infrastructure.
Define the Endpoint:
- The endpoint is defined under the following path: /
.well-known/openid-federation
- The endpoint is defined under the following path: /
Implementation:
- Ensure this endpoint serves the issuer’s Entity Configuration.
Example Entity Configuration: Here is an example of Entity Configuration that can be exposed at the endpoint:
Code Block language js collapse true { "sub": "https://my-issuer.example.com:8000", "metadata": { "federation_entity": { "organization_name": "The OP operator", "contacts": "operations@op.example.com" }, "oauth_authorization_server": { "jwks_uri": "https://my-issuer.example.com:8000/jwks/oauth_authorization_server", "token_endpoint_auth_methods_supported": [], "token_endpoint_auth_signing_alg_values_supported": [ "RS256", "RS384", "RS512", "ES256", "ES256K", "ES384", "ES512", "PS256", "PS384", "PS512", "HS256", "HS384", "HS512", "Ed25519", "Ed448", "EdDSA" ], "response_types_supported": [ "code" ], "response_modes_supported": [ "code" ], "acr_values_supported": [], "scopes_supported": [], "authorization_signing_alg_values_supported": [ "RS256", "RS384", "RS512", "ES256", "ES256K", "ES384", "ES512", "PS256", "PS384", "PS512", "HS256", "HS384", "HS512", "Ed25519", "Ed448", "EdDSA" ], "request_object_signing_alg_values_supported": [ "RS256", "RS384", "RS512", "ES256", "ES256K", "ES384", "ES512", "PS256", "PS384", "PS512", "HS256", "HS384", "HS512", "Ed25519", "Ed448", "EdDSA" ], "claims_parameter_supported": true, "request_parameter_supported": true, "request_object_encryption_alg_values_supported": [], "request_object_encryption_enc_values_supported": [], "code_challenge_methods_supported": [ "plain", "S256", "S384", "S512" ], "deny_unknown_scopes": false, "ui_locales_supported": [], "token_endpoint": "https://my-issuer.example.com:8000/token", "token_endpoint_auth_methods": [ "attest_jwt_client_auth" ], "authorization_endpoint": "https://my-issuer.example.com:8000/authorization", "authorization_endpoint_auth_methods": [ "pushed_authz" ], "pushed_authorization_request_endpoint": "https://my-issuer.example.com:8000/par", "pushed_authorization_request_endpoint_auth_methods": [ "attest_jwt_client_auth" ] }, "openid_credential_issuer": { "attribute_disclosure": { "": [ "given_name", "family_name", "name", "email", "nickname" ] }, "credential_configurations_supported": { "PDA1Credential": { "format": "vc+sd-jwt", "id": "eudiw.pda1.se", "cryptographic_binding_methods_supported": [ "jwk" ], "cryptographic_suites_supported": [ "RS256", "RS512", "ES256", "ES512" ], "display": { "name": "Swedish PDA1 Provider Example", "locale": "en-US" }, "vct": "PDA1Credential", "credential_definition": { "type": [ "PDA1Credential" ], "credentialSubject": { "family_name": { "display": [ { "locale": "en-US", "name": "Current Family Name" } ], "mandatory": true }, "given_name": { "display": [ { "locale": "en-US", "name": "Current First Name" } ], "mandatory": true }, "birth_date": { "display": [ { "locale": "en-US", "name": "Birth date" } ] } } } }, "EHICCredential": { "format": "vc+sd-jwt", "id": "eudiw.ehic.se", "cryptographic_binding_methods_supported": [ "jwk" ], "cryptographic_suites_supported": [ "RS256", "RS512", "ES256", "ES512" ], "display": { "name": "Swedish EHIC Provider Example", "locale": "en-US" }, "vct": "EHICCredential", "credential_definition": { "type": [ "EHICCredential" ], "credentialSubject": { "family_name": { "display": [ { "locale": "en-US", "name": "Current Family Name" } ], "mandatory": true }, "given_name": { "display": [ { "locale": "en-US", "name": "Current First Name" } ], "mandatory": true }, "birth_date": { "display": [ { "locale": "en-US", "name": "Birth date" } ] } } } } }, "jwks": { "keys": [ { "kty": "RSA", "use": "sig", "kid": "ODR1b1ZjUEpsRzVhVHBSaWxLR1hxQ2x3WTU2ZVFDcnVsMXBmdEF5WUM4UQ", "e": "AQAB", "n": "vqLXJgOHZn7YFqL78Kth6vP..." }, { "kty": "EC", "use": "sig", "kid": "YzIwZjJEaFJxU0NOLXJ5MS1mSXgyLUp5RWNZb3I4M1lRMDVhQWxMUjhsZw", "crv": "P-256", "x": "FdYslsTybViEudE4T-gyBrcKeZNleH9-QajFYVpOYW8", "y": "If-rr6KWEEnC_R8N93SrcQRn4E7lC4WXOqgANj-o0UE" }, { "kty": "EC", "kid": "default_signing_key_id", "crv": "P-256", "x": "-i8_UtCwdCic10eDuNwr68IEHWk4B1HSn119fdNT-pQ", "y": "UIMFXTj4kOWF2gZaKDTP3n3K-08TfkLHw8hIV6bOxqw" }, { "kty": "EC", "kid": "default_signing_key_id", "crv": "P-256", "x": "-i8_UtCwdCic10eDuNwr68IEHWk4B1HSn119fdNT-pQ", "y": "UIMFXTj4kOWF2gZaKDTP3n3K-08TfkLHw8hIV6bOxqw" } ] }, "credential_response_encryption_alg_values_supported": [ "RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "A128KW", "A192KW", "A256KW", "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW" ], "credential_response_encryption_enc_values_supported": [ "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM", "A192GCM", "A256GCM" ], "require_credential_response_encryption": false, "credentials_supported": [ "vp_token" ], "credential_endpoint": "https://my-issuer.example.com:8000/credential", "credential_endpoint_auth_methods": [ "dpop_client_auth" ] } }, "authority_hints": [ "https://trust-anchor.example.com:7001" ], "trust_marks": [ "eyJhbGciOiJSUzI1Ni...", "eyJhbGciOiJSUzI1N..." ], "jwks": { "keys": [ { "kty": "RSA", "use": "sig", "kid": "VmhPQndmVDNja09ZYTQ4UlM3eWl2Z3BxMlp1cVd1ZFB1YnhwdWUxa3p4Zw", "e": "AQAB", "n": "y68Zlt9DHIXHvH3HMFtY..." }, { "kty": "EC", "use": "sig", "kid": "dTlESU50RVVjVDA3eWFPV0dMQ2taMC0tbDlWclBjQTBUdkpyNlVhSVBfOA", "crv": "P-256", "x": "IqpTNpOAXTsQVVlO18zzAV1rHI36qBvZv7VbdtniV-c", "y": "JozJQWmYCkvxD4PtUnr6sKXRL8SOj7ggx6WHzQxHgaw" } ] }, "iss": "https://my-issuer.example.com:8000", "iat": 1732718163, "exp": 1732804563 }
...
Trust Anchors
The Trust Anchor (TA) is the root of the Trust Infrastructure’s trust chain.
Trust Anchor URL:
- For your setup, the Trust Anchor URL is:
https://openidfed-test-1.sunet.se:7001
- For your setup, the Trust Anchor URL is:
Trust Anchor Keys: Add the Trust Anchor’s and public keys to your configuration:
Code Block language yml trust_anchors: https://openidfed-test-1.sunet.se:7001: keys: - kty: RSA use: sig kid: UFpoajluZU42dTNUUXo5RnhBVEJnRk9JY2NtU1JKdlVYUk1RUFRyVkFFRQ n: p9S2whcSjmBdxerp80tIJreUUmZiGNGXIocJlNjx9pgD5_WD2l6mBNuEZMpP-QUB_TSV3VesNiqmOdydGp1wkfQ-NmVdoso29FjEdgrckLIwirAVmVQ6bGQQnXJrR56mRz0QqENi11vVpbDj6hsprxK1EZBQL-sQ2kem289B_BCNT-NvwVHrYJlaQA32z7cs1a7W8wt9eLxA10PeiYMgDVU_69wKBw4YrjjozOHKMRGchUQEjQhfSZfk49bip_5TNz4dmBmSCIbdE2yilFrfRSNrh7q2myuyDE3k2QZbSOXXGGT1LtHO74WIY58v-M3A7_zxp0f2Eo9ZD3N4h-InIw e: AQAB - kty: EC use: sig kid: Nm82cTJKMDkydXhxOUMtTm0teFpMWlZiR0ZVa2U3YVVtbkJTV3hBd3FqOA crv: P-256 x: 69XlQkKYfWJDXAv_Vbrqyfz9gfAhu1qQ4mtLde18-Cg y: ntBwdhy4_cS2PRBS-xdKkNwcO1yQP8TdoOHbHN9Yjv8
Purpose: Trust Anchors validate Trust Marks’ signatures and establish trust within the Trust Infrastructure.
...
Registering the Issuer as a Subordinate Entity
In the Trust Infrastructure, the Issuer must be registered as a Subordinate Entity under a Superior Entity (e.g., a Trust Anchor or an Intermediate Entity). This ensures the Issuer's formal inclusion in the trust hierarchy.
Key Steps for the Issuer Operator
Publish Metadata
Make the Issuer's metadata available at the following URL:
https://<issuer-entity-id>/.well-known/openid-federation
...
- Once the metadata is published, provide the `entity_id` to the Superior Entity.
- The Superior Entity will retrieve the metadata from the `/.well-known/openid-federation` endpoint and complete the registration process.
...
Generating the Issuer Registration Document
To register the Issuer with the Trust Infrastructure, you need to create a JSON document containing the Issuer’s public keys. You can do this manually or by using a one-liner command to automate the process. Choose the method that best suits your setup
Option 1: Manual Method
If you prefer to create the document manually, follow these steps:
Copy the Public Keys File to issuer_registration.json
- Run the following command to create a working copy of the file:
Code Block | ||
---|---|---|
| ||
cp satosa/public/pid_fed_keys.json issuer_registration.json |
Edit issuer_registration.json
- Open the file in a text editor of your choice
- Modify the contents to match the following structure, replacing
<issuer-entity-id>
with the actual Issuer Entity Identifier (e.g.,https://issuer.example.com
):
Code Block |
---|
{
"<issuer-entity-id>": {
"entity_types": [
"federation_entity",
"openid_credential_issuer",
"oauth_authorization_server"
],
"jwks":
}
} |
Move the Public Keys into jwks
- Locate the
"keys"
array already present inissuer_registration.json
. - Move it inside the
"jwks"
section so the structure looks like this:
Code Block |
---|
{
"https://issuer.example.com": {
"entity_types": [
"federation_entity",
"openid_credential_issuer",
"oauth_authorization_server"
],
"jwks": {
"keys": [
{
"kty": "RSA",
"use": "sig",
"kid": "example-kid",
"n": "example-n-value",
"e": "AQAB"
}
]
}
}
} |
...
Option 2: One-Liner Command (Automated)
For users who prefer a quick and automated approach, use this single command to generate the JSON document:
Replace "https://issuer.example.com"
with the actual Issuer Entity URI.
Code Block | ||
---|---|---|
| ||
issuer_entity_uri="https://issuer.example.com" && jq --arg uri "$issuer_entity_uri" '{($uri): {"entity_types": ["federation_entity", "openid_credential_issuer", "oauth_authorization_server"], "jwks": .}}' satosa/public/pid_fed_keys.json > issuer_registration.json |
...
Final Step: Send the Document
Once the file issuer_registration.json
is created using either method, send it to:
support@dc4eu.eu
...
...
Authority Hints
The authority_hints
parameter specifies the URL of the Intermediate Entities or Trust Anchors that are Immediate Superiors of the Entity. This helps other Trust Infrastructure participants understand upstream trust relationships.
Add to Configuration: Add
authority_hints
in your issuer’s metadata configuration:Code Block language yml authority_hints: - "https://openidfed-test-1.sunet.se:7001"
Purpose: This parameter establishes hierarchical trust relationships from your issuer to the Trust Anchor.
...
Trust Marks
Trust Marks are JWTs issued by a Trust Mark Issuer to validate compliance with Trust Infrastructure policies.
Types of Trust Marks
The following Trust Marks are available for issuance:
EHIC Credential:
ID: http://dc4eu.example.com/EHICCredential/se
PDA1 Credential:
ID: http://dc4eu.example.com/PDA1Credential/se
Retrieving Trust Marks
For now, Trust Marks will be supplied when the entity is added to the Trust Infrastructure.
Inputs to Trust Mark Issuer:
id
: The identifier for the Trust Mark (e.g.,http://dc4eu.example.com/EHICCredential/se
).sub
: The entity's entity_id.
Steps:
Supply the
id
andsub
to the Trust Mark Issuer.Retrieve the issued Trust Mark as a signed JWT.
Validation:
- Use a JWT library to verify the Trust Mark's signature using the Trust Mark Issuer's public key:
- Retrieve public keys from the Trust Mark Issuer's /.well-known/jwks.json endpoint.
- Validate claims such as
iss
,sub
,id
, andiat
for compliance.
- Use a JWT library to verify the Trust Mark's signature using the Trust Mark Issuer's public key:
Include in Metadata: Add issued Trust Marks to your issuer’s metadata:
Code Block language yml trust_marks: - "eyJhbGciOiJIUzI1NiIsInR..." - "eyJhbGciOiJIUzI1NiIsInR..."
...
Add Trust Marks to the vc_up_and_running Issuer
To update the Trust Marks, you need to modify the trust_marks section of the satosa/plugins/oidc_frontend.yaml file. Follow the steps below to replace the existing Trust Marks with the ones received from the Trust Infrastructure operator.
...