R. Hedberg, Ed.
independent
A. Solberg
Uninett
S. Gulliksson
Schibsted
M. Jones
Microsoft
J. Bradley
Ping Identity
October 18, 2018

OpenID Connect Federation 1.0 - draft 05
openid-connect-federation-1_0

Abstract

The OpenID Connect standard specifies how a Relying Party (RP) can discover metadata about an OpenID Provider (OP), and then register to obtain relying party 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 from resolving trust from a common trusted third party.

While this specification is primarily targeting OpenID Connect, it is designed in order to allow for re-use by other protocols and in other use cases.


Table of Contents

1. Introduction

This specification describes how two entities that would like to interact can dynamically fetch and and resolve trust and metadata for a given protocol, by the use of third party trust issuers.

An identity federation can be realized using this specification by the use of one or more levels of trust issuers. A trust issuer is an entity, which main purpose is to issue trust statements about entities, such as OpenID relying party and providers. This specification does not mandates 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 a dynamic and distributed trust network such as a federation.

An entity will typically configure a local trust root to include the identifier and the certificate of a the trusted third party – the federation. All entities involved in OpenID Connect Federation, including the trust issuers, will have their own unique identifier. This identifier is used to dynamically fetch entity statements. As a complete chain of entity statements is obtained, connecting the local trust root to the target entity, the entity may resolve the resulting trusted metadata, by flattening the metadata found in the trust chain.

Note that a real-world entity like an organisation, a company may be represented by more than one entity in a federation.

The OpenID Connect Federation trust chains are relying on cryptographically signed JWT documents, and the trust chain does not at all rely on TLS in order to establish trust.

OpenID Connect Federation may very well be used for other purposes than building traditional identity federations. One of them could be to build an OpenID Connect deployment where the key rollover process does not fall back to TLS. Another could be allowing traditionally public/native clients, such as medical devices, to generate its own key pair, and use asymmetric crypto to increase the overall security.

1.1. Requirements Language

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.

2. Entity Statement

An entity statement is always a signed JWT. An entity statement is issued by the iss, and the statement considers the subject entity, the sub. To be able to resolve trust and metadata, one needs to know the identifier of the target entity – we refer to this as the leaf entity. The leaf entity will always sign a statement about itself, and give some hints to other entities that may want to issue statements about itself. All other entities in a trust chain we refer to as intermediate entities. The local configured trust root, we refer to as the trust anchor.

iss
REQUIRED. The entity identifier of the entity that issues the statement. If the iss and the sub are identical, the issuer is making a statement about itself.
sub
REQUIRED. The entity identifier of the subject
iat
REQUIRED. The time the statement was issued.
exp
REQUIRED. The time the signed statement expires.
jwks
REQUIRED. A JSON Web Key Set (JWKS) representing the public part of the subject entity's signing keys.

These keys are used verify the identity of the subject. A corresponding private key is used by the leaf entity to sign an entity statement about itself, and intermediate entities to sign statements about other entities. The keys that can be found here are primarily intended to sign entity statements, and can not be used in other protocols, unless the metadata type specification explicitly states how the keys can be used. In OpenID Connect, the jwks keys cannot be used within the Authorization/AccessToken/RefreshToken/UserInfo requests and responses. Instead OpenID Connect specific metadata includes claims for this purpose.
authority_hints
OPTIONAL. A JSON object where the keys are the intermediate entities that may issue an entity statement about the issuer entity. The value MUST be a JSON array of entities that is further up in the trust chain. The array may be an empty list. The JSON array can be used to simplify the selection of trust chains without the need for fetching all possible authority hints.
metadata
REQUIRED. JSON object including protocol specific metadata claims that represent the leaf node. To resolve the resulting metadata for a leaf node, the compound metadata documents included in the trust chain is merged by the metadata flattening process. The keys of the JSON object represent the metadata type identifier, and the value MUST be a JSON object representing the metadata according to the metadata schema of that metadata type. To allow for the leaf node to resolve a specific metadata type, all intermediate entities in the trust chain MUST contain a metadata document for this specific type. See section about metadata. An entity statement may contain multiple metadata statement, but only one for each metadata type.
sub_is_leaf
OPTIONAL. Boolean value that indicates whether the subject is considered a leaf node. A leaf node is not trusted to issue statements about other entities then itself. If this property is left out, it is considered to be false.
sub_meta
OPTIONAL. If present, an JSON object containing one or more of the properties listed below. This is metadata describing the subject of this entity statement. The metadata included in the metadata claim is always referring to the leaf nodes, while the metadata in sub_meta refers to the immediate subject, which may be an intermediate trust issuer.

