SLC Managing Credentials in User Programs Part 1 of 2
Context:
SLC offers three distinct deployment models: Windows Desktop, SLC Server-based, and SLC Hub.
SLC Server-based follows a traditional client/server architecture where each user
launches their own dedicated SLC process on the server. Under this model, every SAS program must include complete definitions for all required resources and dependencies within the program itself.
SLC Hub represents a modern, enterprise-grade approach that provides a collection of managed services through a centralized orchestration layer. Users connect to this
orchestration layer, while individual SAS programs and workloads are automatically distributed across load-balanced worker nodes in a scalable grid configuration.
SLC Hub enables robust governance by establishing global metadata objects—including authentication credentials, database connections, and resource definitions—that users can reference as reusable objects within their SAS programs. This eliminates the need to embed sensitive credentials or resource definitions directly in individual programs.
Additionally, SLC Hub delivers high scalability and is purpose-built to handle large-scale SAS processing workloads efficiently across the distributed infrastructure.
In cases where SLC deployments are in a non-SLC Hub deployment, the use of AUTHDOMAINs are not available.
The following use cases are best practices for handling credentials and other sensitive information in the user’s SAS language program.
The four use cases are:
- 64-bit encoding of password strings
- Extracting password strings from local environment variables
- Creation of a secure confidential JSON file where values are parsed and passed into the user’s program
- Calling an API for CyberArk or public-cloud secrets manager using either PROC HTTP or PROC Python with its requests library
Use case 4 is out of scope for now, as the author’s AWS and GCP accounts are
organizationally controlled accounts with numerous restrictions. Altair does not run CyberArk for authentication and identity services.
These use cases are listed in what we believe the most secure in ascending order.
Use Case 1: PROC PWENCODE
In this use case, user programs make a one-time call to PROC PWENCODE supplying their current password string. This procedure returns a base-64 encoded string. The encoded string is stored as clear text in the user’s program.
7 proc pwencode in=XXXXXXXXXXXXXXXXX;
8 run;
{sas001}UG9saXRlcGlhbm8zNTEj
The encoded string is valid in SAS language procedures or functions that call for a password as input. For example:
When executed by SLC, the (partial) log echoes the statements and masks the password string. See the example program in Appendix A: PROC PWENCODE.sas
29 proc sql;
30 connect to oracle (
31 user="trb"
32 password=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
33 path="localhost:1521/ORCL"
34 );
NOTE: Successfully connected to database ORACLE as alias ORACLE. 35
36 select * from connection to oracle (
37 select user, sysdate from dual
38 );
39
40 disconnect from oracle;
NOTE: Successfully disconnected from database ORACLE.
Use Case 2: Extracting password from environment variables
Reading passwords and other credential-related items from environment variables has the advantage of making these artifacts global for all users. This is particularly useful if SLC access to databases and other resources rely on a service account.
SLC processing of local environment variables on Linux differs based on the execution method. If users are using the Altair Workbench on Windows and submitting the SAS language programs to a remote server, then access to environment variables or any execution of shell scrips are handled with the named file altairslcenv.sh in the SLC home directory. Other locations are searched based on this file name.
More details about this shell script is discussed in the document entitled, “Best Practices for Administration of SLC Servers on Linux: SASAUTOS and AUTOEXEC Processing”.
For this example, we ran SLC interactively, in a non-batch mode. This means we used the local Linux editor to edit our SAS language programs and processed them through the SLC command-line processor. (Another approach is to edit the source programs with a Windows editor and use WinScp or ftp to copy them to the Linux file system).
For more details on SLC batch processing and the command-line interface, see the
document entitled, SLC Use Case: Execute Batch SAS Language Programs with cron’s Scheduler. The first half of this document describes SLC program execution through the command-line command processor.
In our example, we define the environment variable $SLC_GET_ORA_PW as a local environment variable in the .bashrc_profile file. Each time Linux starts a shell process statements in this file (located in the user’s home directory) are executed. Ours has two
lines like:
#User specific environment and startup programs
export SLC_GET_ORA_PW="{sas001}UG9saXRlcGlhbm8zNTEj"
When we execute the SAS program below the sysget() function reads the environment variable value and stores it as a global macro variable called ora_password.
data null;
call symputx('ora_password', sysget('SLC_GET_ORA_PW'), 'G');
run;
data null;
%put &ora_password;
run;
We get:
4 data null;
5 %put &ora_password;
{sas001}UG9saXRlcGlhbm8zNTEj
6 run;
We can now use the &ora_password global macro variable in either LIBANME statements used to make connection to Oracle or, in PROC SQL explicit connection strings used to connect to Oracle. See Appendix B: slc_connect_ora_env_var.sas for the example code.
When we run the code to connect to Oracle, we get:
1 data null;
2 call symputx('ora_password', sysget('SLC_GET_ORA_PW'), 'G');
3 run;
5 libname slc_2_or oracle
6 user="trb"
7 password=XXXXXXXXXXXXXXX
8 path="localhost:1521/ORCL"
NOTE: Library slc_2_or assigned as follows:
Engine: ORACLE
Physical Name: localhost:1521/ORCL
9 schema="trb";