R. Hedberg, Ed. | |
independent | |
M. Jones | |
Microsoft | |
A. Solberg | |
Uninett | |
S. Gulliksson | |
Schibsted | |
J. Bradley | |
Yubico | |
December 01, 2020 |
OpenID Connect Federation 1.0 - draft 13
openid-connect-federation-1_0
The OpenID Connect standard specifies how a Relying Party (RP) can discover metadata about an OpenID Provider (OP), and then register to obtain RP credentials. The discovery and registration process does not involve any mechanisms of dynamically establishing trust in the exchanged information, but instead rely on out-of-band trust establishment.
In an identity federation context, this is not sufficient. The participants of the federation must be able to trust information provided about other participants in the federation. OpenID Connect Federations specifies how trust can be dynamically obtained by resolving trust from a common trusted third party.
While this specification is primarily targeting OpenID Connect, it is designed to allow for re-use by other protocols and in other use cases.
This specification describes how two entities that would like to interact can dynamically fetch and resolve trust and metadata for a given protocol through the use of third-party trust anchor. A trust anchor is an entity whose main purpose is to issue statements about entities, such as OpenID Connect Relying Parties, OpenID Providers, and participating organizations. An identity federation can be realized using this specification using one or more levels of trust issuers. This specification does not mandate a specific way or restrict how a federation may be built. Instead, the specification provides the basic technical trust infrastructure building blocks needed to build a dynamic and distributed trust network such as a federation.
Note that this specification only concerns itself with how two entities in a federation gets to know about each other it does not change any other functionality in OpenID Connect.
Note that a company, as with any real-world organization, may be represented by more than one entity in a federation.
OpenID Connect Federation trust chains rely on cryptographically signed JSON Web Token (JWT) documents, and the trust chain does not at all rely on TLS [RFC8446] in order to establish trust.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
This specification uses the terms "Claim Name", "Claim Value", "JSON Web Token (JWT)", defined by JSON Web Token (JWT) and the terms "OpenID Provider (OP)" and "Relying Party (RP)" defined by OpenID Connect Core 1.0.
This specification also defines the following terms:
An entity statement is issued by an entity and concerns a subject entity and leaf entities in a federation. An entity statement is always a signed JWT. All entities in a federation SHOULD be prepared to publish an entity statement about themselves. If they are not able to do so themselves someone else MUST do it for them.
An entity statement is composed of the following claims:
The entity statement is signed using the private key of the issuer entity, in the form of a JSON Web Signature (JWS). Entities MUST support signing Entity Statements with the RSA SHA-256 algorithm (an alg value of RS256). Consequently entities MUST support signature verification where the statement was signed using RS256.
The following is a non-normative example of an entity statement before serialization and adding a signature. The example contains a critical extension jti (JWT ID) to the entity statement and one critical extension to the policy language regexp (Regular expression).
{ "iss": "https://feide.no", "sub": "https://ntnu.no", "iat": 1516239022, "exp": 1516298022, "crit": ["jti"], "jti": "7l2lncFdY6SlhNia", "policy_language_crit": ["regexp"], "metadata_policy": { "openid_provider": { "issuer": {"value": "https://ntnu.no"}, "organization_name": {"value": "NTNU"}, "id_token_signing_alg_values_supported": {"subset_of": ["RS256", "RS384", "RS512"]}, "op_policy_uri": { "regexp": "^https:\/\/[\\w-]+\\.example\\.com\/[\\w-]+\\.html"} }, "openid_relying_party": { "organization_name": {"value": "NTNU"}, "grant_types_supported": { "subset_of": ["authorization_code", "implicit"]}, "scopes": { "subset_of": ["openid", "profile", "email", "phone"]} } }, "constraints": { "max_path_length": 2 }, "jwks": { "keys": [ { "alg": "RS256", "e": "AQAB", "ext": true, "key_ops": ["verify"], "kid": "key1", "kty": "RSA", "n": "pnXBOusEANuug6ewezb9J_...", "use": "sig" } ] }, "authority_hints": [ "https://edugain.org/federation" ] }
In an OpenID Connect Identity Federation, entities that together build a trust chain can be categorized as:
A trust chain begins with a leaf entity's self-signed entity statement, has zero or more entity statements issued by intermediates about subordinates, and ends with an entity statement issued by the trust anchor about the top-most intermediate (if there are intermediates) or the leaf entity (if there are no intermediates).
A simple example: If we have an RP that belongs to organization A that is a member of federation F, the trust chain for such a setup will contain the following entity statements:
A trust chain MUST always be possible to order such that: If we name the entity statements ES[0] (the leaf entity's self-signed entity statement) to ES[i] (an entity statement issued by the trust anchor), i>0 then:
The signing key that MUST be used to verify ES[i] is distributed from the trust anchors to the any entity that needs to verify a trust chain in some secure out-of-band way not described in this document.
This specification does allow new metadata types to be defined, to support use cases outside OpenID Connect federations. The metadata type identifier will uniquely identify which metadata specification to utilize.
The metadata document MUST be a JSON document. Beyond that there is no restriction.
Metadata used in federations typically re-uses existing metadata standards. If needed, the metadata schema is extended with additional properties relevant in a federated context. For instance, for OpenID Connect Federations, this specification uses metadata values from OpenID Connect Discovery 1.0 and OpenID Connect Dynamic Client Registration 1.0 and adds additional values used for federations.
The metadata type identifier is openid_relying_party.
All parameters defined in Section 2 of OpenID Connect Dynamic Client Registration 1.0 are allowed in a metadata statement.
To that list is added:
The metadata type identifier is openid_provider.
All parameters defined in Section 3 of OpenID Connect Discovery 1.0 are applicable.
In addition, the following parameters are defined by this specification:
The only client authentication method that can be used if doing authentication as described in
OpenID Connect Core 1.0 is request_object. If pushed authorization is used then one of private_key_jwt, tls_client_auth and self_signed_tls_client_auth can be used.
The following is a non-normative example of OP metadata:'
{ "issuer": "https://server.example.com", "authorization_endpoint": "https://server.example.com/authorization", "token_endpoint": "https://server.example.com/token", "jwks_uri": "https://server.example.com/jwks.json", "response_types_supported": ["code", "id_token", "id_token token"], "subject_types_supported": ["public"], "id_token_signing_alg_values_supported": ["RS256", "ES256"], "token_endpoint_auth_methods_supported": ["private_key_jwt"], "pushed_authorization_request_endpoint": "https://server.example.com/par", "client_registration_types_supported": ["automatic", "explicit"], "federation_registration_endpoint": "https://server.example.com/fedreg", "client_registration_authn_methods_supported": { "ar": ["request_object"], "par": ["private_key_jwt", "self_signed_tls_client_auth"] } }
The metadata type identifier is oauth_authorization_server.
All parameters defined in Section 2 of RFC 8414 are applicable.
The metadata type identifier is oauth_client.
All parameters defined in Section 2 of RFC 7591 are applicable.
The metadata type identifier is oauth_resource. There is no standard that specifies what parameters that can occur in the metadata for this kind of entity. So for the time being, this can be regarded as a place holder.
The metadata type identifier is federation_entity.
All entities participating in a federation are of this type.
The following properties are allowed:
Example
"federation_entity": { "federation_api_endpoint": "https://example.com/federation_api_endpoint", "name": "The example cooperation", "homepage_uri": "https://www.example.com" }
The metadata for a specific entity can be constructed by combining the metadata polices defined by the trust anchor and possible intermediates starting with the trust anchor and the applying this combined policy to the metadata information in a leaf entity's entity statement.
Policies are expressed using a JSON object.
The following keywords represent different actions/checks that MUST be applied to the metadata.
The resulting value of the claim will be the intersection of the values specified here and the values of the claim. For instance, the claim policy:
"response_types": { "subset_of": ["code", "code token", "code id_token"]}
if applied to a metadata statement with:
"response_types": ["code", "code id_token token", "code id_token"]
will update the claim in the metadata statement to be:
"response_types": ["code", "code id_token"]
If an entity tries to register a value that is not in the subset_of set of values, applying the policy MUST lead to a failure.
The value of the claim MUST be one of the ones listed here. As an example, if the claim policy:
"request_object_signing_alg": { "one_of": ["ES256", "ES384", "ES512"]}
is applied to the metadata statement
"request_object_signing_alg": "ES384"
the resulting claim statement will be:
"request_object_signing_alg": "ES384"
If an entity tries to register a value that is not in the one_of set of values, applying the policy MUST lead to a failure.
The values of the claim MUST contain the ones listed here. We define superset the mathematical way, that is equality is included. As an example, if the claim policy:
"request_object_signing_alg_values_supported": { "superset_of": ["ES256", "RS256"]}
is applied to the metadata statement
"request_object_signing_alg_values_supported": [ "ES256", "ES384", "RS256", "RS512"]
the resulting claim statement will be:
"request_object_signing_alg_values_supported": [ "ES256", "ES384", "RS256", "RS512"]
If an entity tries to register a set of values that are not a superset of the ones specified by superset_of, applying the policy MUST lead to a failure.
Adds the value or values specified to the list of values for the metadata statement claim. If the specified value is already present in the list, this operation has no effect. If the claim has no value then the claim is initialized with the specified value. As an example, if the claim policy:
"contacts": { "add": "support@federation.example.com"}
is applied to the following claim in the metadata statement:
"contacts": "support@org.example.com"
the end result will be the claim:
"contacts": ["support@org.example.com", "support@federation.example.com"]
Disregarding what value the claim had, if any, the claims value will be set to what is specified here. As an example, if the claim policy:
"require_auth_time": { "value": true}
is applied to a metadata statement with the claim
"require_auth_time": false
then the metadata statement will afterwards contain:
"require_auth_time": true
If no value is assigned to this claim, then the claim's value will be set to what is specified here. As an example, if the claim policy:
"require_auth_time": { "default": true }
is applied to a metadata statement with the claim
"require_auth_time": false
then the metadata statement will afterwards contain:
"require_auth_time": false
If on the other hand, the metadata statement did not contain a require_auth_time claim then the following claim statement would be added to the metadata statement:
"require_auth_time": true
If 'true' then claim MUST have a value. essential can be combined with all the other types.
"tos_uri": { "essential": true}
The upshot of applying this policy to a metadata statement is that the metadata statement MUST contain such a claim otherwise the metadata statement is incorrect.
An entity may use more then one policy type when expressing a policy for a claim. These are the policy types that can be combined in a metadata_policy statement:
If there is more than one metadata policy in a trust chain, then the policies MUST be combined before they are applied to the metadata statement.
Using the notation we have defined in Section 2.2 policies are combined starting with ES[i] and then adding the policies from ES[j] j=i-1,..,1 before applying the combined policy to the entity's metadata.
After having combined the policies, the policy for each claim MUST adhere to the rules defined in Section 4.1.2.
These are the policy types that can be merged when combining two policies:
It should be noted that applying subset_of, superset_of or one_of to an empty value will result in an empty value.
A federations policy for RPs:
{ "scopes": { "subset_of": [ "openid", "eduperson", "phone" ], "superset_of": [ "openid" ], "default": [ "openid", "eduperson" ] }, "id_token_signed_response_alg": { "one_of": [ "ES256", "ES384", "ES512" ] }, "contacts": { "add": "helpdesk@federation.example.org" }, "application_type": { "value": "web" } }
An organization's policy for RPs:
{ "scopes": { "subset_of": [ "openid", "eduperson", "address" ], "default": [ "openid", "eduperson" ] }, "id_token_signed_response_alg": { "one_of": [ "ES256", "ES384" ], "default": "ES256" }, "contacts": { "add": "helpdesk@org.example.org" } }
The combined metadata policy then becomes:
{ "scopes": { "subset_of": [ "openid", "eduperson" ], "superset_of": [ "openid" ], "default": [ "openid", "eduperson" ] }, "id_token_signed_response_alg": { "one_of": [ "ES256", "ES384" ], "default": "ES256" }, "contacts": { "add": [ "helpdesk@federation.example.org", "helpdesk@org.example.org" ] }, "application_type": { "value": "web" } }
If applying policies to a metadata statement results in incorrect metadata, then such a metadata statement MUST be regarded as broken and MUST NOT be used.
There might be parties that want to extend the policy language defined here. If that happens then the rule is that if software compliant with this specification encounters a keyword it doesn't understand it MUST ignore it unless it is listed in a policy_language_crit list, as is done for JWS header parameters with the crit parameter. If the policy language extension keyword is listed in the policy_language_crit list and not understood, then the metadata MUST be rejected.
The following is a non-normative example of a set of policies being applied to an RP's metadata.
The RP's metadata:
{ "contacts": [ "rp_admins@cs.example.com" ], "redirect_uris": [ "https://cs.example.com/rp1" ], "response_types": [ "code" ] }
The federation's policy for RPs:
{ "scopes": { "superset_of": [ "openid", "eduperson" ], "default": [ "openid", "eduperson" ] }, "response_types": { "subset_of": [ "code", "code id_token" ] } }
The organization's policy for RPs:
{ "contacts": { "add": "helpdesk@example.com" }, "logo_uri": { "one_of": [ "https://example.com/logo_small.jpg", "https://example.com/logo_big.jpg" ], "default": "https://example.com/logo_small.jpg" }, "policy_uri": { "value": "https://example.com/policy.html" }, "tos_uri": { "value": "https://example.com/tos.html" } }
The metadata for the entity in question after applying the policies above, would then become:
{ "contacts": [ "rp_admins@cs.example.com", "helpdesk@example.com" ], "logo_uri": "https://example.com/logo_small.jpg", "policy_uri": "https://example.com/policy.html", "tos_uri": "https://example.com/tos.html", "scopes": [ "openid", "eduperson" ], "response_types": [ "code" ], "redirect_uris": [ "https://cs.example.com/rp1" ] }
A constraint specification can contain the following claims:
The following is a non-normative example of such a specification:
{ "naming_constraints": { "permitted": [ "https://.example.com" ], "excluded": [ "https://east.example.com" ] }, "max_path_length": 2 }
If a subordinate entity statement contains a constraint specification that is more restrictive then the one in effect, then the more restrictive constraint is in effect from here on.
If a subordinate entity statement contains a constraint specification that is less restrictive then the one in effect, then it MUST be ignored.
The max_path_length constraint specifies the maximum number of entity statement a trust chain can have between the entity statement that contains the constraint specification and the leaf's entity statement.
A max_path_length constraint of zero indicates that no entity statement may appear between this entity statement and the leaf entity statement. Where it appears, the max_path_length constraint MUST have a value that is greater than or equal to zero. Where max_path_length does not appear, no limit is imposed.
Assuming that we have a trust chain with four entity statements:
Then the trust chain fulfills the constraints if:
The trust chain does not fulfill the constraints if:
The name constraints indicates a name space within which all subject entity identifiers in subordinate entity statements in a trust chain MUST be located.
Restrictions are defined in terms of permitted or excluded name subtrees. Any name matching a restriction in the excluded claim is invalid regardless of information appearing in the permitted claim.
The constraint MUST be specified as a fully qualified domain name and MAY specify a host or a domain. Examples would be "host.example.com" and ".example.com". When the constraint begins with a period, it MAY be expanded with one or more labels. That is, the constraint ".example.com" is satisfied by both host.example.com and my.host.example.com. However, the constraint ".example.com" is not satisfied by "example.com". When the constraint does not begin with a period, it specifies a host.
In this specification we use the US NSTIC definition
"A trustmark is used to indicate that a product or service provider has met the requirements of the Identity Ecosystem, as determined by an accreditation authority"
Technically trust marks as used by this specification are signed JWTs that represents a statement of conformance to a well-scoped set of trust and/or interoperability requirements.
The trust marks are signed by a federation accredited authority. The validation of such a signed statement is performed in the same way as a self-signed entity statement is validated.
Note that a federation may allow an entity to self-signed some trust marks.
These are the properties that can occur in a trust mark:
An entity should not try to validate a trust mark until it knows which trust anchors it wants to use.
validating a trust mark follows the procedure set out in Section 7
Note that the entity representing the accreditation authority MUST be immediately below the trust anchor. There can not be any intermediate between it and the trust anchor.
An example of a self-signed certification mark
{ "iss": "https://example.com/op", "sub": "https://example.com/op", "iat": 1579621160, "id": "https://openid.net/certification/op", "mark": "http://openid.net/wordpress-content/uploads/2016/ 05/oid-l-certification-mark-l-cmyk-150dpi-90mm.jpg", "ref": "https://openid.net/wordpress-content/uploads/2015/ 09/RolandHedberg-pyoidc-0.7.7-Basic-26-Sept-2015.zip" }
An example of a 3rd party accreditation authority
{ "iss": "https://swamid.sunet.se", "sub": "https://umu.se/op", "iat": 1577833200, "exp": 1609369200, "id": "https://refeds.org/wp-content/uploads/2016/01/Sirtfi-1.0.pdf" }
The configuration endpoint is found using the Well-Known URIs specification, with the suffix openid-federation. The scheme, host and port is taken directly from the entity identifier combined with the following path: /.well-known/openid-federation.
If the entity identifier contains a path, it is concatenated after /.well-known/openid-federation in the same manner that path components are concatenated to the well-known identifier in the OAuth 2.0 Authorization Server Metadata [RFC8414] specification. Of course, in real multi-tenant deployments, in which the entity identifier might be of the form https://multi-tenant-service.example.com/my-tenant-identifier the tenant is very likely to not have control over the path https://multi-tenant-service.example.com/.well-known/openid-federation/my-tenant-identifier whereas it is very likely to have control over the path https://multi-tenant-service.example.com/my-tenant-identifier/.well-known/openid-federation. Therefore, if using the configuration endpoint at the URL with the tenant path after the well-known part fails, it is RECOMMENDED that callers retry at the URL with the tenant path before the well-known part (even though this violates [RFC8615]).
Federation Entities SHOULD make an Entity Configuration Document available at the configuration endpoint. There is only one exception to this rule and that is for an RP that only does explicit registration. Since it posts the self-signed entity statement to the OP during client registration, the OP has everything it needs from the RP.
A federation Entity Configuration Document MUST be queried using an HTTP GET request at the previously specified path. The requesting party would make the following request to the Entity https://example.com to obtain its Configuration information:
GET /.well-known/openid-federation HTTP/1.1 Host: example.com
The response is a self-signed Entity Statement, as described in entity statement. If the entity is an intermediate entity or a trust anchor the response MUST contain metadata for a federation entity.
A positive response is a signed entity statement, where the content type MUST be set to application/jose. In case of an error, the response will be a JSON object, the content type MUST be set to application/json and the error response uses the applicable HTTP status code value.
The following is a non-normative example response from an intermediate entity, before serialization and adding a signature:
200 OK Last-Modified: Thu, 29 Aug 2019 08:54:26 GMT Content-Type: application/jose { "iss": "https://example.com", "sub": "https://example.com", "iat": 1516239022, "exp": 1516298022, "metadata": { "federation_entity": { "federation_api_endpoint": "https://example.com/federation_api_endpoint", "name": "The example cooperation", "homepage_uri": "https://www.example.com" } }, "authority_hints": ["https://federation.example.com"], "jwks": { "keys": [ { "alg": "RS256", "e": "AQAB", "ext": true, "key_ops": [ "verify" ], "kid": "key1", "kty": "RSA", "n": "pnXBOusEANuug6ewezb9J_...", "use": "sig" } ] } }
All entities that are expected to publish entity statements about other entities MUST expose a Federation API endpoint.
The federation API endpoint of an entity can be found in the configuration response as described in Section 5 or by other means.
The Federation API is an HTTPS API that may support multiple operations. Fetching entity statements is one of the operations, and the only one that all Federation API endpoints are REQUIRED to support. All the other operations are OPTIONAL. The list of defined operations may be extended in a future.
While all operations on the federation API endpoint make use of a GET request, other operations may choose to use other HTTP methods. If the operation parameter is left out, it is treated as a fetch entity statements request. Unless otherwise mentioned or agreed upon, requests to the federation API do not need to be authenticated.
Fetching entity statement is used to collect entity statements one by one in order to gather trust chains.
In order to fetch an entity statement, an entity needs to know the identifier of the entity to ask (the issuer), the federation API endpoint of that entity and the identifier of the entity that you want the statement to be about (the subject).
The request MUST be an HTTP request using the GET method and the https scheme to a resolved federation API endpoint with the following query string parameters:
The following is a non-normative example of an API request for an entity statement:
GET /federation_api_endpoint? iss=https%3A%2F%2Fopenid.sunet.se%2Ffederation HTTP/1.1 Host: openid.sunet.se
A positive response is a signed entity statement where the content type MUST be set to application/jose. If it is negative response it will be a JSON object and the content type MUST be set to application/json. See more about error responses in Section 6.4.
The following is a non-normative example of a response, before serialization and adding a signature:
200 OK Last-Modified: Mon, 17 Dec 2018 11:15:56 GMT Content-Type: application/jose { "iss": "https://openid.sunet.se", "sub": "https://openid.sunet.se", "iat": 1516239022, "exp": 1516298022, "metadata": { "openid_relying_party": { "application_type": "web", "redirect_uris": [ "https://openid.sunet.se/rp/callback" ], "organization_name": "SUNET", "logo_uri": "https://www.sunet.se/sunet/images/32x32.png", "grant_types": [ "authorization_code", "implicit" ], "jwks_uri": "https://openid.sunet.se/rp/jwks.json" } }, "jwks": { "keys": [ { "alg": "RS256", "e": "AQAB", "ext": true, "key_ops": [ "verify" ], "kid": "key1", "kty": "RSA", "n": "pnXBOusEANuug6ewezb9J_...", "use": "sig" } ] }, "authority_hints": [ "https://edugain.org/federation" ] }
An entity may use the trust negotiation operation in order to fetch resolved metadata about itself as seen/trusted by a remote peer. The result may, for instance, tell an RP what operations, scopes and claims an OP would allow the RP to use if a specific trust anchor was used.
The request MUST be an HTTP request using the GET method and the https scheme to a resolved federation API endpoint with the following query string parameters:
The following is a non-normative example of an API request for trust negotiation:
GET /federation_api_endpoint? operation=resolve_metadata& respondent=https%3A%2F%2Fopenid.sunet.se%2Ffederation& type=openid_provider& anchor=https%3A%2F%2Fswamid.se& peer=https%3A%2F%2Fidp.umu.se%2Fopenid HTTP/1.1 Host: openid.sunet.se
The response is a metadata statement that is the result of applying the metadata policies in the trust chain on the entity's metadata.
The following is a non-normative example of a response:
200 OK Last-Modified: Wed, 22 Jul 2018 19:15:56 GMT Content-Type: application/json { "organization_name": "University of Umea", "contacts": [ "legal@umu.se", "technical@umu.se" ], "logo_uri": "https://www.umu.se/SRWStatic/img/umu-logo-left-neg-SE.svg", "op_policy_uri": "https://www.umu.se/en/about-the-website/legal-information/", "authorization_endpoint": "https://idp.umu.se/openid/authorization", "token_endpoint": "https://idp.umu.se/openid/token", "response_types_supported": [ "code", "code id_token", "token" ], "grant_types_supported": [ "authorization_code", "implicit", "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "subject_types_supported": [ "pairwise" ], "id_token_signing_alg_values_supported": [ "RS256" ], "issuer": "https://idp.umu.se/openid", "jwks_uri": "https://idp.umu.se/openid/jwks_uri.json" }
An entity may query another entity for a list of all the entities immediately subordinate to that entity and about which that entity is prepared to issue statements about. (In some cases, this may be a very large list.)
The request MUST be an HTTP request using the GET method and the https scheme to a resolved federation API endpoint with the following query string parameters:
The following is a non-normative example of an API request for trust negotiation:
GET /federation_api_endpoint? operation=listing& iss=https%3A%2F%2Fopenid.sunet.se%2Ffederation HTTP/1.1 Host: openid.sunet.se
The response MUST contain an JSON list with the known entity identifiers.
The following is a non-normative example of a response:
200 OK Last-Modified: Wed, 22 Jul 2018 19:15:56 GMT Content-Type: application/json [ "https://ntnu.andreas.labs.uninett.no/", "https://blackboard.ntnu.no/openid/callback", "https://serviceprovider.andreas.labs.uninett.no/application17" ]
If the request was malformed, or some error occurred during processing of the request, the following standardized error format should be used regardless of the operation specified.
The HTTP response code MUST be something in 400/500-range, giving an indication of the type of error. The response body MUST be a JSON object containing the claims below and the content type MUST be set to application/json.
The following is a non-normative example of an error response:
400 Bad request Last-Modified: Wed, 22 Jul 2018 19:15:56 GMT Content-Type: application/json { "operation": "fetch", "error": "invalid_request", "error_description": "Required request parameter [iss] was missing." }
An entity (e.g., the Consumer) that wants to establish trust with a remote peer, must have the remote peer's entity identifier and a list of entity identifiers of trust anchors together with the public version of their signing keys. The Consumer will first have to fetch sufficient entity statements to establish at least one chain of trust from the remote peer to one or more of the configured trust anchors. After that the entity MUST validate the trust chains independently, and -- if there are multiple valid trust chains and if the application demands it -- choose one.
Depending on the circumstances, the Consumer may either be handed the remote peer's self-issued entity statement, or it may have to fetch it by itself. If it needs to fetch it, it will use the process described in Section 6.1.1 with both iss and sub set to the entity identifier of the remote peer.
The next step is to iterate through the list of intermediates listed in authority_hints, ignoring the authority hints that end in an unknown trust anchor, requesting an entity statement about the remote peer from each of the intermediates. If the received entity statement contains an authority hint this process is repeated. This time with the iss set to the intermediates entity identifier and the sub to be the iss of the previous query. The Consumer SHOULD NOT attempt to fetch entity statements it already has fetched during this process (loop prevention).
A successful operation will return one or more lists of entity statements. Each of the lists terminating in a self-signed entity statement issued by a trust anchor.
If there is no path from the remote peer to at least one of the trusted trust anchors, then the list will be empty and there is no way of establishing trust in the remote peer's information. How the Consumer deals with this is out of scope for this specification.
As described inSection 2.2, a trust chain consists of an ordered list of entity statements. So whichever way the Consumer has acquired the set of entity statements, it must now verify that it is a proper trust chain using the rules laid out in that section.
To validate the chain, the following must be done:
Verifying the signature is a much more expensive operation then verifying the correctness of the statement and the timestamps. An implementer MAY therefor chose to not verify the signature until all the other checks have been done.
Consumers MAY cache Entity Statements or signature verification results for a given time until they expire Section 7.4.
If multiple valid trust chains are found, the Consumer will need to decide on which one to use.
One simple rule would be to prefer a shorter chain over a longer one.
Consumers MAY follow other rules according to local policy.
Each entity statement in a trust chain is signed and MUST have an expiration time (exp) set. The expiration time of the whole trust chain is set to the minimum value of exp within the chain.
This specification allows for a smooth process of updating metadata and public keys.
As described above inSection 7.4, each trust chain has an expiration time. A consumer of metadata using this specification MUST support refreshing a trust chain when it expires. How often a consumer should re-evaluate the trust chain depends on how quickly the consumer wants to find out that something has changed in the trust chain.
If a leaf entity publishes its public keys in the metadata part using jwks, setting an expiration time on the self-signed entity statement can be used to control how often the receiving entity is fetching an updated version of the public key.
A trust anchor must publish a self-signed entity statement about itself. The trust anchor SHOULD set a reasonable expiration time on that statement, such that the consumers will re-fetch the entity statement at reasonable intervals. If the trust anchor wants to roll over its signing keys it would have to:
It must be taken into consideration that clients may have manually configured pubic keys as part of their configuration.
Since the consumers are expected to check the trust chain at regular, reasonably frequent times, this specification does not specify a standard revocation process. Specific federations may make a different choice and will then have to add such a process.
This section describes how the trust framework in this specification is used to establish trust between an RP and an OP that have no explicit configuration or registration in advance.
There are two alternative approaches to establish trust between an RP and an OP, which we call automatic and explicit registration. Members of a federation or a community should agree upon which one to use. While implementations should support both methods, deployments may choose to disable the use of one of them.
Independent of whether the RP uses automatic or explicit registration, the way that the RP learns about the OP is the same. It will use the procedure that is described in Section 7.
Automatic registration allows an RP to send authorization requests to an OP without first registering with the OP. It basically works by the OP using the client_id in the request to find the RP's metadata using the process outlined in Section 7 and then verifies that the RP is in control of a private key that is a companion to one of the public keys the RP published through its metadata.
For automatic registration to work a number of things must be valid:
The authentication request is performed by passing a request object by value as described in section 6.1 in OpenID Connect Core 1.0 or using pushed authorization as described in Pushed Authorization Requests.
In the case where a request object is used the value of the request parameter is a JWT whose Claims are the request parameters specified in Section 3.1.2 in OpenID Connect Core 1.0. The JWT MUST be signed and MAY be encrypted. The following restrictions applies to the JWT:
The following is a non-normative example of the Claims in a Request Object before base64url encoding and signing:
{ "aud": "https://op.example.org/authorization", "client_id": "https://rp.example.com", "exp": 1589699162, "iat": 1589699102, "iss": "https://rp.example.com", "jti": "4d3ec0f81f134ee9a97e0449be6d32be", "nonce": "4LX0mFMxdBjkGmtx7a8WIOnB", "redirect_uri": "https://rp.example.com/authz_cb", "response_type": "code", "scope": "openid profile email address phone", "state": "YmX8PM9I7WbNoMnnieKKBiptVW0sP2OZ", "sub": "https://rp.example.com" }
The following is a non-normative example of an Authorization Request using the request parameter (with line wraps within values for display purposes only):
https://server.example.com/authorize? redirect_uri=https%3A%2F%2Frp.example.com%2Fauthz_cb &scope=openid+profile+email+address+phone &response_type=code &client_id=https%3A%2F%2Frp.example.com &request=eyJhbGciOiJSUzI1NiIsImtpZCI6ImRVTjJhMDF3Umtoa1 NXcGxRVGh2Y1ZCSU5VSXdUVWRPVUZVMlRtVnJTbWhFUVhnelpYbHB UemRRTkEifQ.eyJzdWIiOiAiaHR0cHM6Ly9ycC5leGFtcGxlLmNvb SIsICJpc3MiOiAiaHR0cHM6Ly9ycC5leGFtcGxlLmNvbSIsICJpYX QiOiAxNTkzNjE1Nzk0LCAiZXhwIjogMTU5MzYxNTg1NCwgImF1ZCI 6ICJodHRwczovL29wLmV4YW1wbGUub3JnL2F1dGhvcml6YXRpb24i LCAianRpIjogIjlhNDY2Njc3ZDZkOTQ5OWZiOTFjNDg4YTY1NzA0N TU2In0.mFq0V4KIb6eM-WV5vvQAvSSwoUyi-cy_ASMDgR1-amotjK 6El0T1WV9-Hdrkgi_zBJtARs6VE380GmwpXXuMF1p6y-IoyIBJUSR w9LaeK9oi3d1stTT_J6VL8JwsNuetB6r9YLAQS-1p6mFKsv7TQSjk xNHfw0BTxfZftcDnooCqusC17xrz11qEY1CCtjDbbxYM1cYfzGFwS I0UZneQUZqa2ChOqWTguumG7XonB5NFZWieAtvyyPZaSI7AW5wCs2 sH6kjMxOHEAIvxygZZwKpTiToccYtU7t0n2xKRr-oYDQaFjuRIemE xsuzVl6pbvCVYqyjxFscS9NgDB-hAAQ
When the OP receives an incoming authentication request, the OP supports OpenID Connect Federation, the incoming client_id is a valid URL and the OP does not have the client_id registered as a known client then the OP should try to resolve and fetch trust chains starting with the RP's entity statement as described in Section 7.1.
The OP MUST then validate the possible trust chains, as described in Section 7.2, and resolve the RP metadata with type openid_relying_party.
The OP furthermore should consider the resolved metadata of the RP, and verify that it complies with the client metadata specification in OpenID Connect Dynamic Client Registration 1.0.
Once the OP has the RP's metadata, it can verify that the client was actually the one sending the authorization request by verifying the signature of the request object using the key material the client published through its metadata.
Pushed Authorization provides an interoperable way to push the payload of a request object directly to the AS in exchange for a request_uri.
When it comes to client authentication the applicable authentication methods are three:
Using the example above a request could look like this:
POST /par HTTP/1.1 Host: op.example.org Content-Type: application/x-www-form-urlencoded redirect_uri=https%3A%2F%2Frp.example.com%2Fauthz_cb &scope=openid+profile+email+address+phone &response_type=code &nonce=4LX0mFMxdBjkGmtx7a8WIOnB &state=YmX8PM9I7WbNoMnnieKKBiptVW0sP2OZ &client_id=https%3A%2F%2Frp.example.com &client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3A client-assertion-type%3Ajwt-bearer &client_assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6ImRVTjJ hMDF3Umtoa1NXcGxRVGh2Y1ZCSU5VSXdUVWRPVUZVMlRtVnJTbW hFUVhnelpYbHBUemRRTkEifQ.eyJzdWIiOiAiaHR0cHM6Ly9ycC 5leGFtcGxlLmNvbSIsICJpc3MiOiAiaHR0cHM6Ly9ycC5leGFtc GxlLmNvbSIsICJpYXQiOiAxNTg5NzA0NzAxLCAiZXhwIjogMTU4 OTcwNDc2MSwgImF1ZCI6ICJodHRwczovL29wLmV4YW1wbGUub3J nL2F1dGhvcml6YXRpb24iLCAianRpIjogIjM5ZDVhZTU1MmQ5Yz Q4ZjBiOTEyZGM1NTY4ZWQ1MGQ2In0.oUt9Knx_lxb4V2S0tyNFH CNZeP7sImBy5XDsFxv1cUpGkAojNXSy2dnU5HEzscMgNW4wguz6 KDkC01aq5OfN04SuVItS66bsx0h4Gs7grKAp_51bClzreBVzU4g _-dFTgF15T9VLIgM_juFNPA_g4Lx7Eb5r37rWTUrzXdmfxeou0X FC2p9BIqItU3m9gmH0ojdBCUX5Up0iDsys6_npYomqitAcvaBRD PiuUBa5Iar9HVR-H7FMAr7aq7s-dH5gx2CHIfM3-qlc2-_Apsy0 BrQl6VePR6j-3q6JCWvNw7l4_F2UpHeanHb31fLKQbK-1yoXDNz DwA7B0ZqmuSmMFQ
There are three different paths the OP must follow when processing the authentication request depending on which client authentication method that was used. It all starts the same though. When the OP receives an incoming authentication request, the OP supports OpenID Connect Federation, the incoming client_id is a valid URL, the OP does not have the client_id registered as a known client and the OP supports the client authentication method used then the OP should try to resolve and fetch trust chains starting with the RP's entity statement as described in Section 7.1.
The OP should validate the possible trust chains, as described in Section 7.2, and resolve the RP metadata with type openid_relying_party.
The OP should consider the resolved metadata of the RP, and verify that it complies with the client metadata specification in OpenID Connect Dynamic Client Registration 1.0.
Once the OP has the RP's metadata, it can verify the client authentication. This is where it diverges depending on which client auhentication method was used.
If the OP fails to establish trust with the RP, it should use an appropriate error code, and an error_description that aids the RP to understand what is wrong.
In addition to the error codes defined in Section 3.1.2.6 of OpenID Connect core, this specification also defines the following error codes:
The following is a non-normative example error response:
HTTP/1.1 302 Found Location: https://client.example.org/cb? error=missing_trust_anchor &error_description= Could%20not%20find%20a%20trusted%20anchor &state=af0ifjsldkj
This method involves performing an explicit registration of a new client the first time an RP interacts with an OP using something that basically follows the steps in OpenID Connect Dynamic Client Registration 1.0 but where the client registration request is a signed entity statement.
The OP MUST support OpenID Dynamic Client Registration as extended by this specification. This is signaled by having the claim federation_registration_endpoint in the OP's metadata.
Given that the OP supports explicit registration, the RP progresses as follows:
The trust chains MUST be constructed using the received entity statement.
A client registration using this specification is not expected to be valid forever. The entity statements exchanged all have expiration times, which means that the registration will eventually time out. An OP can also for administrative reasons decide that a client registration is not valid anymore. An example of this could be that the OP leaves the federation in use.
At regular intervals, the RP MUST:
What is regarded as reasonable intervals will depend on federation policies and risk assessment by the maintainer of the RP.
At regular intervals, the OP MUST:
An OP MUST NOT assign an expiration time to an RP's registration that is later than the trust chain's expiration time.
TBD Register federation_types_supported for OP metadata with initial values automatic, explicit.
TBD Register federation_type for RP registration metadata.
TBD Register federation_registration_endpoint for the OP metadata.
TBD
[RFC8446] | Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018. |
Let us assume the following: The project LIGO would like to offer access to its wiki to all OPs in EduGAIN. LIGO is registered to the InCommon federation.
The players
EduGAIN | +------------------+------------------+ | | SWAMID InCommon | | umu.se | | | op.umu.se wiki.ligo.org
Both SWAMID and InCommon are identity federation in their own right. They also have that in common that they both are members of the EduGAIN federation.
SWAMID and InCommon are different in how they register entities. SWAMID registers organizations and lets the organizations register entities that belong to the organization, while InCommon registers all entities directly and not beneath any organization entity. Hence the differences in depth in the federations.
Let us assume a researcher from Umeå University would like to login at the LIGO Wiki. At the Wiki, the researcher will use some kind of discovery service to find the home identity provider (op.umu.se)
Once the RP-part of the Wiki knows which OP it should talk to it has to find out a couple of things about the OP. All if those things can be found in the metadata. But finding the metadata is not enough; the RP also has to trust the metadata.
Let us start with discovering Provider information.
Metadata discovery is a sequence of steps that starts with the RP fetching the self-signed entity statement of the leaf (in this case https://op.umu.se) using the process defined in Section 5. What follows thereafter is this sequence of steps:
How many times this has to be repeated depends on the depth of the federation. What follows below is the result of each step the RP has to do to find the OP's metadata using the federation set up described above.
When building the trust chain, the entity statements issued by a superior about its subordinate is used together with the self-signed entity statement issued by the leaf.
The self-signed entity statement concerning intermediates are not part of the trust chain.
The LIGO WIKI RP fetches the self-signed entity statement from the OP (op.umu.se) using the process defined in Section 5.
The result is this entity statement.
{ "authority_hints": [ "https://umu.se" ], "exp": 1568397247, "iat": 1568310847, "iss": "https://op.umu.se", "jwks": { "keys": [ { "e": "AQAB", "kid": "dEEtRjlzY3djcENuT01wOGxrZlkxb3RIQVJlMTY0...", "kty": "RSA", "n": "x97YKqc9Cs-DNtFrQ7_vhXoH9bwkDWW6En2jJ044yH..." } ] }, "metadata": { "openid_provider": { "issuer": "https://op.umu.se/openid", "jwks_uri": "https://op.umu.se/openid/jwks_uri.json", "authorization_endpoint": "https://op.umu.se/openid/authorization", "client_registration_type": [ "automatic", "explicit" ], "grant_types_supported": [ "authorization_code", "implicit", "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "id_token_signing_alg_values_supported": [ "ES256", "RS256" ], "logo_uri": "https://www.umu.se/img/umu-logo-left-neg-SE.svg", "op_policy_uri": "https://www.umu.se/en/website/legal-information/", "response_types_supported": [ "code", "code id_token", "token" ], "subject_types_supported": [ "pairwise", "public" ], "token_endpoint": "https://op.umu.se/openid/token", "federation_registration_endpoint": "https://op.umu.se/openid/fedreg", "token_endpoint_auth_methods_supported": [ "client_secret_post", "client_secret_basic", "client_secret_jwt", "private_key_jwt" ] } }, "sub": "https://op.umu.se" }
The authority_hints points to the intermediate https://umu.se. So that is the next step.
This entity statement is the first link in the trust chain.
The LIGO RP fetches the self-signed entity statement from "https://umu.se" using the process defined in Section 5.
The request will look like this:
GET /.well-known/openid-federation HTTP/1.1 Host: umu.se
And the GET will return:
{ "authority_hints": [ "https://swamid.se" ], "exp": 1568397247, "iat": 1568310847, "iss": "https://umu.se", "jwks": { "keys": [ { "e": "AQAB", "kid": "endwNUZrNTJsX2NyQlp4bjhVcTFTTVltR2gxV2RV...", "kty": "RSA", "n": "vXdXzZwQo0hxRSmZEcDIsnpg-CMEkor50SOG-1XUlM..." } ] }, "metadata": { "federation_entity": { "contacts": "ops@umu.se", "federation_api_endpoint": "https://umu.se/oidc/fedapi", "homepage_uri": "https://www.umu.se", "name": "UmU" } }, "sub": "https://umu.se" }
The only piece of information that is used from this entity statement is the federation_api_endpoint, which is used in the next step.
The RP uses the federation API and the "fetch" command as defined in Section 6.1.1 to fetch information about "https://op.umu.se" from the API endpoint published in https://umu.se's configuration.
The request will look like this:
GET /oidc/fedapi?sub=https%3A%2F%2Fop.umu.se& iss=https%3A%2F%2Fumu.se HTTP/1.1 Host: umu.se
and the result is this:
{ "authority_hints": [ "https://swamid.se" ], "exp": 1568397247, "iat": 1568310847, "iss": "https://umu.se", "jwks": { "keys": [ { "e": "AQAB", "kid": "dEEtRjlzY3djcENuT01wOGxrZlkxb3RIQVJlMTY0...", "kty": "RSA", "n": "x97YKqc9Cs-DNtFrQ7_vhXoH9bwkDWW6En2jJ044yH..." } ] }, "metadata_policy": { "openid_provider": { "contacts": { "add": [ "ops@swamid.se" ] }, "organization_name": { "value": "University of Ume\u00e5" }, "subject_types_supported": { "value": [ "pairwise" ] }, "token_endpoint_auth_methods_supported": { "default": [ "private_key_jwt" ], "subset_of": [ "private_key_jwt", "client_secret_jwt" ], "superset_of": [ "private_key_jwt" ] } } }, "sub": "https://op.umu.se" }
This is the second link in the trust chain.
Notable here is that this path leads to two trust anchors using the same next step ("https://swamid.se").
The LIGO Wiki RP fetches the self-signed entity statement from "https://swamid.se" using the process defined in Section 5.
The request will look like this:
GET /.well-known/openid-federation HTTP/1.1 Host: swamid.se
And the GET will return:
{ "authority_hints": [ "https://edugain.geant.org" ], "exp": 1568397247, "iat": 1568310847, "iss": "https://swamid.se", "jwks": { "keys": [ { "e": "AQAB", "kid": "N1pQTzFxUXZ1RXVsUkVuMG5uMnVDSURGRVdhUzdO...", "kty": "RSA", "n": "3EQc6cR_GSBq9km9-WCHY_lWJZWkcn0M05TGtH6D9S..." } ] }, "metadata": { "federation_entity": { "contacts": "ops@swamid.se", "federation_api_endpoint": "https://swamid.sunet.se/fedapi", "homepage_uri": "https://www.sunet.se/swamid/", "name": "SWAMID" } }, "sub": "https://swamid.se" }
The only piece of information that is used from this entity statement is the federation_api_endpoint, which is used in the next step.
The LIGO Wiki RP uses the federation API and the "fetch" command as defined in Section 6.1.1 to fetch information about "https://umu.se" from the API endpoint published in https://swamid.se's configuration.
The request will look like this:
GET /fedapi?sub=https%3A%2F%2Fumu.se& iss=https%3A%2F%2Fswamid.se HTTP/1.1 Host: swamid.se
and the result is this:
{ "authority_hints": [ "https://edugain.geant.org" ], "exp": 1568397247, "iat": 1568310847, "iss": "https://swamid.se", "jwks": { "keys": [ { "e": "AQAB", "kid": "endwNUZrNTJsX2NyQlp4bjhVcTFTTVltR2gxV2RV...", "kty": "RSA", "n": "vXdXzZwQo0hxRSmZEcDIsnpg-CMEkor50SOG-1XUlM..." } ] }, "metadata_policy": { "openid_provider": { "id_token_signing_alg_values_supported": { "subset_of": [ "RS256", "ES256", "ES384", "ES512" ] }, "token_endpoint_auth_methods_supported": { "subset_of": [ "client_secret_jwt", "private_key_jwt" ] }, "userinfo_signing_alg_values_supported": { "subset_of": [ "ES256", "ES384", "ES512" ] } } }, "sub": "https://umu.se" }
This is the third link in the trust chain.
If we assume that the issuer of this entity statement is not in the list of trust anchors the LIGO Wiki RP has access to we have to go one step further.
RP fetches the self-signed entity statement from "https://edugain.geant.org" using the process defined in Section 5.
The request will look like this:
GET /.well-known/openid-federation HTTP/1.1 Host: edugain.geant.org
And the GET will return:
{ "exp": 1568397247, "iat": 1568310847, "iss": "https://edugain.geant.org", "jwks": { "keys": [ { "e": "AQAB", "kid": "Sl9DcjFxR3hrRGdabUNIR21KT3dvdWMyc2VUM2Fr...", "kty": "RSA", "n": "xKlwocDXUw-mrvDSO4oRrTRrVuTwotoBFpozvlq-1q..." } ] }, "metadata": { "federation_entity": { "federation_api_endpoint": "https://geant.org/edugain/api" } }, "sub": "https://edugain.geant.org" }
Again, the only thing we need is the federation_api_endpoint. As described in Section 8.2, note should also be taken to jwks as the trust anchor may be performing a key rollover.
The LIGO Wiki RP uses the federation API and the "fetch" command as defined in Section 6.1.1 to fetch information about "https://swamid.se" from the API endpoint published in https://edugain.geant.org's configuration.
The request will look like this:
GET /edugain/api?sub=https%3A%2F%2Fswamid.se& iss=https%3A%2F%2Fedugain.geant.org HTTP/1.1 Host: geant.org
and the result is this:
{ "exp": 1568397247, "iat": 1568310847, "iss": "https://edugain.geant.org", "jwks": { "keys": [ { "e": "AQAB", "kid": "N1pQTzFxUXZ1RXVsUkVuMG5uMnVDSURGRVdhUzdO...", "kty": "RSA", "n": "3EQc6cR_GSBq9km9-WCHY_lWJZWkcn0M05TGtH6D9S..." } ] }, "metadata_policy": { "openid_provider": { "contacts": { "add": "ops@edugain.geant.org" } }, "openid_relying_part": { "contacts": { "add": "ops@edugain.geant.org" } } }, "sub": "https://swamid.se" }
If we assume that the issuer of this statement appears in the list of trust anchors the LIGO Wiki RP has access to this would be the fourth and final entity statement in the trust chain.
We now have the whole chain from the self-signed entity statement of the leaf up until the last one which is issued by a trust anchor. All in all, we have:
We also have the self-signed entity statements from https://umu.se, https://swamid.se and https://edugain.geant.org about themselves but those are not used in the trust chain verification.
Using the public keys of the trust anchor that the LIGO Wiki RP has been provided with in some secure out-of-band way, it can now verify the trust chain as described in Section 7.2.
Having verified the chain, the LIGO Wiki RP can proceed with the next step.
Combining the metadata policies from the tree entity statements we have, by a superior about its subordinate, and applying the combined policy to the metadata statement that the leaf entity presented, we get:
{ "authorization_endpoint": "https://op.umu.se/openid/authorization", "claims_parameter_supported": false, "contacts": [ "ops@swamid.se" ], "federation_registration_endpoint": "https://op.umu.se/openid/fedreg", "client_registration_type": [ "automatic", "explicit" ], "grant_types_supported": [ "authorization_code", "implicit", "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "id_token_signing_alg_values_supported": [ "RS256", "ES256" ], "issuer": "https://op.umu.se/openid", "jwks_uri": "https://op.umu.se/openid/jwks_uri.json", "logo_uri": "https://www.umu.se/img/umu-logo-left-neg-SE.svg", "organization_name": "University of Ume\u00e5", "op_policy_uri": "https://www.umu.se/en/website/legal-information/", "request_parameter_supported": false, "request_uri_parameter_supported": true, "require_request_uri_registration": true, "response_types_supported": [ "code", "code id_token", "token" ], "subject_types_supported": [ "pairwise" ], "token_endpoint": "https://op.umu.se/openid/token", "token_endpoint_auth_methods_supported": [ "private_key_jwt", "client_secret_jwt" ], "version": "3.0" }
We have now reached the end of the Provider Discovery process.
As described in Section 9, there are two ways which can be used to do client registration:
The LIGO Wiki RP does not do any registration but goes directly to sending an authentication request.
Here is an example of such an authentication request:
GET /authorize? request=eyJhbGciOiJSUzI1NiIsImtpZCI6ImRVTjJhMDF3Umtoa1NXc GxRVGh2Y1ZCSU5VSXdUVWRPVUZVMlRtVnJTbWhFUVhnelpYbHBUemRR TkEifQ.eyJyZXNwb25zZV90eXBlIjogImNvZGUiLCAic2NvcGUiOiAi b3BlbmlkIHByb2ZpbGUgZW1haWwiLCAiY2xpZW50X2lkIjogImh0dHB zOi8vd2lraS5saWdvLm9yZyIsICJzdGF0ZSI6ICIyZmY3ZTU4OS0zOD Q4LTQ2ZGEtYTNkMi05NDllMTIzNWU2NzEiLCAibm9uY2UiOiAiZjU4M WExODYtYWNhNC00NmIzLTk0ZmMtODA0ODQwODNlYjJjIiwgInJlZGly ZWN0X3VyaSI6ICJodHRwczovL3dpa2kubGlnby5vcmcvb3BlbmlkL2N hbGxiYWNrIiwgImlzcyI6ICIiLCAiaWF0IjogMTU5MzU4ODA4NSwgIm F1ZCI6ICJodHRwczovL29wLnVtdS5zZSJ9.cRwSFNcDx6VsacAQDcIx 5OAt_Pj30I_uUKRh04N4QJd6MZ0f50sETRv8uspSt9fMa-5yV3uzthX _v8OtQrV33gW1vzgOSRCdHgeCN40StbzjFk102seDwtU_Uzrcsy7KrX YSBp8U0dBDjuxC6h18L8ExjeR-NFjcrhy0wwua7Tnb4QqtN0QCia6DD 8QBNVTL1Ga0YPmMdT25wS26wug23IgpbZB20VUosmMGgGtS5yCI5AwK Bhozv-oBH5KxxHzH1Oss-RkIGiQnjRnaWwEOTITmfZWra1eHP254wFF 2se-EnWtz1q2XwsD9NSsOEJwWJPirPPJaKso8ng6qrrOSgw &response_type=code &client_id=https%3A%2F%2Fwiki.ligo.org &redirect_uri=https%3A%2F%2Fwiki.ligo.org/openid/callback &scope=openid+profile+email HTTP/1.1 Host: op.umu.se
The OP receiving this authentication request will, unless the RP is already registered, start to dynamically fetch and establish trust with the RP.
The OP needs to establish a trust chain for the RP (wiki.ligo.org). The OP in this example are configured with public key of 2 federations:
The OP starts to resolve metadata for the client identifier https://wiki.ligo.org by fetching the self-issued entity statement using the process described in Section 5.
The process is the same as described in Appendix A.1 and will result in a trust chain with the following entity statements:
Using the public keys of the trust anchor that the LIGO Wiki RP has been provided with in some secure out-of-band way, it can now verify the trust chain as described in Section 7.2.
"metadata_policy": { "openid_provider": { "contacts": { "add": "ops@edugain.geant.org" } }, "openid_relying_party": { "contacts": { "add": "ops@edugain.geant.org" } } }
"metadata_policy": { "openid_relying_party": { "application_type": { "one_of": [ "web", "native" ] }, "contacts": { "add": "ops@incommon.org" }, "grant_types": { "subset_of": [ "authorization_code", "refresh_token" ] } } }
We will not list the complete entity statements but only the metadata and metadata_policy parts. There are two metadata policies:
If you combine these and apply them to the metadata for wiki.ligo.org :
"metadata": { "application_type": "web", "client_name": "LIGO Wiki", "contacts": [ "ops@ligo.org" ], "grant_types": [ "authorization_code", "refresh_token" ], "id_token_signing_alg_values_supported": [ "RS256", "RS512" ], "jwks_uri": "https://wiki.ligo.org/jwks.json", "redirect_uris": [ "https://wiki.ligo.org/callback" ], "response_types": [ "code" ], "subject_type": "public" }
You will get
{ "application_type": "web", "client_name": "LIGO Wiki", "contacts": [ "ops@ligo.org", "ops@edugain.geant.org", "ops@incommon.org" ], "grant_types": [ "refresh_token", "authorization_code" ], "id_token_signing_alg_values_supported": [ "RS256", "RS512" ], "jwks_uri": "https://wiki.ligo.org/jwks.json", "redirect_uris": [ "https://wiki.ligo.org/callback" ], "response_types": [ "code" ], "subject_type": "public" }
Having that, the "registration" is done, and the OP must now use the keys found at the URL specified in jwks_uri to verify the signature on the request object in the authentication request.
Here the LIGO Wiki RP sends a client registration request to the federation_registration_endpoint of the OP (op.umu.se). What it sends is a self-signed entity statement.
Once the OP has the entity statement, it proceeds with the same sequence of steps as laid out in Appendix A.1.
The OP will end up with the same RP metadata as was described in Appendix A.2.1.2, but what it now can do is return a metadata policy that it wants to be applied to the RP's metadata. This metadata policy will be combined with the trust chain's combined metadata policy before being applied to the RP's metadata.
If we assume that the OP does not support refresh tokens, it may want to add a metadata policy that says:
"metadata_policy": { "openid_relying_party": { "grant_types": { "subset_of": [ "authorization_code" ] } } }
In which case the metadata used by the RP should be described like this:
{ "application_type": "web", "client_name": "LIGO Wiki", "contacts": [ "ops@edugain.geant.org", "ops@incommon.org", "ops@ligo.org" ], "grant_types": [ "authorization_code" ], "id_token_signing_alg_values_supported": [ "RS256", "RS512" ], "jwks_uri": "https://wiki.ligo.org/jwks.json", "redirect_uris": [ "https://wiki.ligo.org/callback" ], "response_types": [ "code" ], "subject_type": "public" }
Copyright (c) 2020 The OpenID Foundation.
The OpenID Foundation (OIDF) grants to any Contributor, developer, implementer, or other interested party a non-exclusive, royalty free, worldwide copyright license to reproduce, prepare derivative works from, distribute, perform and display, this Implementers Draft or Final Specification solely for the purposes of (i) developing specifications, and (ii) implementing Implementers Drafts and Final Specifications based on such documents, provided that attribution be made to the OIDF as the source of the material, but that such attribution does not indicate an endorsement by the OIDF.
The technology described in this specification was made available from contributions from various sources, including members of the OpenID Foundation and others. Although the OpenID Foundation has taken steps to help ensure that the technology is available for distribution, it takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this specification or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any independent effort to identify any such rights. The OpenID Foundation and the contributors to this specification make no (and hereby expressly disclaim any) warranties (express, implied, or otherwise), including implied warranties of merchantability, non-infringement, fitness for a particular purpose, or title, related to this specification, and the entire risk as to implementing this specification is assumed by the implementer. The OpenID Intellectual Property Rights policy requires contributors to offer a patent promise not to assert certain patent claims against other contributors and against implementers. The OpenID Foundation invites any interested party to bring to its attention any copyrights, patents, patent applications, or other proprietary rights that may cover technology that may be required to practice this specification.
The authors wish to acknowledge the contributions of the following individuals and organizations to this specification: Vladimir Dzhuvinov, Heather Flanagan, Jouke Roorda, Misha Salle, Marcos Sanz, Peter Schober, Michael Schwartz, and the JRA3T3 task force of GEANT4-2.
The following open issues remain to be addressed in this specification.
[[ To be removed from the final specification ]]
-13
-12
-11
-10
-09
-08
-07
-06
-05
-04