name
OPTIONAL. String. The human readable name describing the subject entity. This may be, for example, the name of an organization.
contacts
OPTIONAL. JSON array with one or more strings. Contact persons at the entity.
policy_url
OPTIONAL. URL to documentation of conditions and policies relevant to this entity
homepage_url
OPTIONAL. URL to a generic home page representing this entity.

The entity statement is signed using the private key of the issuer entity, in the form of a JSON Web Signature (JWS).

Non-normative example of a entity statement, before serialization and adding a signature.

{
  "iss": "https://feide.no",
  "sub": "https://ntnu.no",
  "iat": 1516239022,
  "exp": 1516298022,
  "metadata": {
    "openid_provider": {
      "issuer": "https://ntnu.no",
      "organization": "NTNU",
      "id_token_signing_alg_values_supported": ["RS256", "RS384",
                                                "RS512"]
    },
    "openid_client": {
      "organization": "NTNU",
      "grant_types_supported": ["authorization_code", "implicit"],
      "scopes": ["openid", "profile", "email", "phone"]
    }
  },
  "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": []
  }
}

(postamble)

2.1. The trust anchor

In order to configure trust when deploying a software component, it is recommended to align the configuration with the semantics of a entity statement. How the configuration is stored and the exact format is out of the scope of this specification, but it is recommended to allow the user to configure a list of entries containing sub, jwks and metadata. When the compound metadata from the trust chain is resolved, metadata from the local trust root can be applied in the metadata flattening process. This allows the configuration of a provider to put trust limitations applied to all metadata resolved for the various trust roots. For example, a provider may trust a large federation with a metadata limitation of only releasing the name and userid, and no other scopes or claims. The provider may add other trust roots with a more limited target group to allow for more scopes and claims.

3. Metadata

The OpenID Connect Federations specification does allow new metadata types to be defined, to support use cases outside OpenID Connect. The metadata type identifier will uniquely identify which metadata specification to interpret.

The metadata document MUST be a JSON document. Beyond that there is no restriction.

Metadata used in OpenID Connect Federations typically re-uses existing metadata standards. If needed, the metadata schema is extended with additional properties relevant in a federated context.

3.1. OpenID Connect Relying Party Metadata

The metadata type identifier is openid_client.

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:

allowed_scopes

RECOMMENDED. JSON array containing a list of the RFC6749 scope values that this relying party expects to use.
allowed_claims

RECOMMENDED. JSON array containing a list of the Claim Names of the Claims that the OpenID Client wants values for.

3.2. OpenID Provider Metadata

The metadata type identifier is an openid_provider.

All parameters defined in section 3 of OpenID Connect Discovery 1.0

In addition the following properties are allowed:

organizationName

OPTIONAL. A human readable name representing the organization owning the OpenID Provider. It is intended to be used in the user interface, being recognized by the end users that would be using the provider to authenticate.

3.3. OpenID Connect Discovery

The metadata type identifier is openid-discovery.

3.4. OAuth Provider

The metadata type identifier is openid-provider.

3.5. OAuth Client

The metadata type identifier is openid_client.

3.6. OAuth Protected Resources

The metadata type identifier is openid-api.

4. The Federation API

Given the entity identifier, the endpoint of the federation API endpoint of the entity is easily derived. All entities that are expected to expose entity statements about themselves or other entities, MUST implement a Federation API.

The federation API endpoint of an entity, is resolved from the entity identifier. The Federation API 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.

The Federation API is an HTTP API that may support multiple operations. Fetching entities is one of the operations, and the only one that all entities is REQUIRED to support. All the other operations is OPTIONAL. The op (operation) parameter may be used to defined new operations in a future version of the specification or a local deployment which have agreed upon additional functionality.

While all operations in the specification make use of a GET request, other operations may choose to use other HTTP methods. If the op parameter is left out, it is considered to be a fetch entity statements request. Unless otherwise mentioned or agreed upon, requests to the federation API does not need to be authenticated.

4.1. Fetching entity statements (REQUIRED)

Fetching entity statements is used to collect entity statements and a valid trust chain in order to establish trust with a remote peer.

In order to fetch entity statements, you need to know the identifier of the entity to ask, and the identifier of the entity that you want the statement to be about. Typically the first entity statement to fetch is the remote peer self issued entity statement.

4.1.1. Fetch Entity Statements Request

The request MUST be a HTTP request using the GET method to a resolved federation API endpoint with the following query string parameters:

