Using Subject Alternative Names to Authenticate OAuth Clients

“Nothing has paid more mortgages than certificates,” we often say at Curity. By this, we mean that certificates are a hard technology to work with and that we’ve all sunk lots of time into them. From my labors, I know enough about certificates to know that I have an intermediate understanding of them and am by no means an expert. However, I recently took a step closer though as I learned about Subject Alternative Names (SANs).

This certificate attribute came up when a customer wanted to register an OAuth client with the metadata described in section 2.1.2 of RFC 8705. To be honest, I always skimmed that section, so I had to reread it. When I did, I saw that four SAN-related fields were described:

  1. tls_client_auth_

    san_dns

  2. tls_client_auth_

    san_uri

  3. tls_client_auth_

    san_ip

  4. tls_client_auth_

    san_email

(That section also defines tls_client_auth_subject_dn, which we already support.)

So, what is a SAN? It’s an extension attribute that can be added to an X.509 certificate. When a Certificate Authority (CA) signs a certificate, it can embed not only the Distinguished Name (DN) into the certificate, but also alternative names. When it does, the SAN actually should be used in lieu of the DN. Here’s an example of one (where I’ve elided and formatted the content to show only the DN and SAN):

$ openssl x509 -noout -text -in my-good-cert.pem Certificate: Subject: C=SE, L=Stockholm, O=Curity, OU=IT, CN=client3 X509v3 extensions: X509v3 Subject Alternative Name: IP Address:127.0.0.1, DNS:client3.example.com, DNS:client3.local, URI:https://client3.curityio.net, URI:uuid:DEB5180B-BA52-40D5-97C1-15417A486B41, email:test@curity.io

This snippet uses OpenSSL’s x509 command to show the parsed value of an X.509 certificate with multiple SANs. The “Subject” value is the DN of the certificate. The SAN is part of the “extensions” section of the certificate. There are alternative names in multiple formats, including an IP address, a couple of DNS names, URIs, and an email address. This certificate would allow a client to authenticate itself by registering or being configured at the OAuth authorization server with any of those alternative names.

From this example, you can see that a SAN is nothing magical. It’s just another name for the subject (i.e., the entity to whom the certificate is issued).

Importance of SANs

If a certificate has a name (the DN), you may wonder why it needs alternatives. One answer I arrived at was that if the DN includes values that change or are temporary, the DN is probably not a stable identifier and will require effort to maintain. For instance, the DN above has an Organizational Unit (OU) of IT. If we were to reorganize and manage our certificates in the infrastructure or security group, the DN would change, but the OAuth client would remain the same. As a result, systems would have to be reconfigured with the updated DN. Alternatively, we could use a SAN (like the GUID URI), and organizational changes would not impact the various systems. In general, using a SAN is a good idea when a DN contains temporal or mutable values or the subject can simply be identified by multiple names. Other use cases include when a DN contains a business address or even a business name.

Use of SANs in SPIFFE

A growing use of SANs is when deploying SPIFFE. SPIFFE is an open-source standard that helps authenticate software systems like microservices. This standard is implemented in a runtime where the reference implementation is called SPIRE. A novel use case in SPIFFE SPIRE deployments is to convert an X.509 certificate into a JWT to be consumed by a microservice.

The X.509 certificates in a SPIRE deployment typically include temporal data and are very short-lived. For this reason, configuring the OAuth client (that will authenticate to the Curity Identity Server) with a static DN increases the maintenance costs — using a DN would require very frequent updates to the OAuth configuration. Instead, one of the more stable SAN values (like a URI) should be used (e.g., something like spiffe://example.com/client1). This will allow the microservice consumer (the OAuth client) to get new X.509 certificates and still be able to authenticate to Curity’s token service without any reconfiguration or synchronization required.

The point of authenticating to the OAuth server is to obtain new JWTs. One element that must go into this JWT SVID is the subject — the DN of the certificate or parts thereof. Because this value is constantly changing, though, this also can’t be static. This is why we updated our client certificate claims provider in version 7.2 to include additional attributes like the SAN values. This makes it easy to authenticate using a SAN and placing the DN, parts of the DN, or a combination of DN values and SAN values into the final sub claim of the JWT.

Learn More

As I mentioned, there’s a lot to learn about certificates. In this post, I merely introduced the idea of a SAN and how you can use them in version 7.2.0 of the Curity Identity Server. To learn more, check out our new resource on the subject and contact us with any questions you may have.

Join The Discussion

Follow @curityio on Twitter