Skip to content

OAuth with Member Identity Certificates

The Trust Framework uses OAuth to authorise APIs which provide access to data that requires Permission from the end-user.

All server-to-server communication is secured with mTLS using client certificates. In the certificate, the client is identified by a URL in the client X.509 certificate as the single Subject Alternative Name of type URI.

Note: This document uses US English. To align with W3C and other prevalent standards, IB1 uses US English in its technical specifications and technical documentation.

OAuth Profile

The Trust Framework uses a FAPI 2 compliant profile within the FAPI 2.0 Security Profile specification.

Profile options

The following options within the FAPI 2 profile are used:

  • MTLS is required on all server-to-server communication endpoints.
  • OAuth endpoints use the tls_client_auth method.
  • PKCE is used with the S256 code challenge method.
  • TLS 1.3 is required.
  • The Registry License URL is used as the scope, and provides the text which must be displayed to the end-user to give informed consent.
  • The client_id is the Directory URL from the client X.509 certificate, and must match the presented client certificate. The client_secret is not used.
  • Tokens are bound to the Directory URL from the certificate (rather than to the specific certificate instance) by requiring that the client_id matches the certificate.

When this specification is used with another Trust Framework specification, these requirements may not be varied.

Unused options

The following FAPI 2 options are not used:

  • Dynamic Client Registration (the Directory issued certificate provides all client information)
  • OpenID Connect (no end user identifier is passed to the clients)
  • Rich Authorization Requests (the License URL requires no further authorization data)
  • Access and refresh tokens are not required to be JWTs, as long as the tokens are bound to the URL in the client certificate.
  • The additional x-fapi-* headers defined in the FAPI 2 implementation advice, as better functionality is provided by other Trust Framework specifications.

When this specification is used with another Trust Framework specification, these options may be used.

OAuth Issuer Endpoints

The OAuth Issuer must implement the pushed_authorization_request, authorization and token endpoints.

The userinfo and registration endpoints must not be implemented.

Other endpoints may be implemented, for example, introspection, if they are restricted to use by the Member's internal systems only.

OAuth Issuer Metadata

This profile requires that the OAuth Issuer publishes metadata according to RFC8414 at the standard location formed by inserting /.well-known/oauth-authorization-server between the host and path components of the authorization server's issuer identifier.

For example, the issuer https://auth.example.org/accounts would publish metadata at https://auth.example.org/.well-known/oauth-authorization-server/accounts.

The profile requires the metadata has the following values:

{
  "mtls_endpoint_aliases": {
    // Must be exactly the same as the *_endpoint values defined at the top level
  },
  "use_mtls_endpoint_aliases": true,
  "require_pushed_authorization_requests": true,
  "tls_client_certificate_bound_access_tokens": true,
  "response_types_supported": ["code"],
  "code_challenge_methods_supported": ["S256"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "authorization_endpoint_auth_methods_supported": ["tls_client_auth"],
  "token_endpoint_auth_methods_supported": ["tls_client_auth"]
  // No equivalent for pushed_authorization_request_endpoint
}

Any *_endpoint value must be repeated exactly within the mtls_endpoint_aliases property so the aliased and unaliased values are equal. For example:

{
  "issuer": "https://auth.example.org/accounts",
  "authorization_endpoint": "https://auth.example.org/accounts/authorization",
  "token_endpoint": "https://auth.example.org/accounts/token",
  "pushed_authorization_request_endpoint": "https://auth.example.org/accounts/par",
  "mtls_endpoint_aliases": {
    "authorization_endpoint": "https://auth.example.org/accounts/authorization",
    "token_endpoint": "https://auth.example.org/accounts/token",
    "pushed_authorization_request_endpoint": "https://auth.example.org/accounts/par"
  }
}

OAuth Flow

Pushed Authorization Request (PAR)

The Client starts the flow by making a Pushed Authorization Request to the pushed_authorization_request_endpoint URL using MTLS,

  • requesting a code response,
  • specifying a Directory URL as the client_id, which must match the URL in their MTLS client certificate,
  • including a PKCE code_challenge,
  • setting the scope to a Registry License URL,
  • and include a redirect_uri, which does not have to be pre-registered.

Precautions must be taken to avoid creating an open redirect, in particular by not including attacker controlled values in the redirect_uri.

POST /accounts/par HTTP/1.1
Host: auth.example.org
Content-Type: application/x-www-form-urlencoded

response_type=code
&client_id=https%3A%2F%2Fdirectory.core.trust.ib1.org%2Fapplication%2F38328a78
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256
&scope=https%3A%2F%2Fregistry.core.trust.ib1.org%2Fscheme%2Felectricity%2Flicense%2Fsmart-meter%2F2025-02-06
&redirect_uri=https%3A%2F%2Fapp1.consumer.example.com%2Fcb
&state=WFqUWTVvX49tM

The Issuer will respond with a request_uri:

HTTP/1.1 201 Created
Cache-Control: no-cache, no-store
Content-Type: application/json

{
  "request_uri": "urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2",
  "expires_in": 90
}

Redirection of User Agent to Issuer user interface

The Client forms a URL using the authorization_endpoint, their Directory URL, and the request_uri, and redirects the end user's User Agent to that URL:

https://auth.example.org/accounts/authorization?
  client_id=https%3A%2F%2Fdirectory.core.trust.ib1.org%2Fapplication%2F38328a78
  &request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2

The Issuer URL uses a public CA to present a certificate trusted by the end user's browser, even though the same URL appears within the mtls_endpoint_aliases section.

Redirection of User Agent to Client Application

After the OAuth Issuer has authenticated the end user, it will redirect the end user's User Agent back to the Client with the authorization code and state parameter from the Pushed Authorization Request.

https://app1.consumer.example.com/cb?code=Mo9iP1GkbP7P0Cut58JOH9SVHc
  &state=WFqUWTVvX49tM

Exchange authorization code for tokens

The Client uses the token_endpoint URL with MTLS to exchange the authorization code for access and refresh tokens, with

  • the code returned by the Issuer to the redirect_uri,
  • the PKCE code_verifier,
  • the Directory URL client_id matching the MTLS client certificate,
  • the redirect_uri from the PAR.
POST /accounts/token HTTP/1.1
Host: auth.example.org
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=Mo9iP1GkbP7P0Cut58JOH9SVHc
&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
&client_id=https%3A%2F%2Fdirectory.core.trust.ib1.org%2Fapplication%2F38328a78
&redirect_uri=https%3A%2F%2Fapp1.consumer.example.com%2Fcb

The Issuer will respond with the access and refresh tokens.

Use of access and refresh tokens

Both the OAuth token_endpoint and the resource server must verify that the URL in the MTLS client certificate matches the client_id associated with the token.