op
OPTIONAL. If not present MUST be set to fetch.
iss
REQUIRED. The entity identifier of the issuer from which you want an entity statement issued. Because of the normalization of the URL, multiple issuers may resolve to a shared federation API. This parameter makes it explicit exactly which issuer we want entity statements from.
sub
OPTIONAL. The entity identifier of the subject for which you would like an entity statement issued. If this parameter is left out, it is considered to be the same as the issuer, and would indicate a request for a self issued statement.
aud
OPTIONAL. The entity identifier of the requester. The issuing entity may choose to include this parameter to form the entity statement specifically for this target, in which the aud claim also should be present in the entity statement it self.
prefetch
OPTIONAL. If left out, it is assumed to be false. If set to true, it indicates that the requester would like the API to prefetch entity statements that may be relevant for consumer to establish a trust chain, and may save the consumer from performing additional API requests.

The following is a non-normative example of an API request for entity statement:

GET /.well-known/openid-federation?
iss=https%3A%2F%2Fopenid.sunet.se%2Ffederation HTTP/1.1
Host: openid.sunet.se

(postamble)

4.1.2. Fetch Entity Statements Response

As long as the request is correct, understood and accepted, the response MUST be a JSON array including signed entity statements. The content type MUST be set to application/json. If the issuing entity does not recognize the subject or the issuer, it should return an empty JSON array. The returned list of entity statements SHOULD include a statement issued by the issuing entity about the entity represented in the subject parameter. The issuing entity may also decide to prefetch additional entity statements that may be relevant to the requester.

A non-normative example of a response:

200 OK
Last-Modified: Wed, 22 Jul 2018 19:15:56 GMT
Content-Type: application/json

["eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJodHRwczovL3Nlc..."]

(the signed JWT is truncated)

4.2. Trust negotiation (OPTIONAL)

An entity may use the trust negotiation operation in order to fetch a resolved metadata of it self as seen/trusted by a remote peer. The remote peer will fetch the metadata and necessary trust chain to the requester, and perform metadata flattening. The remote peer should include it own trust root configuration when generating the resulting metadata. The metadata returned should be the same as the one used in the software.

4.2.1. Trust negotiation Request

Resolving metadata for a specific type of metadata, for a given peer. The relying party may ask a specific provider to resolve the relying party openid_client metadata with its own configured trust root. The result may tell what operations, scopes and claims the relying party is allowed to use.

op
REQUIRED. MUST be set to resolve_metadata.
iss
REQUIRED. The entity identifier of the issuer from which you want to resolve metadata. Because of the normalization of the URL, multiple issuers may resolve to a shared federation API. This parameter makes it explicit exactly which issuer we want to interact with.
peer
REQUIRED. The entity identifier of the entity the information is required for.
type
REQUIRED. The metadata type to resolve. In this document we use the metadata types, openid_client and openid_provider.

The following is a non-normative example of an API request for trust negotiation:

GET /.well-known/openid-federation?
op=resolve_metadata&
iss=https%3A%2F%2Fopenid.sunet.se%2Ffederation&
type=openid_provider&
peer=https%3A%2F%2Fidp.umu.se%2Fopenid HTTP/1.1
Host: openid.sunet.se

4.2.2. Trust negotiation Response

The response is a generated flattened metadata of the type specified in the request.

A non-normative example of a response:

200 OK
Last-Modified: Wed, 22 Jul 2018 19:15:56 GMT
Content-Type: application/json

{
  "organization": "University of Ume?",
  "contacts": ["legal@umu.se", "technical@umu.se"],
  "logo_uri":
    "https://www.umu.se/SRWStatic/img/umu-logo-left-neg-SE.svg",
  "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"],
  "LoaMax": "http://swamid.se/LoA/substantial",
  "expires": 8776635
}

4.3. Entity listings (OPTIONAL)

An entity may query another entity for a list of all entities that that entity is prepared to issue statements about.

4.3.1. Entity Listings Request

The following request parameters are allowed in the query part:

op
REQUIRED. MUST be set to listing.
iss
REQUIRED. The entity identifier of the issuer from which you want to resolve metadata. Because of the normalization of the URL, multiple issuers may resolve to a shared federation API. This parameter makes it explicit exactly which issuer we want to interact with.
type
OPTIONAL. Provide this parameter to filter the results to entity statements that contain entries for this specific metadata type.
sub_is_leaf
OPTIONAL. If left out, result should include both leaf nodes and intermediate nodes. If set to true , the response should contain only leaf nodes. If set to false, the response should contain only intermediate nodes.
claims
OPTIONAL. A comma separated list of claim names that the requester would like to get for each entity. If left out or an empty string, the response should contain an empty object for each of the known entities.

4.3.2. Entity Listing Response

The response MUST contain an JSON object where the known entity identifiers are the property keys, and a JSON object with the requested claims is the property value. Requested claims that the responder is not able to provide should be left out.

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/": {
    "client_name": "NTNU Labs"
  },
  "https://blackboard.ntnu.no/openid/callback": {
    "client_name": "Blackboard"
  },
  "https://serviceprovider.andreas.labs.uninett.no/application007": {
    "client_name": "Test application"
  }
}

