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 an OpenID Federation (OIDF) trust framework. It includes details on configuring the authority_hints
, trust_marks
, federation info endpoint
, and trust_anchors
using specific values provided for the test environment.
Before proceeding, ensure the following are in place:
The configuration endpoint publishes the Entity Configuration document, detailing the issuer’s configuration information for federation participants.
Define the Endpoint:
.well-known/openid-federation
Implementation:
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 } |
The Trust Anchor (TA) is the root of the federation’s trust chain.
Trust Anchor URL:
https://openidfed-test-1.sunet.se:7001
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 |
Purpose: Trust Anchors validate Trust Marks’ signatures and establish trust within the federation.
In an OpenID Federation trust framework, the Issuer must be added as a Subordinate Entity under a Superior Entity (e.g., a Trust Anchor or an Intermediate Entity). This process ensures that the Issuer is recognized as part of the trust hierarchy.
The authority_hints
parameter specifies the URL of the Intermediate Entities or Trust Anchors that are Immediate Superiors of the Entity. This helps other federation participants understand upstream trust relationships.
Add to Configuration: Add authority_hints
in your issuer’s metadata configuration:
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 are JWTs issued by a Trust Mark Issuer to validate compliance with federation policies.
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
Inputs to Trust Mark Issuer:
id
: The identifier for the Trust Mark (e.g., http://dc4eu.example.com/EHICCredential/se
).sub
: The entity's unique identifier (entity_id
).Steps:
Supply the id
and sub
to the Trust Mark Issuer.
Retrieve the issued Trust Mark as a signed JWT.
Validation:
.well-known/jwks.json
endpoint.iss
, sub
, id
, and iat
for compliance.Include in Metadata: Add issued Trust Marks to your issuer’s metadata:
trust_marks: - "eyJhbGciOiJIUzI1NiIsInR..." - "eyJhbGciOiJIUzI1NiIsInR..." |
Decode JWT: Use tools like jwt.io
to inspect the Trust Mark's claims and ensure all required fields are present.
Verify Signature: Validate the JWT signature against the Trust Mark Issuer's public key.
Check Expiration: Ensure the exp
claim (if present) has not expired.
Validate References: Follow the ref
URL (if provided) to confirm compliance with human-readable policy documents.
Configure the Issuer:
authority_hints
, trust_marks
, federation info endpoint
, and trust_anchors
.Register with the Federation:
.well-known/openid-federation
endpoint with the Trust Anchor or superior entity for registration.Validate Configuration:
Monitor the Connection:
Validate Trust Marks: Use tools like jwt.io
to decode and verify Trust Marks using the Trust Anchor's public keys.
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 |
Check Authority Hints: Verify that authority_hints
points to the correct Trust Anchor:
authority_hints: - "https://openidfed-test-1.sunet.se:7001" |
Validate Public Keys: Confirm that the Trust Anchor’s public keys match the ones provided in the configuration.