Upgrade OAuth 2.0 security with client certificate bound access tokens

Posted on 2017-08-17

OAuth 2.0 received its most significant security upgrade in its 7 year history, thanks to a new extension spec being developed at the OAuth WG. The simplicity of the bearer token made OAuth 2.0 the success that it is today, but is also its major weakness: whoever possesses the token is able to access the resource that it protects. Attackers aim to exploit just that — by trying to phish or steal access tokens. Once they have them, the original user is impersonated.

The new mutual TLS extension fixes the bearer weakness with an elegant approach: if the OAuth client submits a X.509 certificate during the TLS exchange at the token endpoint, the issued access token is automatically bound to the certificate.

The binding is expressed as a "cnf.x5t#S256" claim associated with the token, representing the client certificate’s SHA-256 thumbprint:

 "iss" : "https://c2id.com",
 "sub" : "[email protected]",
 "exp" : 1493726400,
 "scp" : [ "openid", "read", "write" ],
 "cnf" : { "x5t#S256" : "bwcK0esc3ACC3DB2Y5_lESsXE8o9ltc05O89jdN-dg2" }

When the client accesses a protected resource with the bound token, such as the UserInfo endpoint of an OpenID provider, the client X.509 certificate must again be submitted with the HTTPS request. The resource server will compare the expected hash with that of the received certificate, and if they match, the request can proceed. If they don’t match, or no certificate was submitted, an invalid token error is returned.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token" error_description="Missing / invalid client X.509 certificate for x5t#S256 bound access token"

Client certificate bound tokens are great security enhancement to OAuth 2.0. Even if an attacker succeeds in stealing a token, e.g. from a compromised client app store, that won’t be enough to access the resource server. The private key for the client certificate must also be possessed, and that key may be safely locked in a secure element or HSM.

The mutual TLS spec has some neat features you should be aware of:

  • It also works with self-signed client certificates, so there’s no need to deploy heavy PKIX along your OAuth 2.0 / OpenID Connect servers and applications.

  • Even if you choose to setup a CA for issuing the client certificates, the resource servers don’t need to validate the full certificate chain, as only the client certificate’s hash must be computed to validate the token binding.

  • The client certificate can also serve as a client authentication method at the token endpoint (instead of HTTP basic auth or the JWT assertion methods).

  • Public OAuth 2.0 clients, e.g. on mobile devices, can also use a client X.509 certificate to received bound tokens.

  • It works with all OAuth 2.0 grant types, or at least that’s how we implemented it in the Connect2id server.

We’re pleased to announce you can now use the Connect2id server to issue client certificate bound access tokens. Support for that is available in the latest 6.13 release.

Here are two guides to get you started:

Other new features in v6.13:

See the release notes below for additional information.


To download a ZIP package of Connect2id server 6.13:


(SHA-256: 3bcaadb0316d1cdb85f075ee8cf2acef58d83be82e7408e0ee78963bd33e3912)

As WAR package only:


(SHA-256: ed79c70ebacd283a5ebdb4e317a15825710a2a5762231b3e6c1bc75dce12a69f)


Get in touch with Connect2id support.

Release notes

6.13 (2017-08-17)


  • Adds support for issuing and inspecting client X.509 certificate bound access tokens. See Mutual TLS Profile for OAuth 2.0 (draft-ietf-oauth-mtls-03).

  • Adds support for the Financial Services – Financial API - Part 2: Read and Write API Security Profile (implementers’ draft from 2017-07-17).


  • /WEB-INF/authzStore.properties

    • authzStore.refreshToken.alwaysUpdate — New configuration setting, if
      "true" causes the refresh token to be updated on each authorisation update and on each refresh token use. Defaults to "false" (no update). See The OAuth 2.0 Authorization Framework (RFC 6749), section 6.
  • /WEB-INF/oidcProvider.properties

    • op.idToken.includeStateHash —- New configuration setting, if "true" causes a state hash (s_hash) claim to be included in issued ID tokens. The state hash claim is specified in Financial Services – Financial API - Part 2: Read and Write API Security Profile, section 5.1.
  • /WEB-INF/web.xml

    • Adds a startup listener (SystemPropertyLoader) for loading additional Java system properties from a local file if the Java system property named "systemPropertiesFile" is set. May be used in cloud, virtualised and container deployments to pass selected Connect2id server configuration properties as an external text file.

    • Adds a startup listener (SystemPropertyNameDotRestore) for restoring Java system property names where dot characters "." have been replaced with underscore "_" characters. May be used in AWS Elastic Beanstalk deployments to pass selected Connect2id server configuration properties as environment variables where underscore characters are not allowed in the environment variable name (and cannot be escaped).
  • /WEB-INF/infinispan-mysql-{redis}.xml

    • Changes "dataSourceClassName" to "org.mariadb.jdbc.MariaDbDataSource" (MariaDB driver library included in the c2id.war, compatible with MySQL).

    • Changes default "dataSource.url" to "jdbc:mariadb:…".


  • /.well-known/openid-configuration

    • Includes the "mutual_tls_sender_constrained_access_tokens" parameter in the advertised OpenID provider metadata.
  • /clients

    • OAuth 2.0 clients registered for public key bound TLS client authentication (pub_key_tls_client_auth) will also be implicitly registered to receive access tokens bound to the client X.509 certificate (mutual_tls_sender_constrained_access_tokens=true). Explicit registration to receive client certificate bound access tokens and to have that setting enforced by requiring a client certificate to be presented at the token endpoint is not supported at present for public OAuth 2.0 clients or confidential OAuth 2.0 clients having another authentication method.
  • /token

    • Confidential as well as public OAuth 2.0 clients which submit a client X.509 certificate during the TLS handshake will be issued with an access token bound to the certificate using its SHA-256 thumbprint (as cnf.x5t#S256 token claim). Applies to self-contained (JWT) as well as identifier (key) based access tokens.
  • /token/introspect

    • Adds support for inspecting client X.509 certificate bound access tokens (self-contained and identifier-based). The certificate binding, if present for the token, is indicated by the cnf.x5t#S256 claim.
  • /userinfo

    • Adds support for handling client X.509 certificate bound access tokens. OAuth 2.0 clients which submit a bound access token without the matching client X.509 certificate will have their UserInfo request denied (HTTP 401 Unauthorized) with an "invalid_token" error. See The OAuth 2.0 Authorization Framework: Bearer Token Usage (RFC 6750), section 3.

Resolved Issues

  • Adds refresh token decoding exception logging at debug level (issue authz-store/142).

Dependency changes

  • Upgrades to com.nimbusds:oauth2-oidc-sdk:5.35
  • Upgrades to com.nimbusds:nimbus-jose-jwt:4.41.1
  • Upgrades to com.nimbusds:oauth2-authz-store:5.17

Mutual TLS client authentication in Connect2id server 6.12

Posted on 2017-08-07

We are pleased to announce the Connect2id server now supports client X.509 certificate authentication, bound to a public RSA or EC JWK which the client has registered with the server. Open banking applications in Europe, where X.509 certificate based authentication is required by law, will find this new method indispensable.

The OAuth working group is developing the client certificate based authentication as part of the Mutual TLS Profile for OAuth 2.0. The profile includes another great security feature that prevents access token phishing. This is achieved by binding the token to the client’s X.509 certificate. This feature will be implemented in the next Connect2id server release.

Client X.509 certificate authentication will also work when the HTTPS connections are terminated at a TLS proxy. Check out our guide for that.


To download a ZIP package of Connect2id server 6.12:


(SHA-256: c18eb19a13a6041dfd9308dc59d62ad70bc0bbecc6a9db391091014d6c495806)

As WAR package only:


(SHA-256: ac3ed2f14228c1335e67a6328e7f668b3ea834511895addf124bc309c8226645)


Get in touch with Connect2id support.

Release notes

6.12 (2017-08-07)


  • Adds support for public key bound TLS client authentication (pub_key_tls_client_auth) at the token endpoint, as specified in Mutual TLS Profile for OAuth 2.0 (draft-ietf-oauth-mtls-03), section 2.1.


  • /WEB-INFO/oidcProvider.properties

    • op.token.authMethods — Supports pub_key_tls_client_auth for indicating public key bound TLS client authentication, as specified in Mutual TLS Profile for OAuth 2.0 (draft-ietf-oauth-mtls-03), section 2.1.

    • op.tls.clientX509CertHeader — New optional configuration property. Sets the name of the HTTP header to receive validated self-signed client X.509 certificates (PEM-encoded) from a TLS termination proxy. Intended for use in public key TLS client authentication (pub_key_tls_client_auth) only. The header name must be kept confidential between the TLS termination proxy and the Connect2id server and must include at least 32 random alphanumeric characters to make brute force guessing impractical. If not specified or commented out use of a TLS termination proxy for public key TLS client authentication is disabled.


  • /authz-sessions/rest/v3, /authz-sessions/rest/v2

    • The optional authorisation session "data" JSON object field is now also included in the final response message.

Resolved issues

  • Fixes NPE when logging none configured advertised ACR values at Connect2id server startup (issue server/301).
  • Reduces frequency of reaping orphaned subject/N entries in the session store from once every 5 minutes to once per 24h to reduce effect on touching the last-used timestamp of subject sessions (issue session-store/63).
  • Includes the name of the submitted client authentication method in a token error response message indicating the submitted client authentication method is not supported by the Authorisation Server.

Dependency changes

  • Upgrades to com.nimbusds:oauth2-oidc-sdk:5.34.2
  • Upgrades to com.nimbusds:nimbus-jose-jwt:4.41
  • Upgrades to com.nimbusds:oidc-session-store:5.2.5
  • Upgrades to org.cryptomator:siv-mode:1.2.1
  • Upgrades to Infinispan 8.2.7
  • Upgrades to org.jooq:jooq:3.9.4
  • Upgrades to com.zaxxer:HikariCP:2.6.3
  • Upgrades to org.mariadb.jdbc:mariadb-java-client:2.0.3
  • Upgrades to org.postgresql:postgresql:42.1.3
  • Upgrades to io.prometheus:simpleclient:0.0.25
  • Upgrades to io.prometheus:simpleclient_servlet:0.0.25
  • Upgrades to io.prometheus:simpleclient_dropwizard:0.0.25
  • Upgrades to com.thetransactioncompany:cors-filter:2.6

Key takeaways from the OAuth security workshop in Zürich

Posted on 2017-07-21

The 2017 OAuth Security Workshop at the ETH in Zürich was packed with useful talks. Here are the key takeaways.

Best practices for native OAuth apps

Check out the best practices for OAuth apps, presented by John Bradley and William Denniss. The slides are based on the formal BCP document that is being edited the OAuth WG.

Are you developing native apps that require OAuth? The AppAuth libraries developed by the great community at OpenID support Android, iOS as well as NativeJS.

John also updated us on the upcoming SafariViewController changes in iOS 11 and that we’ll have to rely on SFAuthenticationSession instead, in order to achieve SSO between apps and the system browser.

OAuth for JavaScript apps

Jacob Ideskog presented a nice framework for simplifying OAuth and OpenID Connect integration in JavaScript apps. The app can obtain the tokens it needs by simply posting a message to an iframe loaded from the authorisation server / IdP.

OAuth is becoming the new "password"

The proliferation of OAuth 2.0 applications, even to areas like finance, means we must take greater care to secure tokens, through their entire lifecycle — how they are obtained, relayed and consumed. Deployments are also turning more dynamic. This means the basic OAuth 2.0 framework (RFC 6749) published in 2012 is no longer adequate. Security must be enhanced, across the board.

We need more science, i.e. formal analysis, in protocol design

The design of security protocols, like TLS, has been treated like art for a long time. But that’s not good enough. We need more science, meaning formal analysis, to be confident that the desired security properties of the protocols we craft are actually met, and critical bits don’t get overlooked.

  • David Basin from the ETH demonstrated the power of formal analysis tools, used for example, to uncover a terrible security omission in the ISO/IEC 9798 protocol.

  • Cas Cremers made a reassuring presentation that formal analysis has been taken up by the TLS 1.3 working group, to good effect. The whole Internet security relies on TLS, so we must seek to have total confidence in the protocol.

  • Daniel Fett, Ralf Kuesters, and Guido Schmitz from Uni Stuttgart presented their in-depth analysis of OpenID Connect and the conclusion that within their formal model, the protocol is secure. This is great news!

Crypto: Validate all EC keys that you deal with

Antonio Sanso presented the invalid curve attack and how it can lead to JWE ECDH exploits. The lesson: Always validate the curves of EC keys you’re dealing with. In the Nimbus JOSE+JWT library we now perform these validations at EC JWK construction time, even before any crypto operations are attempted with them.