PingAM 7.5.1

Mutual TLS

Clients can authenticate to AM by using mutual TLS (mTLS) and X.509 certificates. The certificates are either self-signed or use public key infrastructure (PKI), per version 12 of the draft OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound Access Tokens specification.

AM also supports the Certificate Bound Access Tokens part of the specification. For more information, refer to Certificate-bound proof-of-possession.

Mutual TLS using PKI

To authenticate OAuth 2.0 clients with mTLS, the certificate presented by the client must have a subject-distinguished name that matches exactly a value specified in the client profile in AM.

The Certificate Authority specified in the chain must also be trusted by AM. You can configure secret a mapping with the secret label am.services.oauth2.tls.client.cert.authentication to specify which certificate authorities AM trusts.

Configure AM for mutual TLS using PKI

Follow the steps in this procedure to configure AM to support mutual TLS using PKI.

  1. If you haven’t already done so, create an OAuth 2.0 client profile in AM.

    For more information, refer to Client application registration.

  2. Set up a secret store in the same realm as the OAuth 2.0 client.

    AM maintains the details of trusted certificate authorities in this secret store.

    You can use an existing secret store or create a new store as follows:

    • In the AM admin UI, go to Realms > Realm Name > Secret Stores, and click Add Secret Store.

    • Enter an ID for the secret store (for example, TrustStore), select the store type, complete the required fields, and click Create.

      You may need to configure the credentials for accessing the new store in one of the other configured secret stores. For more information on configuring secret stores, refer to Secrets, certificates, and keys.

  3. Import the certificates belonging to the certificate authorities you want the instance of AM to trust.

  4. Map the aliases of the imported certificates to the am.services.oauth2.tls.client.cert.authentication secret label:

    • In the AM admin UI, go to Realms > Realm Name > Secret Stores > Store Name > Mappings, and click Add Mapping.

    • In the Secret Label field, select am.services.oauth2.tls.client.cert.authentication.

    • In the Aliases field, enter the alias of the imported CA certificate to trust, and click Add.

    • Repeat the previous step to add the aliases of all the CA certificates to trust, and click Create.

  5. Add the subject-distinguished name that must appear in the client certificate to be able to authenticate:

    • In the AM admin UI, go to Realms > Realm Name > Applications > OAuth 2.0 > Agent Name > Signing and Encryption.

    • In the mTLS Subject DN field, enter the distinguished name that must exactly match the subject field in the client certificate. For example, CN=myOauth2Client.

      If this field is left empty, the default value that must be found in a CA-signed client certificate is CN=Client ID. For example, CN=myMTLSClient.

    • Save your changes.

  6. Configure the OAuth 2.0 provider to check whether the certificates presented by the authenticating clients have been revoked:

    • In the AM admin UI, go to Realms > Realm Name > Services > OAuth2 Provider > Advanced.

    • Enable Check TLS Certificate Revocation Status.

    • In the OCSP Responder URI field, enter the URI of the online certificate status protocol responder service. AM will use this service to check the certificates.

      If not specified, AM determines the appropriate URI from the certificate.

    • In the OCSP Responder Certificate field, enter the PEM-encoded certificate that AM will use to verify all OCSP responses.

      If not specified, AM determines the appropriate certificate from the trusted CA certificates configured in the am.services.oauth2.tls.client.cert.authentication secret label.

AM is now configured to accept CA-signed client certificates for authentication. For information on how to present the certificates when authenticating, refer to Providing client certificates to AM.

Mutual TLS using self-signed X.509 certificates

This method of authenticating OAuth 2.0 clients requires that the self-signed X.509 certificate presented by the client matches exactly a certificate specified in the client profile in AM.

You can specify the expected self-signed X.509 certificate in the client profile using one of the following methods:

  • JSON Web Key Set (JWKS)

    Specify the X.509 certificates in the X.509 Certificate Chain (x5c) attribute of the one or more JSON Web Keys specified in the set.

  • JSON Web Key Set URI (JWKS_uri)

    AM periodically retrieves the JWKS from the specified URI, and uses the certificates provided in the X.509 Certificate Chain (x5c) attribute to verify the client certificate.

  • Store the X.509 certificate as a secret in the secret store.

  • Store the X.509 certificate in the configuration.

    Add the content of the X.509 certificate as-is into the client profile.

    Unlike the other methods, only a single certificate can be specified using this method.

Configure AM for Mutual TLS using self-signed X.509 certificates

