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. Theclient_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.
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 theredirect_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.