4.4. Force refreshing of entity statements

TBD.

4.5. Generic Error Response

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 else than 200, giving an indication of the type of error. The response body MUST be a JSON object including these claims:

op
REQUIRED. Which operation was the request processed as.
error
REQUIRED. The error code.
error_description
REQUIRED. A human readable short text describing the error.

A non-normative example of a error response:

400 Bad request
Last-Modified: Wed, 22 Jul 2018 19:15:56 GMT
Content-Type: application/json

{
  "op": "fetch",
  "error": "generic_error",
  "error_description":
    "Required request parameter [iss] was missing."
}

5. Resolving trust chain and metadata

An entity seeking to establish trust with a remote peer will start with the knowledge of the remote peer entity identifier and with a locally configured trust anchor. The entity will first have to fetch sufficient entity statements to establish a chain of trust from the remote peer to the locally configured trust anchor. Afterwards, the seeking entity will have to validate the trust chain and choose one if there are multiple valid trust chains.

5.1. Fetching entity statements to establish a trust chain

The seeking entity should always start to ask the remote peer entity about its self-issued entity statement. This entity statement MAY contain an list of intermediate entities in the authority_hints claim.

The seeking entity may iterate through the list of authority_hints and request an entity statement on the remote peer from each of the intermediates. It may further iterate intermediate entity statements for their authority_hints, and so on. The seeking entity should never attempt to fetch entity statements that it has already fetched in this process (loop prevention).

The result of this operation should be a number of flat lists of entity statements.

5.2. Finding trust chains

The seeking entity will look for paths from the remote peer entity to the locally configured trust anchors. If no path is found, the process of establishing trust has failed. The result may also very well be more than one possible path.

5.3. Validating the trust chains

A trust chain consists of an ordered list of entity statements that refer to each other from one entry in the local trust anchor to the self-issued entity statement of the remote peer.

We refer to the locally configured trust root as ES0, the top level intermediate entity statement as ES1, up to the self signed entity statement ESi. A trust chain without any intermediate entities is also valid. The trust anchor might include a ES0 representing a direct trust to a remote peer, and the self-issued statement of the peer will then be ES1.

To validate the chain, the signed JWT ES1 is validated against the public signing keys in ES0, jwks. Next, the signed JWT ES2 is validated against the public signing keys in ES1, and so on until the complete chain is validated.

5.4. Choosing one of the valid trust chains

If multiple valid trust chain is found, the seeking entity will need to decide

5.5. Calculating the lifetime of a trust chain

Each entity statement in a trust chain is signed and MUST have a expiration time (exp) set. Given that all of them are sometime in the future then the expiration time of the whole trust chain is then the expiration time that is closest in time to the present time.

6. Updating metadata, key-rollover and revocation

The OpenID Connect Federation allows for a smooth process of updating metadata and public keys.

Each entity statement has an explicit expiration time. A trust chain is valid until one or more of the involved entity statements expires. This specification describes how entity statement is fetched and metadata is resolved for the first time, but a consumer of metadata from OpenID Connect Federation MUST support refreshing at least the expired entity statements and re-evaluate the whole trust chain when needed.

Setting an expiration time on an entity statement can be used to control how often the remote party is fetching an updated version of your public key.

6.1. Key-rollover for entity

A leaf node, such as an OpenID Provider will typically have at least two set of key pairs, one that is embedded in the entity statement issued by the superior trust issuer, and one that is embedded in the protocol specific metadata that is included in the self issuer entity statement.

6.1.1. Leaf node key-rollover on keys used in protocol

  1. Generate a new key pair to use (K2) to replace the existing (K1). The lifetime T1 is the time until all previously issued entity statements are expired.
  2. Publish both K1 and K2 in the metadata part of the self issued entity statement. Use K1 to sign outgoing messages. Accept encrypted messages to both K1 and K2. Set K2 to prioritized key. Wait at least T1 before moving to next step.
  3. Remove K1 from the metadata part in the published entity statements. Start signing outgoing messages with K2, accept incoming encrypted messages with both K1 and K2. Wait at least T1.
  4. Only K2 is used and accepted.

The complete time of this key-rollover process is 2x T1.

6.1.2. Key-rollover for entity signing key

Identical to the section above, but the entity statements is issued by the superior party, such that an out of band process for the entity to push its key material to the superior entity MUST be added.

6.2. Key rollover for trust roots

As previous steps.

Take into considerations that clients have manually configured pubic keys as part of configuration.

6.3. Updating metadata

The process of updating its own metadata follows the same procedure as with public keys.

6.4. Revocation

7. Flattening metadata from the chain of entity statements

