Disclaimer:
This document is a work in progress and subject to further refinements and updates. Please note that some details may change as new requirements emerge or as part of ongoing development. Feedback and suggestions for improvement are welcome.


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.

  1. Define the Endpoint:

    • The endpoint is defined under the following path: /.well-known/openid-federation
  2. Implementation:

    • Ensure this endpoint serves the issuer’s Entity Configuration.
  3. Example Entity Configuration: Here is an example of Entity Configuration that can be exposed at the endpoint: 

    {
        "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.

  1. Trust Anchor URL:

  2. Trust Anchor Keys: Add the Trust Anchor’s  and public keys to your configuration: 

    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
  3. Purpose: Trust Anchors validate Trust Marks’ signatures and establish trust within the Trust Infrastructure.



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.

  1. Add to Configuration: Add authority_hints in your issuer’s metadata configuration: 

    authority_hints:
      - "https://openidfed-test-1.sunet.se:7001"

  2. Purpose: This parameter establishes hierarchical trust relationships from your issuer to the Trust Anchor.


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.

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

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):
{
  "<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 in issuer_registration.json.
  • Move it inside the "jwks" section so the structure looks like this:
{
  "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.

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


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.

  1. 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.
  2. Steps:

    • Supply the id and sub to the Trust Mark Issuer.

    • Retrieve the issued Trust Mark as a signed JWT.

  3. 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, and iat for compliance.
  4. Include in Metadata: Add issued Trust Marks to your issuer’s metadata:

    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.

  1. Locate the Trust Marks Section

    In the current configuration, the trust_marks are defined under: 

    trust_marks:
      - <existing-trust-mark-1>
    

    You need to replace these values with the new Trust Marks provided by the Trust Infrastructure operator.

  2. Example Update 

    If the operator provided the following new Trust Marks:

    eyJhbGciOiJSUzI1NiIsImtpZCI6IjM2NWQ2MjY3LTI5MzQtNGJhNy05YjEyLWU4ZmFkNTYwYjZjMyJ9...
    eyJhbGciOiJSUzI1NiIsImtpZCI6IjkwNTFjZTgzLTY1NzEtNDliYi04ODdjLTc3OWQzMDNmOTRmYyJ9...

    Modify the trust_marks section as follows: 

    trust_marks:
      - eyJhbGciOiJSUzI1NiIsImtpZCI6IjM2NWQ2MjY3LTI5MzQtNGJhNy05YjEyLWU4ZmFkNTYwYjZjMyJ9...
      - eyJhbGciOiJSUzI1NiIsImtpZCI6IjkwNTFjZTgzLTY1NzEtNDliYi04ODdjLTc3OWQzMDNmOTRmYyJ9..
  3. Restart the Issuer to Apply Changes

    Once you've updated the configuration file, restart the Issuer container to apply the changes: 

    ./stop.sh && \
    ./start.sh
  4. Verify the Changes
    After restarting the Issuer, verify that the new Trust Marks are correctly applied:

    curl -k -s https://<issuer-host>:8000/.well-known/openid-federation | cut -d '.' -f2 | tr '_-' '/+' | base64 -d 2>/dev/null | jq .

    Look for the updated trust_marks in the JSON response.

Testing Trust Marks

  1. Decode JWT: Use tools like jwt.io to inspect the Trust Mark's claims and ensure all required fields are present.

  2. Verify Signature: Validate the JWT signature against the Trust Mark Issuer's public key.

  3. Check Expiration: Ensure the exp claim (if present) has not expired.

  4. Validate References: Follow the ref URL (if provided) to confirm compliance with human-readable policy documents.


Steps to Connect the Issuer

  1. Configure the Issuer:

    • Update the Issuer’s configuration to include authority_hints, trust_marks, and trust_anchors.
  2. Register with the Trust Infrastructure:

    • Share your issuer_registration.json with the Trust Anchor or superior entity for registration.
  3. Validate Configuration:

    • Test the issuer using testing tools or with a sandbox environment.
  4. Monitor the Connection:

    • Regularly verify the status and ensure Trust Marks are up-to-date.

Testing the Trust Relationships

  1. Validate Trust Marks: Use tools like jwt.io to decode and verify Trust Marks using the Trust Anchor's public keys.

  2. Retrieve Metadata: Ensure the .well-known/openid-federation endpoint correctly serves the issuer’s metadata: 

    curl -X GET https://your-issuer.example.com/.well-known/openid-federation

  3. Check Authority Hints: Verify that authority_hints points to the correct Trust Anchor: 

    authority_hints:
      - "https://openidfed-test-1.sunet.se:7001"
    
    
  4. Validate Public Keys: Confirm that the Trust Anchor’s public keys match the ones provided in the configuration.


  • No labels