More information is available at https://ras44.github.io/blog/2019/01/19/keeping-credentials-secret-with-keyrings-in-r.html.
We often need to provide credentials to access resources such as databases. Hardcoding these credentials is frowned upon as it could lead to these credentials being exposed (e.g. committed to GitHub). To protect this information, we can store passwords, tokens, and other sensitive information in a keyring using the keyring library. The code presented below is available in GitHub at https://github.com/NACHC-CAD/r-keyring.
The following code shows the create_keyring function defined in the r-keyring project.
# --- # # function to create a keyring # # --- # installs # install.packages("keyring") # libraries library(keyring) # create the key ring create_keyring <- function(kr_name, kr_service, kr_username) { kb <- keyring::backend_file$new() kb$keyring_create(kr_name) kb$set(kr_service, username = kr_username, keyring = kr_name) kb$keyring_lock(kr_name) }
When this code is call, you will be asked to enter a keyring
password. This is the password that you use when you want to retrieve
your password or token. In this example we use “foo”.
You will then be asked to enter a password.
This is the password or token for your database. In this example we
entered “asdf1098743n12lkjj5-MY_TOKEN-aoipuoi19087mnoipuasddf”.
# get the password from the keyring keyring::backend_file$new()$get( service = kr_service, user = kr_username, keyring = kr_name )
When you execute this code you will be asked for the password for the keyring (in this example we used “foo”).
This code will output the following.> # get the password from the keyring > keyring::backend_file$new()$get( + service = kr_service, + user = kr_username, + keyring = kr_name + ) [1] "asdf1098743n12lkjj5-MY_TOKEN-aoipuoi19087mnoipuasddf"
# # functions to get databricks token (user will be prompted for keyring password) # getToken <- function () { return ( keyring::backend_file$new()$get( service = "databricks", user = "token", keyring = "databricks_keyring" ) ) } # # functions to get databricks token (user will be prompted for keyring password) # getUrl <- function () { url <- "jdbc:databricks://nachc-databricks.cloud.databricks.com:443/default;transportMode=http;ssl=1;httpPath=sql/protocolv1/o/3956472157536757/0123-223459-leafy532;AuthMech=3;UseNativeQuery=1;UID=token;PWD=" return ( paste(url, getToken(), sep = "") ) }
You should be able to run the code in the r-keyring
project shown below as is to store your Databricks token. You will be
asked to enter a password for the keyring and your Databricks token.
# --- # # example script to create/delete a keyring # # --- # installs # install.packages("keyring") # libraries library(keyring) # source source("CreateKeyRing.R") source("DeleteKeyRing.R") # variables kr_name <- "databricks_keyring" kr_service <- "production" kr_username <- "token" kb <- keyring::backend_file$new() # list existing keyrings (before) kb$keyring_list() # delete existing delete_keyring(kr_name) create_keyring(kr_name,kr_service,kr_username) # list existing keyrings (after) kb$keyring_list() # get the token keyring::backend_file$new()$get( service = kr_service, user = kr_username, keyring = kr_name )
The code can be modified as shown below so that the key ring is only created if it does not exist.
createDatabaseKeyRing <- function(kr_name, kr_service, kr_username) { kb <- keyring::backend_file$new() # Get a list of existing keyrings existing_keyrings <- kb$keyring_list() # Check if the keyring already exists if (!(kr_name %in% existing_keyrings$keyring)) { kb$keyring_create(kr_name) kb$set(kr_service, username = kr_username, keyring = kr_name) kb$keyring_lock(kr_name) } else { print(paste("Keyring already exists for: ", kr_name)) } }