The metadata for a specific entity can be constructed by starting with the information in ms_0 and then adding the information in ms_1 to ms_n using the following rule:

Given two metadata statements ms_i and ms_j (j > i, i=0, ..., n-1, j=1, ..., n) For every claim in ms_j: If the claim does not appear in ms_i add it to ms_i. If the claim appears in ms_i then replace the value of the claim in ms_i with the value of the claim in ms_j if and only if the value in ms_j is a subset of the value in ms_i else an error MUST be generated.

A subset is defined as:

String

One string is a subset of another string if it is exactly the same, byte by byte.
Simple lists

An array A is a subset of B if every element in A is also in B. And if of the matching elements the one in A is a subset of the one in B.
Booleans

Boolean A is a subset of B if A is equal to B.
Integer/Floats

The number A is a subset of the number B if A is less or equal to B.
Associative array/dictionary

The dictionary A is a subset of the dictionary B if every key in A is in B and the value of A[x] is a subset of B[x].

The following is a non-normative example of a set of relying party-specific metadata statements that together form the metadata for an entity:

ms_0

{
  "contacts": ["helpdesk@example.com"],
  "logo_uri": "https://example.com/logo.jpg",
  "policy_uri": "https://example.com/policy.html",
  "tos_uri": "https://example.com/tos.html"
}
            

ms_1

{
  "rp_scopes": ["openid", "eduperson"],
  "response_types": ["code", "code id_token"],
}
            

ms_2

{
  "contacts": ["rp_helpdesk@example.com"],
  "redirect_uris": ["https://example.com/rp1"],
  "response_types: ["code"]
}            

sum(ms_0...2)

{
  "contacts": ["helpdesk@example.com"],
  "logo_uri": "https://example.com/logo.jpg",
  "policy_uri": "https://example.com/policy.html",
  "tos_uri": "https://example.com/tos.html"
  "rp_scopes": ["openid", "eduperson"],
  "response_types": ["code"],
  "redirect_uris": ["https://example.com/rp1"],
}

8. OpenID Connect Communication

This section describes how the trust framework in this specification is used to establish trust between an OpenID Relying Party and an OpenID Provider that has no explicit configuration or registration in advance. The use of OpenID Connect Federation enables dynamically building large scale multi-lateral federations.

There are two alternative approaches to establish trust between a Relying Party and a Provider. Members of a federation or a community should agree upon which approach to use. Whilst implementations should support both methods, deployments may choose to disable the use of one of them.

8.1. Explicit Registration

This method involves performing an explicit registration of a new client the first time a Relying Party interacts with an OpenID Provider using something akin to OpenID Connect Dynamic Client Registration 1.0.

It is assumed that a federation entity has a set of authority_hints and knowledge about which trust anchor that can be found at the end of a trust chain starting in each authorityHint. How the entity has received this knowledge is outside the scope of this document.

8.1.1. Provider Discovery

The RP will start by figuring out the OPs metadata using the process specified in Resolving trust chain and metadata above.

8.1.2. Client Registration

8.1.2.1. Client Registration Request

The OP MUST support dynamic relying party registration. That it does so is signaled by having the claim federation_registration_endpoint in the metadata.

Given that the OP supports dynamic registration the RP progresses as follows:

  1. Once it has the list of acceptable trust chains for the OP it MUST choose the subset it wants to progress with. The subset can be as small as one trust chain but it can also contain more then one.
  2. Based on the trust anchors referenced in the subset of trust chains, the RP will choose a set of authority_hints from its own set that terminates in those trust anchors.
  3. The RP will now construct a self-signed entity statement where the metadata statement chosen is influenced by the OPs metadata and the authority_hints specified are picked by the process described above.
  4. The entity statement is sent to the federation_registration_endpoint defined in this document.

8.1.2.2. Client Registration Response

Now on the OPs side the following occurs:

Back at the RP it will:

8.1.3. After client registration

A client registration using this specification is not expected to be valid for ever. The entity statements exchanged all have expiration times, which means that the registration will eventually time out. An OP can also for some reason decide that a client registration is not valid anymore. To this can be added that the entities in the federation, for a number of reasons, over time may change how fast their signature will expire, thereby increasing or decreasing the lifetime of a trust chain.

8.1.3.1. What the RP MUST do

At regular intervals the RP MUST:

8.1.3.2. What the OP MUST do

TBD

8.2. Implicit Registration

The trust between the entities is established using the above described extensions in the first two steps of the communication between an RP and an OP. How the RP found the OP in the first place is out of scope for this document.

------                                       ------
|    | <--- 1) Discovery ------------------> |    |
| RP | ---- 2) Authentication request -----> | OP |
|    |                                       |    |
------                                       ------     

After the discovery and registration is completed a first time, those steps SHOULD only be repeated if any changes occur (see notes in respective sections below).

