OpenID Federation policy guide
How to design metadata policies for protocol and API interoperability between federated entities, such as applications, services or devices? How to enforce a common security profile in a federation? This guide for federation architects explains the principles and operation of the OpenID Federation 1.0 metadata policy language and how to apply it.
1. Application protocols rely on entity metadata
When a federation is formed it is to establish a trust framework for its participants. The participants can then safely transact with one another, using one or more agreed-upon protocols. In a federation for user authentication and single sign-on (SSO) the protocol can be OpenID Connect. In a federation of verifiable credential (VC) issuers, wallets and verifiers the protocols can be based on the OIDC4VC/VP specs.
Protocols often require certain knowledge about the other entity prior to the transaction. For example, in OpenID Connect the identity provider needs to know at a minimum the redirection URI of the relying party in order to handle a login request from it.
To this end OpenID Federation 1.0 enables an entity
to publish metadata about itself in its configuration, at the
/.well-known/openid-federation
URL, so that other federation participants can
readily obtain the metadata, as part of the trust chain resolution. The
metadata is explicitly typed, for example openid_relying_party
for OpenID
relying party metadata. This guarantees the type safety of metadata and enables
entities to potentially have multiple distinct protocol identities.
Example metadata for an OpenID relying party:
{
"metadata" : {
"openid_relying_party" : {
"redirect_uris" : [ "https://rp.example.com/cb" ],
"client_name" : "Space Launcher App",
"logo_uri" : "https://rp.example.com/logo.png",
"signed_jwks_uri" : "https://rp.example.com/jwks.jwt",
"token_endpoint_auth_method" : "private_key_jwt",
"token_endpoint_auth_signing_alg" : "RS256"
}
}
}
What are the typical purposes of entity metadata?
-
Enable the discovery of protocol endpoints. In OpenID Connect this can be the
redirect_uri
of the relying party, or the keys, authorisation and token endpoints of the identity provider. -
List supported cryptography algorithms. In OpenID Connect this can include the JWS algorithm for JWT-based client authentication.
-
Configure UIs. In OpenID Connect this can be the client name and logo to display on the login screen.
-
Identify supported protocol extensions. In OpenID Connect this can be extensions such as Identity Assurance / eKYC.
2. When are metadata policies needed?
When a policy the published entity metadata becomes necessary this usually boils down to two reasons:
-
To ensure interoperability between entities at the protocol level – When the metadata contains optional parameters or must be configured in a certain way to ensure all entities can successfully interop with one another. In OpenID Connect an example of this is that both providers and relying parties must publish support for the same method(s) of client authentication. If that isn’t observed a login request may fail due to the client using an inappropriate authentication method.
-
To enforce a security profile – When the protocol and its metadata support varying levels of security and all entities in the federation must comply with a certain profile. In OpenID Connect this could for instance be a requirement to support a FAPI security profile.
Federation architects may feel tempted to use the policy facility to enforce type checks on the JSON values of metadata parameters. This is an antipattern, federation policies should not be concerned with such checks. Tney should be done by the application layer, which receives the resolved metadata as a JSON object to parse into an internal application-specific representation.
Metadata policies are not necessary when the following is true:
-
The metadata is minimal, has no optional parameters or generally doesn’t allow metadata instances with incompatible interoperability to be specified.
-
The application protocol / layer is capable on its own to enforce any interoperability or security requirements of the federation.
Future protocols that are intended for use by entities in OpenID compliant federations may be designed with a strategy to require little or no special metadata policies.
3. Principles of the policy language
The policy language of OpenID Federation 1.0 has a simple expressive syntax that is entirely JSON-based. Trust anchors and intermediate entities can seamlessly embed metadata policies in the subordinate statements that they issue. The policy syntax can be parsed with a regular JSON library, no special parser is required.
The policy language in OpenID Federation 1.0 was designed around 6 principles:
-
Hierarchy
Trust anchors and intermediate entities can define metadata policies for their subordinate statements. Once a policy is defined, a subordinate intermediate cannot override it, repeal it make it more permissive.
The principle of policy hierarchy is preserved in nested federations where a trust anchor in one federation may act as an intermediate entity in another.
-
Equal opportunity
Intermediate entities are given the opportunity to define their own policies, as long as they do not clash with the policies of superior entities. An intermediate can for instance define a more restrictive policy, or a new policy for a metadata parameter that isn’t already controlled by superior entities.
-
Specificity and granularity
Policies are expressed at the level of individual metadata parameters, for example
token_endpoint_auth_method
, and collected into an object for a given entity type, for exampleopenid_relying_party
. This ensures the policies for different entity types are independent and isolated from one another. This rule applies also to the individual metadata parameters for an entity type.Trust anchors and intermediate entities have the choice to define policies that apply to all their subordinate entities, or only to specific subjects.
-
Operation
A policy is a check, a modification, or a combination of both on a given metadata parameter.
OpenID Federation 1.0 specifies 7 standard operators. A federation may define and use additional custom operators, provided they are in line the principles
-
Integral metadata enforcement
The resolution and application of metadata policies occurs as part of the trust chain resolution.
-
A trust chain which has conflicting policies, for example a policy of an intermediate entity clashing with a trust anchor’s policy, is deemed invalid.
-
A trust chain with entity metadata that does not comply with the resolved policies is also automatically deemed invalid.
-
-
Determinism
This principle guarantees that when a trust anchor or an intermediate entity formulates a policy, it has predictable and reproducible outcomes.
4. Operators
OpenID Federation 1.0 defines 7 operators for validating and shaping entity metadata in a trust chain.
Policy operator | Purpose | JSON type | ||
---|---|---|---|---|
Modifier | Check | Policy operator | Metadata parameter | |
value | v | x | any | any |
add | v | x | any | JSON array |
default | v | x | any | any |
essential | x | v | true, false | any |
one_of | x | v | JSON array (1) | any |
subset_of | v | v | JSON array | JSON array |
superset_of | v | v | JSON array | JSON array |
Legend:
- “any” means any JSON value type per RFC 8259, section 3.
- (1) the JSON array must not be empty
Policy operator: value
The value
operator sets or overrides a metadata parameter.
Scenario 1
Example policy to ensure RPs will be registered to receive ID tokens with the
auth_time
claim, by setting the require_auth_time
metadata parameter to
true
.
{
"require_auth_time" : {
"value" : true
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
Scenario 2
Example policy to ensure RPs cannot register a 3rd party login initiation URL,
by removing any initiate_login_uri
metadata parameter.
{
"initiate_login_uri" : {
"value" : null
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
Policy operator: add
The add
operator appends one or more values to a metadata parameter that is a
JSON array.
Scenario 1
Example policy by an intermediate federation entity that adds the email address
of its administrator to the contacts
metadata parameter of subordinate RPs.
{
"contacts" : {
"add" : "admin@example.com"
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
Scenario 2
Example policy that adds two email addresses to the contacts
metadata
parameter of subordinate RPs.
{
"contacts" : {
"add" : [ "admin@example.com", "webmaster@example.com" ]
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
Policy operator: default
The default
operator specifies a parameter when it’s absent in the metadata.
Scenario 1
Example policy that sets the ID token JWS algorithm to RS256
for RPs that
don’t specify an algorithm in their metadata.
{
"id_token_signed_response_alg" : {
"default" : "RS256"
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
Policy operator: essential
When true
the essential
operator requires a metadata parameter to be
present. When false
the metadata parameter is voluntary and
may be absent. The essential
operator has a default value false
(voluntary). Entity metadata that is missing an essential parameter is
considered invalid.
Scenario 1
Example policy that requires RPs to provide a client_name
metadata parameter.
{
"client_name" : {
"essential" : true
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
Scenario 2
Example RP policy that marks the client_name
metadata parameter as voluntary.
This is the same as omitting essential
.
{
"client_name" : {
"essential" : false
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
Policy operator: one_of
The one_of
operator ensures a metadata parameter that is present and not
null
is set to a whitelisted value.
Scenario 1
Example policy to ensure that when RPs choose to register for signed UserInfo
responses the JWS algorithm must be either PS256
or ES256
.
{
"userinfo_signed_response_alg" : {
"one_of" : [ "PS256", "ES256" ]
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
C |
|
|
Scenario 2
Example policy that requires RPs to register either for the PS256
or the
ES256
ID token JWS algorithm. The metadata parameter is marked essential and
hence RPs must always specify it.
{
"id_token_signed_response_alg" : {
"essential" : true,
"one_of" : [ "PS256", "ES256" ]
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
C |
|
|
Policy operator: subset_of
The subset_of
operator computes the intersection between a specified JSON
array of values and a metadata parameter (also a JSON array) that is present:
- If the resulting intersection is non-empty the metadata parameter becomes the intersection.
- If the resulting intersection is empty the outcome depends on whether the
metadata parameter is essential:
- If the parameter is essential, the metadata is considered invalid.
- If the parameter is voluntary it is removed from the metadata.
Scenario 1
Example policy to ensure that when RPs choose to specify a set of response
types they must include the code
and / or code id_token
values.
{
"response_types" : {
"subset_of" : [ "code", "code id_token" ]
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
C |
|
|
D |
|
|
E |
|
|
Scenario 2
Example policy requiring RPs to register for a set of response types that
includes the code
and / or code id_token
values. The metadata parameter is
marked essential and RPs must always specify it.
{
"response_types" : {
"essential" : true,
"subset_of" : [ "code", "code id_token" ]
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
C |
|
|
Policy operator: superset_of
The superset_of
operator ensures a metadata parameter (JSON array) that is
present includes a specified set of values.
Scenario 1
Example policy requiring RPs that choose to specify a set of grant types to
include at least the authorization_code
type.
{
"grant_types" : {
"superset_of" : [ "authorization_code" ]
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
C |
|
|
Scenario 2
Example policy requiring RPs to register for a set of grant types that include
at least the authorization_code type
. The metadata parameter is marked
essential and RPs must always specify it.
{
"grant_types" : {
"essential" : true,
"superset_of" : [ "authorization_code" ]
}
}
Input metadata | Output metadata | |
---|---|---|
A |
|
|
B |
|
|
C |
{} |
|