BookmarkSubscribeRSS Feed

Guarding Secrets in SAS® Programs With Azure Key Vault

Started ‎09-29-2023 by
Modified ‎11-17-2023 by
Views 1,549

In the ever-evolving landscape of application security, inadvertently exposing sensitive information like API keys, database credentials or private keys remains a critical mistake. With code repositories like Git being widely used, secrets can easily infiltrate your code base, whether it's SAS, Python or any other files, leaving your application vulnerable. Azure Key Vault is a powerful solution to prevent this security pitfall. By integrating a key vault into your development process, you can eliminate the need to store secrets in your code files. This straightforward yet highly effective approach draws inspiration from real-life scenarios: Keep your valuable assets secure and retrieve them only when necessary. Azure Key Vault provides robust protection against accidental leaks, significantly reducing the risks of compromising sensitive information. This SAS Explore presentation delved into the methods of safeguarding your code base by seamlessly retrieving secrets from an Azure Key Vault within SAS programs. Explore utilizing the Key Vault Python library, REST APIs or the Azure CLI when submitting SAS programs in batch. Bid adieu to the perils of secret exposure and elevate your code base to a secret-proof state with Azure Key Vault.

 

Presentation slides are attached to this post.

 

Recorded Presentation and Demonstrations

Watch the recorded presentation, including several short demonstrations:

  • Azure components.
  • Azure Key Vault and a secret rotation strategy.
  • Use Azure Key Vault in SAS Studio.

 

 

Let's see in more detail the needed components.

 

Components

Secrets_in_SAS_Programs_from_Azure_Key_Vault.png

 

Azure

  • Azure subscription.
  • Azure Key Vault.
  • Secret created inside the key vault.
  • Azure service principal. A service principal is a security identity used by user-created apps, services, and automation tools to access specific Azure resources. The service principal is defined in Azure as an application that you need to register. The application has three main components used to identify it, the Azure tenant ID, the client identification or the client ID and the client secret.
  • Azure Key Vault access policy. The access policy is authorizing the service principal through permissions, for example, against secret permissions. To read a secret value, you would need at list Get and List secret permissions.

 

We might discuss the Azure components in a future post.


SAS Viya

  • Python configured with SAS Viya.
  • Python packages: azure-identity, azure-keyvault-secrets.
  • Python program to retrieve secrets from the key vault.
  • SAS program which calls the Python program and makes use of the secrets.

 

Python Packages

You can install these using pip:

pip install azure-identity
pip install azure-keyvault-secrets

Specifically for SAS Viya, if you use the SAS Configurator for Open Source (which creates and executes a sas-pyconfig job), you would need to add the new packages in the change-configuration.yaml.


Python Program to Retrieve Secrets from Azure Key Vault

 

Environment Variables

 

In an environment or variable file, add the service principal details: the client ID, the client secret and the Azure tenant ID.

import os
os.environ['AZURE_CLIENT_ID'] = '***'
os.environ['AZURE_CLIENT_SECRET'] = '***'
os.environ['AZURE_TENANT_ID'] = '***'

 

Python Program

Then you can write a Python program:

# import env variables - associated with managed application (service principal)
from vars import *
print ('Requires vars.py in working directory path: ', os.getcwd())

# retrieve secret function
def retrieve_secret_from_key_vault(secretName,keyVaultName):
    import os
    from azure.identity import DefaultAzureCredential
    from azure.keyvault.secrets import SecretClient

    # retrieve variables
    KVUri = f"https://{keyVaultName}.vault.azure.net"
    AzureClientId = os.environ["AZURE_CLIENT_ID"]

  # Azure credential
    credential =  DefaultAzureCredential(managed_identity_client_id = AzureClientId,
                                         additionally_allowed_tenants=["*"])
    # source https://devblogs.microsoft.com/azure-sdk/guidance-for-multi-tenant-applications-using-the-azure-identity-libraries/

    # secret operations
    client = SecretClient(KVUri, credential)
    print(f"Retrieving your {secretName} from {keyVaultName}.")
    retrieved_secret = client.get_secret(secretName)
    return retrieved_secret.value

First, the function will confirm the Azure identity of the service principal and second, it will retrieve the secret from the key vault, if allowed by the vault policies.


The function has two inputs, the key vault name and the secret name, and one output, the secret value.

 

SAS Program


Let's look now at a SAS program, calling the Python function "infile".

 

* you might need to add the path to the location of the Python program;
proc python infile='kv_sas_get.py';
    submit;

secretName = 'postgresql-db-pass'
keyVaultName = 'my-key-vault'
secretValue = retrieve_secret_from_key_vault(secretName,keyVaultName)
print(f"Your secret is :...well...secret'")
SAS.symput('KVSecret', secretValue)
endsubmit;
options nosource nomlogic nosymbolgen;
run;

* Connect to the SQL Server and created db;
libname pgdvd clear;
libname pgdvd postgres
	server='my-postgresql.postgres.svc.cluster.local'
	port=5432
    user=sas password=&KVSecret
    database=dvdrental schema=public
	SSLMODE='prefer';

* Clear the secret macro;
%SYMDEL KVSecret;
options source mlogic symbolgen;


* Check deletion of the secret macro;
%put "Explicit secret value from Azure Key Vault via Python";
%put &KVSecret;
%put "Silent secret value from Azure Key Vault via Python";
data _null_;
	pwd = symget('KVSecret');
run;

 

First, pass a secret name and the key vault name as parameters to the Python function and the secret value is returned in a macro variable.

Second, use that macro variable to connect to your database or any other data source.

Third, pay extra attention to suppress the output in the Python And in the SAS log.

Fourth, you can test the macro variable in a libname statement to make sure that the connection is successful the Python function.


You can use Python not only to retrieve elements from the key vault, but you can also set a new version of the secret. You can delete the secret, you can update the secret, you can manage the secret then the SAS program which is making use of the Python function. See a few examples in Quickstart: Azure Key Vault secret client library for Python.


Conclusions

 

You can hard code the passwords or the secrets and hope for the best.

Or you can be security conscious and you can make your SAS programs:

  • Ready for Git.
  • Resilient if the credentials are changing.
  • Suitable for a secret rotation strategy.

A few lines written in Python next to a SAS program can make all the difference.


Therefore, consider a key vault when programming and using secrets, in particular when related to Azure resources.


 


 

Version history
Last update:
‎11-17-2023 01:37 PM
Updated by:
Contributors

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

SAS Explore 2023 presentations are now available! (Also indexed for search at lexjansen.com!)

View all available SAS Explore content by category: