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.
Watch the recorded presentation, including several short demonstrations:
Let's see in more detail the needed components.
We might discuss the Azure components in a future post.
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.
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'] = '***'
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.
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.
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:
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.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.
Early bird rate extended! Save $200 when you sign up by March 31.
SAS Explore 2023 presentations are now available! (Also indexed for search at lexjansen.com!)
View all available SAS Explore content by category: