By default, SAS Logon Manager uses a registered client_id and client_secret to authenticate itself to your Microsoft Entra ID Tenant. SAS Logon Manager must authenticate to exchange the Authorization Code for an ID Token when using OpenID Connect authentication with Entra ID. Microsoft refers to this as client_secret in their documentation. With SAS Viya 2024.03 SAS Viya now also supports the use of private_key_jwt for the authentication of SAS Logon Manager to Microsoft Entra ID. In this post we’ll look at why you might want to use private_key_jwt and how you can configure this.
Why use private_key_jwt
The Microsoft documentation states:
SOMETIMES CALLED A PUBLIC KEY, A CERTIFICATE IS THE RECOMMENDED CREDENTIAL TYPE BECAUSE THEY'RE CONSIDERED MORE SECURE THAN CLIENT SECRETS.
The same documentation also states:
CLIENT SECRETS ARE CONSIDERED LESS SECURE THAN CERTIFICATE CREDENTIALS. APPLICATION DEVELOPERS SOMETIMES USE CLIENT SECRETS DURING LOCAL APP DEVELOPMENT BECAUSE OF THEIR EASE OF USE. HOWEVER, YOU SHOULD USE CERTIFICATE CREDENTIALS FOR ANY OF YOUR APPLICATIONS THAT ARE RUNNING IN PRODUCTION.
Further details are available in the Microsoft Security Best Practices for App Registration.
Private Key JWT is a method of client authentication where the client creates and signs a JWT using its own private key. This method is described in a combination of RFC 7521 (Assertion Framework) and RFC 7523 (JWT Profile for Client Authentication), and referenced by OpenID Connect and FAPI 2.0 Security Profile.
Using private_key_jwt means that no secret is shared between SAS Logon Manager and Entra ID. The private_key_jwt mechanism is based on asymmetric cryptography rather than symmetric cryptography which offers stronger algorithms. Also, the use of private_key_jwt is a requirement for the Open Banking APIs under the Financial Grade API (FAPI).
So, we can see you might want to move to using private_key_jwt instead of client_secret; either because of regulatory requirements, or generally because you want to improve the security of the OIDC implementation you are using.
Configuring private_key_jwt
The SAS documentation covers the steps to configure JWT Client Authentication with Microsoft Entra ID. You will need to complete steps in both SAS Viya and your Entra ID tenant.
SAS Viya 2024.01 introduced an update to the sas.logon.oauth.providers configuration. This update is the addition of the property jwtclientAuthentication. The jwtclientAuthentication property has the description: "Use OIDC private key JSON web tokens (JWTs) for client authentication. The public key must be registered with the provider. Only effective if relyingPartySecret is not set." This is a Boolean property so can either be turned on or turned off, the default value is false or turned off.
Therefore, if we want to use private_key_jwt with Microsoft Entra ID we must change both jwtclientAuthentication and relyingPartySecret. The property jwtclientAuthentication must be turned on or set to true. At the same time the value of relyingPartySecret must be removed or set to the empty string. Then we need to consider how to register the public key with our Microsoft Entra ID tenant.
SAS Logon Manager automatically generates a public/private key pair that is used to sign the JSON Web Tokens that are provided to the SAS Viya web applications and other clients of SAS Logon Manager. The public key is then made available to consumers by SAS Logon Manager at its jwks_uri endpoint. However, the public key part is not wrapped inside an X509 certificate object. Microsoft Entra ID will only accept the public key when it is wrapped inside an X509 certificate. The changes introduced with SAS Viya 2024.03 allow us to replace the existing public/private key pair with a private key and associated X509 certificate containing the public key.
One major advantage of using a X509 certificate to hold the public key is that this has a built-in expiry, ensuring that you regularly rotate the credential used by SAS Logon Manager to authenticate to Microsoft Entra ID. Microsoft recommends using a X509 certificate signed by a public Certificate Authority for applications deployed to production. However, you can use self-signed X509 certificates, but Microsoft recommends these are only used for testing. Microsoft even provides documentation for creating a self-signed public certificate to authenticate your application which uses PowerShell to create the private key and self-signed certificate. Alternatively, you could use OpenSSL to do the same thing. For example, the following commands will create a private key and self-signed certificate:
mkdir -p ~/OIDC_Certs
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
-subj "/ST=SelfSigned/CN=SASLogonSigningKey" \
-keyout ~/OIDC_Certs/SASLogonSigning.key \
-out ~/OIDC_Certs/SASLogonSigning.cert
openssl rsa -in ~/OIDC_Certs/SASLogonSigning.key -out ~/OIDC_Certs/SASLogonSigningRSA.key
The resulting private key (~/OIDC_Certs/SASLogonSigningRSA.key) and X509 Certificate (~/OIDC_Certs/SASLogonSigning.cert) need to be provided to SAS Logon Manager. This is provided in the sas.logon.jwt configuration, you could use SAS Environment Manager or the SAS Viya CLI to add this configuration. For example, the following commands will create a JSON configuration file with the required contents and apply this with the SAS Viya CLI:
# Clean up files for use in JSON configuration
sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g' ~/OIDC_Certs/SASLogonSigningRSA.key > ~/OIDC_Certs/JSON.key
sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g' ~/OIDC_Certs/SASLogonSigning.cert > ~/OIDC_Certs/JSON.crt
# Find the correct URL for SAS Logon Manager
NS=name-of-namespace ;\
logon_host=`kubectl -n ${NS} get ing sas-logon-app -o=jsonpath='{.spec.tls[0].hosts[0]}'` ;\
# Create JSON Configuration
mkdir -p ~/JSON
tee ~/JSON/OIDCSigning.json > /dev/null << EOF
{
"name": "addOIDCSigning",
"items": [
{
"version": 1,
"metadata": {
"allowUserProperties": true,
"isDefault": false,
"mediaType": "application/vnd.sas.configuration.config.sas.logon.jwt+json;version=7"
},
"signingKey": "$(<~/OIDC_Certs/JSON.key)",
"signingCert": "$(<~/OIDC_Certs/JSON.crt)",
"issuer.uri": "https://${logon_host}/SASLogon"
}
]
}
EOF
# Use SAS Viya CLI to apply configuration
/opt/sas/viya/home/bin/sas-viya auth login;\
/opt/sas/viya/home/bin/sas-viya configuration configurations create \
--file ~/project/deploy/gelenv/site-config/JSON/OIDCSigning.json; \
/opt/sas/viya/home/bin/sas-viya auth logout
SAS Logon Manager will now use this private key to sign all JSON Web Tokens that are generated. This means the JSON Web Token (JWT) used to authenticate to Microsoft Entra ID as well as all JWTs used within the SAS Viya environment. For the other SAS Viya web applications and services to be able to use these JWTs they must be able to validate the signature. The SAS Viya web applications and services will retrieve the public key they use to validate the signature automatically on start-up. As such, since you have just changed the public/private key pair you must now restart the SAS Viya environment. You can use the sas-stop-all and sas-start-all CronJobs in order to restart all services.
Remember you will need to repeat these steps in the future when you need to rotate the private key and X509 certificate, when the certificate expires.
Once SAS Logon Manager is configured and all services have restarted you can add the certificate to your Microsoft Entra ID App Registration. This is covered in the SAS documentation and Microsoft documentation. You will need to complete the following steps:
Log in to the Azure portal.
On the Home page, click Microsoft Entra ID from the list of Azure services.
In the Entra ID interface, click App registrations in the left pane.
In the list of Owned applications, select your SAS Viya application.
In the left pane, click Certificates & secrets.
Click the Certificates tab.
Click Upload certificate to configure a new certificate.
In the Upload certificate window, click the Browse button to locate the CER, PEM, or CRT file on your hard drive. Note: Microsoft requires a Base64-encoded X509 certificate based on private/public keys.
Specify a Description to identify the certificate.
Click Add.
The Thumbprint, start date, expiration date, and Certificate ID will be generated and the resulting screen in the Azure portal should look like the following:
Select any image to see a larger version. Mobile users: To view the images, select the "Full" version at the bottom of the page.
Validating New Signing Private/Public Key
Once your SAS Viya environment is up and running you can validate that the new private/public key pair are being used to sign the JSON Web Tokens used inside the environment. First, we’ll examine the JSON Web Key Set (JWKS) endpoint for SAS Logon Manager to ensure the new public key information is present. We can just use CURL to return the contents of the JWKS endpoint:
curl -s https://${logon_host}/SASLogon/token_keys |jq -r
We expect to see something like the following:
{
"keys": [
{
"kty": "RSA",
"x5t#S256": "mo9hdOWsjOUdDJab1lddtOcX_P8e4ZHXXeKckLgtAS4",
"e": "AQAB",
"use": "sig",
"x5t": "JkZEK5rFR2YMem2aXgFvwiA23dk",
"kid": "legacy-token-key",
"x5c": [
"MIIFNzCCAx +gAwIBAgIJAMIS0J74K19eMA0GCSqGSIb3DQEBCw...aeS28iTpRhJfPaQ=="
],
"alg": "RS256",
"value": "-----BEGIN PUBLIC KEY-----\nMIICIjANBg...AwEAAQ==\n-----END PUBLIC KEY-----",
"n": "r0t4gcdw2...MmzvLp6xgQ7TiwAcKSc "
}
]
}
The important parts of this output are:
x5c which is the X509 public key certificate
x5t which is the base64url-encoded SHA-1 thumbprint (a.k.a. digest) of the DER encoding of the X.509 certificate
x5t#S256 which is the base64url-encoded SHA-256 thumbprint (a.k.a. digest) of the DER encoding of the X.509 certificate
If these fields are included in the output, then our new public key wrapped in a X509 certificate is being used.
Second, we can inspect a token generated by SAS Logon Manager. The easiest way to validate this is to complete the following:
Log into SAS Studio and launch a SAS Compute Server
Run the following code to display the current SAS_SERVICES_TOKEN:
%put %sysget(SAS_SERVICES_TOKEN);
In the SAS log the current value of the SAS_SERVICES_TOKEN will be displayed and can be copied
Use https://jwt.io to inspect the contents of the SAS_SERVICES_TOKEN
In the Verify Signature section paste the X509 Certificate and corresponding private key contents
You should see the following to show the signature has been successfully validated:
Conclusion
The introduction of support for using private_key_jwt as the client authentication mechanism for OpenID Connect configuration strengthens the security of the OIDC configuration. It also allows for support of the Open Banking APIs under the Financial Grade API (FAPI). With SAS Viya 2024.01 Stable release support for private_key_jwt was introduced with OKTA; the 2024.03 release has added support with Microsoft Entra ID. The support for Microsoft Entra ID depends upon the ability to specify a X509 certificate to contain the public key used by SAS Logon Manager.
If you want to explore this topic in more detail, you can refer to Course: Advanced Topics in Authentication on SAS Viya.
Find more articles from SAS Global Enablement and Learning here.
... View more