R. Hedberg, Ed.
independent
R. Gulliksson
UmU
M. Jones
Microsoft
J. Bradley
Ping Identity
September 9, 2016

OpenID Connect Federation 1.0 - draft 01
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 client credentials. During discovery and registration there is no automated mechanism for the OP or the RP to verify the information exchanged during this process. All the information is self-asserted.

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.

This document describes how an identity federation can be built around a trusted third party, the federation operator.


Table of Contents

1. Introduction

The OpenID Connect specification defines how a Relying Party and an OpenID Connect Provider can exchange information dynamically about each other. This information is necessary for future successful OIDC communication.

One problem with using dynamic discovery and registration is that the correctness of the information that is exchanged can not be easily verified by the recipient since it is self-asserted.

Another problem that has been raised is the dependency on TLS as the sole protection against attacks on the transferred information. These last couple of years a number of problems with OpenSSL, which is probably the most widely used TLS library, has been discovered that puts reasonable doubt into this dependency.

This document extends Signed Metadata, as introduced by OAuth 2.0 Authorization Server Metadata [I-D.draft-ietf-oauth-discovery], to create so called metadata statements. Metadata statements together with the use of a trusted third party (that verifies and enforces some common policy), can be used to transfer verified data and trust in the data between clients and servers.

2. 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 [RFC2119].

3. Metadata Statement

A metadata statement asserts metadata values about an entity (client or server).

3.1. Metadata Common to All Entities

These extra metadata parameters appear in both provider and client metadata statements:

signing_keys

OPTIONAL. A JSON Web Key Set (JWKS) [RFC7517] representing the public part of the entity's signing keys.
signing_keys_uri

OPTIONAL. Location where a JWKS representing the public part of the entity's signing keys can be found. SHOULD return the Content-Type "application/jose" to indicate that the JWKS is in the form of a JSON Web Signature (JWS) [RFC7515] using the JWS Compact Serialization.
metadata_statements

OPTIONAL. JSON array containing a list of metadata statements.
metadata_statement_uris

OPTIONAL. JSON object where the names are the federation identifiers and the values are URLs pointing to metadata statements connected to each federation.
signed_jwks_uri

OPTIONAL. This is the signed version of the jwks_uri parameter defined in OpenID Connect Dynamic Client Registration 1.0 [OpenID.Registration]. SHOULD return the Content-Type "application/jose" to indicate that the JWKS is in the form of a JWS using the JWS Compact Serialization. The key used to sign the JWKS can be found among the keys published in signing_keys or fetched from signing_keys_uri

Metadata statements and signing keys can be transferred in two different ways: either by including the information in the statement, or by providing a URI that points to the information. How metadata statements and signing keys are transferred is independent of each other. It is NOT allowed to divide the information (metadata statements or signing keys) into two pieces and send one in the statement and leave the rest to be fetched using the URI.

Along the same line if both jwks_uri and signed_jwks_uri are present, which they might be for backward compatibility reasons, then signed_jwks_uri SHOULD be preferred.

3.2. Specific Client Metadata

All parameters defined in section 2 of OpenID Connect Dynamic Client Registration 1.0 [OpenID.Registration] are allowed in a metadata statement.

To that list is added:

scopes

RECOMMENDED. JSON array containing a list of the RFC6749 [RFC6749] scope values that this clients expects to use.
claims

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

3.3. Specific Provider Metadata

All parameters defined in section 3 of OpenID Connect Discovery 1.0 [OpenID.Discovery]

3.4. Compounded Metadata Statement

The metadata for each entity in the federation is described by one or more metadata statements (for example, MS0, MS1, ..., MSn). MS0 is the most generic, and MS1-MSn would in turn be successively more specific. To describe an entity belonging to an organization, MS0 would typically contain information that belongs to the organization, for example tos_uri, contacts and the like while MSn would contain information about the specific entity like authorization_endpoint for an OP or redirect_uris for a RP.

The metadata for a specific entity is constructed by starting with the information in MS0 and then adding the information in MS1 to MSn using the rule below.

If the same claims appear in MSa and MSb (b > a, a=0,..,n, b=0,..,n) then unless the value in MSb is less or equal to the value in MSa then the value in MSb should be ignored.