The client_id of the RP MUST be set identical to the RP entity identifier.

Without a registration process, the RP does not have any client_secret. Instead the implicit registration model requires the RP to make use of asymmetric crypto.

The RP MUST host a Federation API that allows the OP to fetch the entity statements.

8.2.1. The Authentication Request

The authentication request as specified in OpenID Connect Core.

8.2.2. Processing the authentication request

When the OP receives an incoming authentication request and both the OP supports OpenID Connect Federation and the incoming client_id is a valid URL, the OP should try to resolve and fetch the entity statement as described in fetching entity statements.

The OP should validate the possible trust chains, and resolve the RP metadata with type openid_client.

The OP should consider the resolved metadata of the RP and perform these additional validation steps:

8.2.3. Authentication Error Response

If the OP fails to establish trust with the RP, it should use the error_description error code, with an error_description that aids the RP to fix what is wrong.

8.2.4. Authentication at the Token endpoint

The RP will have to use asymmetric crypto to authenticate to the token endpoint. The RP MUST authenticate the request by including the private_key_jwt parameter, as described in OpenID Connect Core Section 9.

9. Timeouts

There are a number of timeouts that MUST considered:

Taking this into consideration, an OP MUST NOT assign a lifetime to a relying party registration that exceeds the lifetime of the metadata statement signatures.

10. Acknowledgements

11. IANA Considerations

TBD

12. Security Considerations

TBD

13. Normative References

[OpenID.Core] Sakimura, N., Bradley, J., Jones, M., de Medeiros, B. and C. Mortimore, "OpenID Connect Discovery 1.0", August 2015.
[OpenID.Discovery] Sakimura, N., Bradley, J., Jones, M. and E. Jay, "OpenID Connect Discovery 1.0", August 2015.
[OpenID.Registration] Sakimura, N., Bradley, J. and M. Jones, "OpenID Connect Dynamic Client Registration 1.0", August 2015.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997.
[RFC5785] Nottingham, M. and E. Hammer-Lahav, "Defining Well-Known Uniform Resource Identifiers (URIs)", RFC 5785, DOI 10.17487/RFC5785, April 2010.
[RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, October 2012.
[RFC6962] Laurie, B., Langley, A. and E. Kasper, "Certificate Transparency", RFC 6962, DOI 10.17487/RFC6962, June 2013.
[RFC7033] Jones, P., Salgueiro, G., Jones, M. and J. Smarr, "WebFinger", RFC 7033, DOI 10.17487/RFC7033, September 2013.
[RFC7515] Jones, M., Bradley, J. and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 2015.
[RFC7517] Jones, M., "JSON Web Key (JWK)", RFC 7517, DOI 10.17487/RFC7517, May 2015.

Appendix A. Illustrative example of OpenID Connect flow

A service Foodle would like to offer its services to all identity providers in eduGAIN. Foodle is managed and registered by the university NTNU. NTNU is part of the Norwegian Feide federation. Foodle is also directly trusted in the Swedish SWAMID federation. Both Feide and SWAMID are part of the international eduGAIN federation.

A.1. Initial setup of Foodle

The Foodle service choose to use the entity identifier https://foodl.org/. And upon deployment, Foodle is setup with a RSA key pair, with the following public key:

{
  "kid": "key1",
  "use": "sig",
  "kty": "RSA",
  "alg": "RS256",
  "n": "pnXBOusEANuug6ewezb9J_XbxbSGEISyA75wBGkerPNg6WTXmmxJ-DV1U4sCu
RqhSdo3Uncmw6-01bZKCtAyRHT_TOZN2TMfNPRsfLkOstVofyfxg5oIWViLX9IDG_iZVd
q6_T6yOuufOIvqpaeBMwSKuDXHNa_DU0aUu_3kOAc5_2hD4Dq-XXtum-oix2EPkNSbFfP
qFIp5n4gS1XrzGzuNQiDw82k-H6mWN0wlVWfqLxJA9DZikAX7x9feipn36wxDH-XUlzDD
Ui3nfnC8GSkT-CYII3oZPsIgMV527iQGVsehIV9KqTF2FnaP83cqV9YgvMfhs1wrx4L3Z
-3B8Q",
  "e": "AQAB",
  "key_ops": ["verify"],
  "ext": true
}

Foodle offers a WebFinger interface and a metadata API according to this specification, with the ability to issue entity statements about itself.

A.2. Federation setup

How trust is established and entities becomes part of a federation is out of scope of this specification. But it could involve some kind of non-technical contract, agreement or term of use that is established, followed by a federation or trust issuer that registers an entity identifier, public key and a set of metadata that restricts the delegated trust that is represented in the entity statement about the joining party.

The following example, assumes the following trust relations are established, and the following entities are able to issue entity statements:

Foodle has a local trust root configuration that looks like this (notice that the exact format and content on the trust root configuration is out of scope of this specification):

[
  {
    "sub": "https://www.sunet.se/swamid",
    "sub_meta": {"name": "SWAMID"},
    "metadata": {
      "openid-provider": {
        "loa_max": "http://swamid.se/LoA/substantial"
      }
    },
    "jwks": {
      "keys": [
        {
          "kty": "RSA",
          "alg": "RS256",
          "n": "v6xydqciFKGfvQaqYGmk9A7etbfvNY[...]",
          "e": "AQAB",
          "key_ops": ["verify"],
          "ext": true,
          "kid": "swamid",
          "use": "sig"
        }
      ]
    }
  }
]

A.3. User chooses to login at Foodle

Let us assume a student from Umeå would like to login at Foodle. Some sort of discovery process involves the end user choosing an OpenID provider. OpenID Discovery using the e-mail address is one option. Foodle presenting a list of available providers for the user to choose from is another.

After the discovery process, Foodle knows that the user would like to login using the OpenID provider with entity identifier https://www.umu.se/openid.

A.4. Foodle discovers the OpenID provider

Foodle normalizes the entity identifier of the OpenID Provider, and performs a request to fetch the self-issued entity statement using the Federation API of the OpenID provider.

GET /.well-known/openid-federation?
iss=https%3A%2F%2Fumu.se%2Fopenid HTTP/1.1
Host: umu.se
HTTP/1.1 200 OK
Content-Type: application/json
["eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InVtdSJ9.eyJpYXQi..."]

The API endpoint returns a list of signed entity statements. In this case we look for a self-issued statement from the Umeå university. We then decode and inspect the content:

{
  "iat": 1539174048,
  "exp": 1539177648,
  "metadata": {
    "openid-provider": {
      "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", "public"],
      "id_token_signing_alg_values_supported": ["RS256"],
      "logo_uri":
        "https://www.umu.se/SRWStatic/img/umu-logo-left-neg-SE.svg",
      "policy_uri":
        "https://www.umu.se/en/about-the-website/legal-information/",
      "loa_max": "http://eidas.europa.eu/LoA/high"
    }
  },
  "iss": "https://umu.se/openid",
  "sub": "https://umu.se/openid",
  "authority_hints": {
    "https://www.sunet.se/swamid": ["https://edugain.org/oidc"],
    "https://kalmar2.org/openid": []
  },
  "jwks": {
    "keys": [
      {
        "kty": "RSA",
        "alg": "RS256",
        "n": "z1V1kyi6qwmXfKsfhVqKUMmQH3AixN[...]",
        "e": "AQAB",
        "key_ops": ["verify"],
        "ext": true,
        "kid": "umu",
        "use": "sig"
      }
    ]
  }
}