Follow the steps in this procedure to configure AM to support mutual TLS using self-signed certificates.

  1. If you haven’t already done so, create an OAuth 2.0 client profile in AM.

  2. To provide the X.509 certificates the client will use to authenticate, go to Applications > OAuth 2.0 > Agent Name > Signing and Encryption, and then perform one of the following steps:

    1. Use a JSON Web Key Set (JWKS) to specify the certificates:

      • Set the Public key selector property to JWKs.

      • Enter the contents of the JWKS in the Json Web Key property.

    2. Use a JSON Web Key Set URI (JWKS_uri) to specify the certificates:

      • Set the Public key selector property to JWKs_uri.

      • Enter the JWKS URI in the Json Web Key URI property.

    3. Store the X.509 certificate as a secret in a secret store:

      • Follow the steps in Secret stores to add the certificate as a secret.

      • Map this secret to the am.applications.oauth2.client.identifier.mtls.trusted.cert secret label, where identifier is the value of the Secret Label Identifier configured for the client on the Core tab.

    4. Use the contents of an X.509 certificate:

      • Set the Public key selector property to X509.

      • In the mTLS Self-Signed Certificate field, enter the content of the X.509 certificate in PEM format.

        You can include or exclude the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- labels.

        OIDC clients must also specify the authentication method they are using in their client profiles. See OIDC client authentication.

  3. Save your changes.

AM is now configured to accept self-signed client certificate for authentication. For information on how to present the certificates when authenticating, refer to Providing client certificates to AM.

Providing client certificates to AM

The client can provide its certificate to AM using either standard TLS client certificate authentication or trusted headers.

You must configure the web container in which AM runs to use TLS connections, and to request and accept client certificates.

Consult the documentation for your web container to determine the appropriate actions to take.

  1. Standard TLS client certificate authentication

    The client provides its certificates in the standard servlet client certificate attribute.

    This is the preferred method, as the web container will verify that the client authenticated the TLS session with the private key associated with the certificate.

    After configuring AM to accept client certificates, the client can authenticate to the OAuth 2.0 access_token endpoint using one of the X.509 certificates registered in the client.

    Any of the OAuth 2.0 grant flows that makes a call to the access_token endpoint can authenticate clients using X.509 certificates. The following example uses grant_type=client_credentials and attaches the client certificates to the request:

    $ curl \
    --request POST \
    --data "client_id=myClient" \
    --data "grant_type=client_credentials" \
    --data "scope=write" \
    --data "response_type=token" \
    --cert "myClientCertificate.pem" \
    --key "myClientCertificate.key.pem" \
    "https://openam.example.com:8443/openam/oauth2/realms/root/realms/alpha/access_token"
    {
      "access_token": "sbQZuveFumUDV5R1vVBl6QAGNB8",
      "scope": "write",
      "token_type": "Bearer",
      "expires_in": 3599
    }
  2. Trusted headers

    AM receives the certificates in a configured, trusted HTTP header.

    This method is intended for cases where TLS is being terminated at a reverse proxy or load balancer, and therefore, the container in which AM runs is not directly able to authenticate the client.

    You must configure the proxy or load balancer to:

    1. Forward the certificate to AM in the trusted header.

      AM supports receiving certificates in the following formats:

      • Raw PEM-encoded.

      • PEM-encoded first, then URL-encoded, for compatibility with the NGINX $ssl_client_escaped_cert variable.

      • PEM-encoded first, URL-encoded next, and then included as a field in a multi-field trusted header, for compatibility with the Envoy x-forwarded-client-cert headers.

    To specify the format of the trusted header, go to Realms > Realm Name > Services > OAuth2 Provider > Advanced, and choose the appropriate value in the TLS Client Certificate Header Format drop-down list:

    • Use URLENCODED_PEM for raw PEM and NGINX-like URL-encoded formats.

    • Use X_FORWARDED_CLIENT_CERT for the Envoy-like format.

      1. Strip the trusted header from any incoming requests.

        This is because AM has no way of authenticating the contents of this header, and so would trust whatever is present.

        To specify the name of the trusted header, in the AM admin UI, go to Realms > Realm Name > Services > OAuth2 Provider > Advanced, and enter the header name in the Trusted TLS Client Certificate Header property.

        Specify a strong, random name for the trusted header. A misconfigured proxy or load balancer could let an attacker send malicious header values. A trusted header name that’s difficult to guess makes this type of attack more difficult.