The reason for us to define a compounded metadata statement in this way is so new OIDC entities can be created and described without having to involve all the parties up to and including the FO. Only the party responsible for the entity and the immediate superior party, who has to sign the new information, has to be involved.

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

MS0

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

MS1

{
  "scope": "openid eduperson",
  "response_types": ["code"],
}
            

MS2

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

sum(MS0...2)

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

3.5. Conceptual Model

A set of metadata statements, together describe an entity are brought together using the metadata_statement parameter.

The following is a non-normative example of a compounded metadata statement. Also note that the the metadata_statement MUST be a signed JWT. In this example, the only the parts of the signed JWT payload pertinent to the example are shown.

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

4. Trust Model

The trust model is based on linking together signing keys, referred to in the metadata statements and represented asJWK Sets [RFC7517]. Each signature chain is rooted in the trusted third party's signing keys. By verifying such signature chains, the entities can establish trust in the metadata.

4.1. Federation Operator

The Federation Operator (FO) is the trusted third party. The FO MUST have a globally unique identifier. It will publish a JWKS, containing the signing keys that the FO will use for signing metadata submitted to it, at a HTTPS URL which server certificate MUST appear in a well-known Certificate Transparency log [RFC6962]. The key IDs of the FO's signing keys MUST be globally unique since they are the keys in the metadata_statment_uris object.

For the following description, this is assumed to be true: A federation consists of a number of members, and each member has one or more representatives registered with the federation. These representatives are allowed to issue metadata signing requests on behalf of the member to the federation. Below such a representative is called a Level 0 Requester (L0Req). Within each member unless all entities belonging to the member is handled by the L0Req there may exists parties that are responsible for single or groups of entities. Within these parties we may have further subdivisions such that we end up with Level 0, 1, 2, 3 or more requesters. This document makes no assumption on the number of levels.

Note that the level N requester is the level N+1 signer.

4.2. The Starting Point

The innermost metadata statement in the nest of metadata statements is the one that the FO has signed. That statement MUST NOT contain any references to other metadata statements. All other metadata statements in the nest MUST contain at least one reference to another metadata statement.

4.3. Constructing a Signed Metadata Statement

These are the steps that are performed to construct a signed metadata statement. A metadata signing request may be about one specific entity or a group of similar entities.

  1. The requester constructs a signing request by collecting the necessary client or provider metadata as described in Section 3.
  2. If this is the top most metadata statement (MS0) then no metadata statement will be added to the metadata statement. If it is a more specific metadata statement (MS1...n) then more general metadata statement/-s MUST be added. Dependent on setup the metadata statement can be added by the requester or the signer.
  3. The signing request is transported to the signing party. In the case or MS0 this MUST be the FO. If it is MS1 it is the LOReq. If it is MS2 it is the L1Req and so on.
  4. The signing party verifies the information in the signing request, modifies and/or adds more information according to the applicable policies (e.g. federation policy if the signing request pertains to metadata statement MS0, or organizational policy for metadata statements MS1..n) before signing the statement.
  5. Once the signing party has processed the signing request, the metadata statement is returned to the requester.

An example of the construction of a compounded metadata statement.

4.4. Verifying a Metadata Statement

def verify(ms, sign_keys):
    keys = []
    pl = get_payload(ms)
    if 'metadata_statements' in pl:
        md = []
        for statement in pl['metadata_statements']:
            _ms, _md = verify(statement, sign_keys)
            if _ms:
                keys.append(get_keys(_ms))
                if _md:
                    md.extend([_ms, _md])
                else:
                    md.append(_ms)
    elif 'metadata_statement_uris' in pl:
        md = []
        for _iss, uri in pl['metadata_statement_uris'].items():
            statement = html_get(uri)
            _ms, _md = verify(statement, sign_keys)
            if _ms:
                keys.append(get_keys(_ms))
                if _md:
                    md.extend([_ms, _md])
                else:
                    md.append(_ms)
    else:
        return verify_signature(ms, pl['iss'], sign_keys), []

    return verify_signature(ms, pl['iss'], keys), md
                        

Verifying the received metadata statement involves running a function similar to this:

As can be see from the pseudo code the process is that you successively unpack the metadata statements (this involves base64 decoding the JWS payload without verifying the signature) until you reach the inner most MS (MS0). After having verified the signature of MS0 using the FOs signing keys, you can now use the signing keys included in or referenced from MS0 to verify the signature of the next layer (MS1) and so on.

5. OpenID Connect Communication

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) Registration -----> | 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).

5.1. Provider Discovery

The OP MUST publish its provider metadata as specified by OpenID Connect Discovery 1.0 [OpenID.Discovery]. The RP makes a standard OpenID Provider Configuration Request. The OP responds with its provider configuration and the additional metadata parameters specified in Section 3

5.2. Client Registration

The OP MUST support dynamic client registration as described in OpenID Connect Dynamic Client Registration 1.0 [OpenID.Registration]. The RP makes a Client Registration Request including the additional metadata specified in Section 3

6. Belonging to Several Federations

6.1. Choosing federation

This draft allows any entity to belong to more then one federation. During the provider discovery and client registration process the parties has to agree on which federation to use.

6.2. Relying Party

An organization may be a member of more the one federation. The RPs it is responsible for may be members of one or more of these.

The organization registers and gets metadata staements signed by each federation. One extreme is that it will mint a new key pair for each federation, the other is that it will use the same key pair for all federations. It does not matter which it chooses, but the end result MUST be that there is one signed RP registration request per signing key. This is then published using metadata_statement_uris or metadata_statements the client registration request.

The following is a non-normative example of an absolutely minimal client registration request sent to an OP:

{
  "redirect_uris": ["https://example.com/rp2/callback"],
  "metadata_statement_uris": {
      https://swamid.sunet.se/":
        "https://dev.example.com/rp1/idfed/swamid.jws",
      "https://www.incommon.org":
        "https://dev.example.com/rp1/idfed/incommon.jws"
  }
}
            

As described above, when the OP receives a request like this it will choose which federation it will work within and then signal that by only returning that corresponding information in the metadata_statements / metadata_statement_uris in the registration response.

The following is a non-normative example of an OPs response on the client registration request above:

{
  "client_id": "abcdefgh",
  "client_secret": "0123456789",
  "client_id_issued_at": 1462375583,
  "client_secret_expires_at": 1462379183,
  "redirect_uris": ["https://example.com/rp2/callback"],
  "metadata_statement_uris": {
    "https://swamid.sunet.se/":
      "https://dev.example.com/rp1/idfed/swamid.jws",
  }
}
            

6.3. OpenID Provider

An OP has the choice of whether it wants one key pair per federation, one key pair for everyone, or anything in between. And, like the RP owner, it has to produce one signed metadata statement per key used.

The following is a non-normative example of an OPs response to a provider configuration request:

  {
    "issuer": "https://foo.example.org/op/fDTowvP0slEdEAcc",
    "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"],
    "metadata_statement_uris": {
      "https://swamid.sunet.se/":
        "https://foo.example.org/op/idfed/swamid.jws",
      "https://www.incommon.org":
        "https://foo.example.org/op/idfed/incommon.jws"
      "https://www.switch.ch":
        "https://foo.example.org/op/idfed/switch.jws"
      "https://www.aco.net/":
        "https://foo.example.org/op/idfed/aconet.jws"
  }
            

7. Timeouts

There are a number of timeouts that MUST considered

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

8. Acknowledgements

9. IANA Considerations

TBD

10. Security Considerations

TBD

11. Normative References