A.5. Resolving the provider trust chain

In order to establish trust with this provider, the Foodle service provider would need to fetch sufficient entity statements to represent a complete chain from the self-issued statement to the locally configured trust root, which contains SWAMID.

The information found in the authority_hints is critical in order to dynamically discover the trust chain. If such hints are not present, the relying party may resume to fixed configured trust roots to ask for trust statements.

In this example, Foodle now fetches an entity statement from SWAMID using the Federation API endpoint of SWAMID, discovered in the authority_hints claim.

GET /.well-known/openid-federation?
iss=https%3A%2F%2Fwww.sunet.se%2Fswamid&
sub=https%3A%2F%2Fumu.se%2Fopenid HTTP/1.1
Host: www.sunet.se
HTTP/1.1 200 OK
Content-Type: application/json
["eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImZlaWRlIn0.eyJp..."]

The decoded version of the entity statement is:

{
  "iat": 1539174048,
  "exp": 1539177648,
  "metadata": {
    "openid-provider": {
      "subject_types_supported": ["pairwise"],
      "id_token_signing_alg_values_supported": ["RS256", "RS512"],
      "organization": "University of Ume?",
      "contacts": ["legal@umu.se", "technical@umu.se"]
    },
    "openid-client": {}
  },
  "iss": "https://www.sunet.se/swamid",
  "sub": "https://umu.se/openid",
  "sub_meta": {"name": "University of Ume?"},
  "jwks": {
    "keys": [
      {
        "kty": "RSA",
        "alg": "RS256",
        "n": "v6xydqciFKGfvQaqYGmk9A7etbfvNY[...]",
        "e": "AQAB",
        "key_ops": ["verify"],
        "ext": true,
        "kid": "swamid",
        "use": "sig"
      }
    ]
  }
}