[I-D.draft-ietf-oauth-discovery] Sakimura, N., Bradley, J. and M. Jones, "OAuth 2.0 Authorization Server Metadata", August 2016.
[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.
[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.
[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. Example

The necessary steps for adding a Relying Party to a federation

The following JWKS represents the signing key that the Federation Operator is using in the following example:

{
  "keys": [
    {
      "d": "DpFZnXz8fcKmOxFPfPdh3aZz44U2ZWm1Mxy6CiqHYcA80KVAY-wrjKFV4e
iSl9JENpoWXax4dpMcyJa2TdAXL9-4WqGNQAPRvdOfHcJM_uaBSGZwsuqAqZi_0sbNxurG
gbjKV38ra-iz42fcSXHCgNdMJjCi3VixS8iASHGU82R6mYyVeMWdX_j2RG--41PDxud4xS
YCKDuR6s2qlLVXyCZqFu_Yzl5zChiNxZJ_ggcxyL6i_hngi1oSbbVjgNKTcJNaIdOfzzcn
Ud5J9GP941-tylwg7NC3gRo1bXlUx6HFx3LkYe1PdroHhQd92RPyJdPqHDfbizJ4sjXN4c
Nq-Q",
      "e": "AQAB",
      "kid": "uZX0-P1-TMsZRqK1SeXpdLgsLoeUNskN2W_rwBNKAtc",
      "kty": "RSA",
      "n": "rqJ_CFECPF2nBD1eXkFonJo5gGcbnCvDudm_-7f1thcQqiuY2Xz0eKqQ2H
P3Nw-wP5q2hKbNVgAQSBbMp_AgNwRFmboJKF4cFEr3ZtmvO94bM6L15vUR2HNyX-4LaZ6S
9u35jSikOVJDt1BK-72w_DKeb8O8qa2dl9k7F6QZJQT6Nfh5rEALQLOZgwBgZAUpu2tQUh
3TFpwe3J_rQtCBbI3r0W1XoM1pD3EXTm9MI_aANRL82rh7_ZqLwGeBprD3F6ns9i5-psQ0
UZ-2eVjN6J1um40U6ysu3QjFUZEwb0yxNVx2D9bzOPMHwo6GAzePhJ46rI8NQ0NwJdB7lN
vrhw",
      "p": "y4VcmM4QZoIjsGlTE7jvkJzYAud9Hz3uexVdeTShHnS-btLySSP70EWdvI
CkHK7Z4KikNZaD3cET978LmkoG03WZcs7iEEg7hQ0N7ePMv7P1w6X1Z2_IeWml0c4iFSMa
GPJk8a65HgBZ8fYPXFtERI7e1M--oqCrsTFikP8wYQU",
      "q": "26pTV-JNgwx3LMrqEKIoIvHwLKfjFouRZXtTnOJP9G9BZ9vhAn1qX06M-x
W02G3qGzhQEpNZKMj54APNcqkg4PH1wMJmJ-cs1T44KoNhhihoHd6awT7PGNMo9I728CwY
fkM3ZW-BsgGBzQcfdI043cV3ebXzIEWwPbqTR44p8Bs",
      "use": "sig"
    }
  ]
}
        

A.1. Relying Party joining a federation

A.1.1. Step 1 - Developer creates its signing key pair.

{
  "keys": [
    {
      "d": "RJmqe2KiVOShoTMaZBmoMLkmeZY97PW3TOgSGDgZejL6I2qdhNlBAa3e9N
z6ggkWpxEy6IGNGetwNwS9aYA_Z6m45kaaUHXGKol_R_5s4TJryXUppxWDuHScE_dVcfzl
usm9Cq8J-U-xoaoKL36I3rakCJ_dWpsGNDpYSMenXcXuX-gJ5-HvSTETV5Bp23izUF4BH8
TSVWniD8Vk5Hv8EtWVqsqc7YmIG1zW_ctJhK7peymmNIVpcGpIxaT8agUOS-hcNxpN4AlY
rELn2twzq8tXp5bPZNiHHNXgzXANy5BgNFXXnZFqFiNiBn3agQxF2aiu4Ei5k5OidHTV8q
eGWQ",
      "e": "AQAB",
      "kid": "z414hVxt2-nkbqgG3VFYOZGB3Miwuhe75SfWT1BQQTc",
      "kty": "RSA",
      "n": "waDXGJwu9pV3gMY7rtpq3OYSAG1HZy7qilGC3ULMxJxjhSQCJ7M9PBC4uo
F_f5178FebpKBIoT3_YzqETt9Ry_6NA_mGBq6xtjEgnmNv6ktQj8hKI0tYheWRHMJIt2ay
8IwnV-3LD0Q_Nn7E3YgGaJUBlzDgJxQQcRVGFEOcFL-7TiKtVdPmPDGcSF7FivaGJO-MVq
mDkCsZVMTZoqmKeuaqbshsDjxy9GaiImQLe8tyzkhxEoG7qvovlGoV4AE8WroMinx0qWvg
lR8n041qQhrUMtoQMDCI53uLy6ZSR0jbNNEwvDBbiqD4Hm3piAwTUrGKWYLxbeicK_7A6g
F2Sw",
      "p": "3SBEMBmIGztaOpCH-C9vwr80SyXm6M1uwCoKjBOiy_-kJ03jvacztd5CEO
cCvhRLVvl3rEYSP97DR_Eju-jlKWi92tbIECGvWzgszMHLdEdjvVvpJLlOSAfFMYsaPxa1
Sw2HS7RgoAwIxD5HVcdPK-3cJ5Gi0hInbz-ufrH4ru0",
      "q": "4CphaFI0lSGr0HNifXJBN5JkXmCZp6WX06cI4pR_DwZAHTojc8dK1ECMHU
2oP2nPn1pmAVZj4p98vO0MfTxSgNB15EmDRkic_cmS-SenUUf7Pl3avJwpZq_qxYPqDajA
gWHuuci-2zKXRlKS_ZCz1MAmx-gV0We3AnletWV52xc",
      "use": "sig"
    }
  ]
}

Developer creates its signing key pair.

A.1.2. Step 2 - Developer submits registration data to FO

The developer submits registration data to Federation Operator (FO).

{
  "contacts": [
    "dev_admin@example.com"
  ],
  "logo_uri": "https://example.com/logo.jpg",
  "policy_uri": "https://example.com/policy.html",
  "signing_key": {
    "e": "AQAB",
    "kid": "z414hVxt2-nkbqgG3VFYOZGB3Miwuhe75SfWT1BQQTc",
    "kty": "RSA",
    "n": "waDXGJwu9pV3gMY7rtpq3OYSAG1HZy7qilGC3ULMxJxjhSQCJ7M9PBC4uoF_
f5178FebpKBIoT3_YzqETt9Ry_6NA_mGBq6xtjEgnmNv6ktQj8hKI0tYheWRHMJIt2ay8I
wnV-3LD0Q_Nn7E3YgGaJUBlzDgJxQQcRVGFEOcFL-7TiKtVdPmPDGcSF7FivaGJO-MVqmD
kCsZVMTZoqmKeuaqbshsDjxy9GaiImQLe8tyzkhxEoG7qvovlGoV4AE8WroMinx0qWvglR
8n041qQhrUMtoQMDCI53uLy6ZSR0jbNNEwvDBbiqD4Hm3piAwTUrGKWYLxbeicK_7A6gF2
Sw",
    "use": "sig"
  },
  "tos_uri": "https://example.com/tos.html"
}
           

A.1.3. Step 3 - FO returns a signed metadata statement

The FO returns a signed metadata statement containing the submitted registration data, and any applied policy restrictions like response_types, signing/encryption algorithms to be used and additional specific policy parameters like the ones specified above.

This is an example of a metadata statement constructed by the FO before it is signed by the FO:

{
  "contacts": [
    "dev_admin@example.com"
  ],
  "exp": 1462438820,
  "iat": 1462438820,
  "iss": "https://swamid.sunet.se/",
  "jti": "e920396fc2cb4ac0aaeb229674fd286a",
  "kid": "uZX0-P1-TMsZRqK1SeXpdLgsLoeUNskN2W_rwBNKAtc",
  "logo_uri": "https://example.com/logo.jpg",
  "policy_uri": "https://example.com/policy.html",
  "response_types": [
    "code",
    "code id_token",
    "token"
  ],
  "scopes": [
    "openid",
    "email",
    "phone"
  ],
  "signing_key": {
    "e": "AQAB",
    "kid": "z414hVxt2-nkbqgG3VFYOZGB3Miwuhe75SfWT1BQQTc",
    "kty": "RSA",
    "n": "waDXGJwu9pV3gMY7rtpq3OYSAG1HZy7qilGC3ULMxJxjhSQCJ7M9PBC4uoF_
f5178FebpKBIoT3_YzqETt9Ry_6NA_mGBq6xtjEgnmNv6ktQj8hKI0tYheWRHMJIt2ay8I
wnV-3LD0Q_Nn7E3YgGaJUBlzDgJxQQcRVGFEOcFL-7TiKtVdPmPDGcSF7FivaGJO-MVqmD
kCsZVMTZoqmKeuaqbshsDjxy9GaiImQLe8tyzkhxEoG7qvovlGoV4AE8WroMinx0qWvglR
8n041qQhrUMtoQMDCI53uLy6ZSR0jbNNEwvDBbiqD4Hm3piAwTUrGKWYLxbeicK_7A6gF2
Sw",
    "use": "sig"
  },
  "token_endpoint_auth_method": "private_key_jwt",
  "tos_uri": "https://example.com/tos.html"
}
            

The signed version of this metadata statement, or a link to it, is then expected to be included in the RPs client registration request before being signed by the level 0 signing key.

A.1.4. Step 4 - The RP gets a signing key

{
  "keys": [
    {
      "d": "BA0bo5OR3ht2KGDeAUpZsKv-Jjo9IKpYA2x7yQhcIH3bt9T2495pXVAHLQ
XXnZpjMenz7WPx94ajxIh96Bt59AYx4AwAEaBnPzK8vXLIP-A92NP3HV7vk0p8KWsrEdDw
xBaypqRXxz7V5vPGQVnOGg2eKSlP5F4-HoGpU6xDRo8Lptcs5VNx0a9kKVqEu-YpQkc2z2
uLRjl8urOu471sks38U03wRwWDElepUI28jEjhPydVSQw-E5w3yKhHTZeh1mVdNMp7_8LD
zScP1Ah5VCRLFfrmx1bOXxXZWHpMD6vgghmaCQGmyhgEr3XNzHVlH4bfVI_2Vrxp6cxHpe
3iYw",
      "e": "AQAB",
      "kid": "Tvd2gF4mcNtiYx6FyOOH83Xj_MkF-8yn_rD2Gm06RxY",
      "kty": "RSA",
      "n": "2kCKMUluhKV2INV3dS89WQ305J6JL8OJQ1cPk3GQ20Zvraa3DCntNns1xy
9gynGYUQzom7LYAqcmpu7xFGNXH0gN8JyXcCiWl02IuD6lwS6N2d7y6xJm8-mUBiwVrAlh
wWL1Bf8JRycRUQ51c6Y8yYrUf2pjeIFQBQEfUhcjNg13L1OUDoWJizy5QhaTe4p2uezYhK
lKtSHC7T6Brs6kWJA57j8BY5Tx4p6cyWRGsN58XXfmWg1hA1LjVIwgtSBvax7KRGUY6TXO
d5Km2MvJgBOfqAYfh1z0wZRiBdUa0RzsXavf4HGjnwPknYcSY1MwKZCzz_W0_uAiGlHFlN
wLSQ",
      "p": "5279rRhB4IBf5chMgrTVwsAEKWyEsRrIVs5xLFVA5rpOKLN6qGhLO6PU9j
msD7dYEa0IA-eTxVCCuMp09KEfyrRAn0OWpWdndu8IR_n2e4zZxBXbf4WuIeZwxfM5PqKi
5LOnp442CthmzbsVD2OLmlgSViWSAP9SLFOBGfniTqs",
      "q": "8WtasUyu9D9StGJkgolHjofbMnxXzRqpnA-QSV71htsQD3wof-vda8e8Jk
DLPPfAYuVYieCHeJYGsT9EHAG1Nyyr9OMzFeo73N1FdKGIGihWHSuvW6sRr6FTta12ZMN7
Jkm3l2rQoZALgvMtdYdDGJ-D3gwusW5nNS3-xJqMPds",
      "use": "sig"
    }
  ]
}
            

The RP gets a signing key

A.1.5. Step 5 - RP produces a client registration request

{
  "application_type": "web",
  "jwks_uri_signed": "https://example.com/rp1/jwks.jws",
  "redirect_uris": [
    "https://example.com/rp1/callback"
  ],
  "response_types": [
    "code"
  ],
  "signing_key": {
    "e": "AQAB",
    "kid": "Tvd2gF4mcNtiYx6FyOOH83Xj_MkF-8yn_rD2Gm06RxY",
    "kty": "RSA",
    "n": "2kCKMUluhKV2INV3dS89WQ305J6JL8OJQ1cPk3GQ20Zvraa3DCntNns1xy9g
ynGYUQzom7LYAqcmpu7xFGNXH0gN8JyXcCiWl02IuD6lwS6N2d7y6xJm8-mUBiwVrAlhwW
L1Bf8JRycRUQ51c6Y8yYrUf2pjeIFQBQEfUhcjNg13L1OUDoWJizy5QhaTe4p2uezYhKlK
tSHC7T6Brs6kWJA57j8BY5Tx4p6cyWRGsN58XXfmWg1hA1LjVIwgtSBvax7KRGUY6TXOd5
Km2MvJgBOfqAYfh1z0wZRiBdUa0RzsXavf4HGjnwPknYcSY1MwKZCzz_W0_uAiGlHFlNwL
SQ",
    "use": "sig"
  }
}
            

The RP produces a client registration request

A.1.6. Step 6 - Developer produces metadata statement for RP

{
  "application_type": "web",
  "jwks_uri_signed": "https://example.com/rp1/jwks.jws",
  "redirect_uris": [
    "https://example.com/rp1/callback"
  ],
  "response_types": [
    "code"
  ],
  "signing_key": {
    "e": "AQAB",
    "kid": "Tvd2gF4mcNtiYx6FyOOH83Xj_MkF-8yn_rD2Gm06RxY",
    "kty": "RSA",
    "n": "2kCKMUluhKV2INV3dS89WQ305J6JL8OJQ1cPk3GQ20Zvraa3DCntNns1xy9g
ynGYUQzom7LYAqcmpu7xFGNXH0gN8JyXcCiWl02IuD6lwS6N2d7y6xJm8-mUBiwVrAlhwW
L1Bf8JRycRUQ51c6Y8yYrUf2pjeIFQBQEfUhcjNg13L1OUDoWJizy5QhaTe4p2uezYhKlK
tSHC7T6Brs6kWJA57j8BY5Tx4p6cyWRGsN58XXfmWg1hA1LjVIwgtSBvax7KRGUY6TXOd5
Km2MvJgBOfqAYfh1z0wZRiBdUa0RzsXavf4HGjnwPknYcSY1MwKZCzz_W0_uAiGlHFlNwL
SQ",
    "use": "sig"
  },
  "metadata_statements": [
    "eyJraWQiOiJ1WlgwLVAxLVRNc1pScUsxU2VYcGRMZ3NMb2VVTnNrTjJXX3J3Qk5LQ
XRjIiwiYWxnIjoiUlMyNTYifQ.eyJwb2xpY3lfdXJpIjogImh0dHBzOi8vZXhhbXBsZS5j
b20vcG9saWN5Lmh0bWwiLCAidG9rZW5fZW5kcG9pbnRfYXV0aF9tZXRob2QiOiAicHJpdm
F0ZV9rZXlfand0IiwgImNvbnRhY3RzIjogWyJkZXZfYWRtaW5AZXhhbXBsZS5jb20iXSwg
ImxvZ29fdXJpIjogImh0dHBzOi8vZXhhbXBsZS5jb20vbG9nby5qcGciLCAic2NvcGVzIj
ogWyJvcGVuaWQiLCAiZW1haWwiLCAicGhvbmUiXSwgImlhdCI6IDE0NjI0Mzg4MjAsICJp
c3MiOiAiaHR0cHM6Ly9zd2FtaWQuc3VuZXQuc2UvIiwgImtpZCI6ICJ1WlgwLVAxLVRNc1
pScUsxU2VYcGRMZ3NMb2VVTnNrTjJXX3J3Qk5LQXRjIiwgImp0aSI6ICJlOTIwMzk2ZmMy
Y2I0YWMwYWFlYjIyOTY3NGZkMjg2YSIsICJyZXNwb25zZV90eXBlcyI6IFsiY29kZSIsIC
Jjb2RlIGlkX3Rva2VuIiwgInRva2VuIl0sICJzaWduaW5nX2tleSI6IHsiZSI6ICJBUUFC
IiwgImtpZCI6ICJ6NDE0aFZ4dDItbmticWdHM1ZGWU9aR0IzTWl3dWhlNzVTZldUMUJRUV
RjIiwgImt0eSI6ICJSU0EiLCAidXNlIjogInNpZyIsICJuIjogIndhRFhHSnd1OXBWM2dN
WTdydHBxM09ZU0FHMUhaeTdxaWxHQzNVTE14SnhqaFNRQ0o3TTlQQkM0dW9GX2Y1MTc4Rm
VicEtCSW9UM19ZenFFVHQ5UnlfNk5BX21HQnE2eHRqRWdubU52Nmt0UWo4aEtJMHRZaGVX
UkhNSkl0MmF5OEl3blYtM0xEMFFfTm43RTNZZ0dhSlVCbHpEZ0p4UVFjUlZHRkVPY0ZMLT
dUaUt0VmRQbVBER2NTRjdGaXZhR0pPLU1WcW1Ea0NzWlZNVFpvcW1LZXVhcWJzaHNEanh5
OUdhaUltUUxlOHR5emtoeEVvRzdxdm92bEdvVjRBRThXcm9NaW54MHFXdmdsUjhuMDQxcV
FoclVNdG9RTURDSTUzdUx5NlpTUjBqYk5ORXd2REJiaXFENEhtM3BpQXdUVXJHS1dZTHhi
ZWljS183QTZnRjJTdyJ9LCAidG9zX3VyaSI6ICJodHRwczovL2V4YW1wbGUuY29tL3Rvcy
5odG1sIiwgImV4cCI6IDE0NjI0Mzg4MjB9.ZVnHkrdGqQTP36UXwZhb9hhcIc1hgkYNd8d
GsyS-uHojrr4lYqkAyDjCr39fJnGvRnJvm_-LQDBfaKFHyGjSCi97uQAN72lWC-FRs-wuE
D0abhgSEyrpDBSG0enNvIyOP_BEbo5xx950MJrlcmOT9s2MCI2KPKV4Rt8ZIJUdLO5kWPl
fzaHkRZenCnob7sKYY4mbFosrslT0ny51yFSbZLtvnc04dmR0Q8ccAYJkMfL4t-IIGrrKR
bDB6x52_gqJ8REgbhfiN6StM6jwiv_UydOjLXvFpsl5_5AZWWubNaIzj-4eCIpPFYjxBaO
Gcs0FsmD1irBDIAIQodidYoI6aA"
  ]
}
              

Developer produces metadata statement based on client registration request

A.1.7. Step 7 - RP sends a client registration request to an OP

{
  "redirect_uris": [
    "https://example.com/rp1/callback"
  ],
  "metadata_statement_uris": {
    "https://swamid.sunet.se/":
      "https://dev.example.com/rp1/idfed/swamid.jws",
  }
}
              

The RP sends a client registration request to the OP

A.1.8. Step 8 - OP handles metadata statement

The OP fetches the metadata statement from the URI 'https://dev.example.com/rp1/idfed/swamid.jws' and then goes about unpacking the metadata. At this point in time the OP doesn't have the necessary key to verify the signature of the metadata. Therefor it has to unpack the JWT without verifying the signature. It will then get a JSON document looking like whats listed in step 6 above. From this document it can extract the metadata statement which should be signed by a key belonging to the FO. The OP should have the fetched the public version of that key from the FO at some time prior to this. It can now verify the signature of the metadata statement and unpack the JWT. The JSON document it then gets is the one listed in step 3. The signing key specified in that document can now be extracted and used to verify the signature of the metadata.

What's remaining now for the OP is to put all the pieces of the client registration request together. It will have one piece from the level 0 request augmented with the federation policy and then another piece from the RP.

Appendix B. Notices

Copyright (c) 2016 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 approved specification ]]

-01

-00

Authors' Addresses

Roland Hedberg (editor) independent EMail: roland@catalogix.se
Rebecka Gulliksson Umea University EMail: rebecka.gulliksson@umu.se
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/