Notice that the entity statement about University of Umeå also contains an entry for openid_client metadata. This indicates that SWAMID expresses this university to be trusted to issue its own OpenID clients without the need for registering these directly in SWAMID.

These two entity statements are sufficient to establish a path from the local configured trust anchor which trust SWAMID, to the self-issued statement from the University of Umeå. Here are the steps performed to validate the trust chain:

A.6. Extracting the provider metadata

The output from the trust chain validation is an ordered list of entity statements. In order to extract the needed metadata, we need to look at the metadata type relevant in the given context. In this case, we are establishing trust with an OpenID Provider, and we take a look at the openid_provider metadata object of the trust chain:

[
  {"loa_max": "http://swamid.se/LoA/substantial"},
  {
    "subject_types_supported": ["pairwise"],
    "id_token_signing_alg_values_supported": ["RS256", "RS512"],
    "organization": "University of Ume?",
    "contacts": ["legal@umu.se", "technical@umu.se"]
  },
  {
    "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", "public"],
    "id_token_signing_alg_values_supported": ["RS256"],
    "logo_uri":
      "https://www.umu.se/SRWStatic/img/umu-logo-left-neg-SE.svg",
    "policy_uri":
      "https://www.umu.se/en/about-the-website/legal-information/",
    "loa_max": "http://eidas.europa.eu/LoA/high"
  }
]

The metadata flattening process converts this to a single metadata object. The resulting metadata in this case would be:

{
  "organization": "University of Ume?",
  "contacts": ["legal@umu.se", "technical@umu.se"],
  "logo_uri":
    "https://www.umu.se/SRWStatic/img/umu-logo-left-neg-SE.svg",
  "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"],
  "loa_max": "http://swamid.se/LoA/substantial"
}

A.7. RP sends authentication request (implicit registration)

Foodle after establishing trust with the University of Umeå and extracted a resulting set of metadata, will send an authentication request to the OpenID provider. This example involves the implicit registration.

Here is an example of an authentication request:

GET /authorize?
  response_type=code
  &scope=openid%20profile%20email
  &client_id=https%3A%2F%2Ffoodl.org%2F
  &state=2ff7e589-3848-46da-a3d2-949e1235e671
  &redirect_uri=https%3A%2F%2Ffoodl.org%2Fopenid%2Fcallback HTTP/1.1
Host: idp.umu.se

The provider receiving this authentication request will, unless the RP is cached or statically configured, start to dynamically fetch and establish trust with the RP.

A.8. Provider fetches entity statements

The provider needs to establish a trust chain for the RP from which a authentication was received. The provider in this example has the following configured trust root:

[
  {
    "sub": "https://edugain.org/oidc",
    "metadata": {
      "openid-client": {
        "rp_scopes": ["openid", "userid-targetedid", "eduperson"],
        "response_types": ["code", "code id_token"]
      }
    },
    "jwks": {
      "keys": [
        {
          "kty": "RSA",
          "use": "sig",
          "alg": "RS256",
          "n": "qnd5_krrHKzuJzb5_YEt4sP-YOGSbf[...]",
          "e": "AQAB",
          "key_ops": ["verify"],
          "ext": true,
          "kid": "edugain"
        }
      ]
    }
  },
  {
    "sub": "https://www.sunet.se/swamid",
    "metadata": {
      "openid-client": {
        "rp_scopes": ["openid", "userid-persistent", "fs"],
        "response_types": ["code", "code id_token"]
      }
    },
    "jwks": {
      "keys": [
        {
          "kty": "RSA",
          "alg": "RS256",
          "n": "v6xydqciFKGfvQaqYGmk9A7etbfvNY[...]",
          "e": "AQAB",
          "key_ops": ["verify"],
          "ext": true,
          "kid": "swamid",
          "use": "sig"
        }
      ]
    }
  }
]

A.9. Provider fetches entity statements

The provider starts to resolve metadata for the client identifier https://foodl.org/ by fetching the self-issued entity statement using the Federation API.

uses WebFinger, the metadata API endpoints and the authority_hints in order to establish a full trust chain to the trust root.

In this case there are two possible trust chains:

Appendix B. Notices

Copyright (c) 2018 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.

Appendix C. Document History

[[ To be removed from the final specification ]]

-05

-04

Authors' Addresses

Roland Hedberg (editor) independent EMail: roland@catalogix.se
Andreas Åkre Solberg Uninett AS EMail: andreas.solberg@uninett.no URI: https://www.linkedin.com/in/andreassolberg/
Samuel Gulliksson Schibsted Media Group EMail: samuel.gulliksson@gmail.com
Michael B. Jones Microsoft EMail: mbj@microsoft.com URI: http://self-issued.info/
John Bradley Ping Identity EMail: ve7jtb@ve7jtb.com URI: http://www.thread-safe.com/