Skip to content

Tools to Use Secure Credentials Within R Scripts #rstats

License

Notifications You must be signed in to change notification settings

rsaporta/rcreds

Repository files navigation

Securely Incorporate Login Credentials Into R Scripts

There are two main functions in `rcreds`
* WRITE functions:  `write_credentials_to_file()` and the database version `write_db_credentials_to_file()`
* READ  functions: `read_credentials_from_file()` and the database version `read_db_credentials_from_file()`

`rcreds` allows for a secure way to code scripts that require sensitive inputs such as login credentials to databases, APIs, or other systems. Users can securely write their credentials and other sensitive information to an encrypted file on disk, and then later read those credentials back into R. 

The main concept has been adopted from 
      https://github.com/sdoyen/r_password_crypt/blob/master/crypt.R


## Overview

Many scripts require login to other systems.  The most common example is accessing data from a database. 

Most comonly, a user will simply hardcode their credentials right into their code. Avoiding this practice generally involves re-inputting passwords over and over again or nesting scripts within other scripts when scheduling tasks. 

We will assume that, by nature of searching out such a package we can avoid here the discussion of the _why_ to implement a different approach (even when _"I am the only one who will be using or accessing this"_) and simply move on to the _how_ to use.

## Usage

Let's assume you have some function which requires the use of sensitive inputs. 

```{r, echo=FALSE, results='asis'}
some_login_function <- function(username, password, separate_param) {
     ## does something with username/password
     ## ... 

      message(sprintf("some_login_function() received username = '%s' and password = '%s' and separate_param = '%s'\n   (obviously wouldn't normally output like this)", username, password, separate_param))

     return(TRUE)
}
```
 
The `rcreds` approach would be to write the credentials to an encrypted file on disk and then read and decrypt them when needed. 

## Initial Setup

The user needs to tell `rcreds` where files should be written to and read from. 
This can go in your `~/.Rprofile` file.
```{r, echo=FALSE, results='asis'}
library(rcreds)

set_default_rcreds_folder("~/.rcreds/credential_files")
set_default_rcreds_folder("~/.rcreds/db_credential_files", DB=TRUE)
set_default_rcreds_key_folder(folder="~/.rcreds/key_files")
```


## Saving Credentials

One time, write to disk
```{r, echo=FALSE, results='asis'}

## NEEDED FOR VIGNETTE -- should be in an .Rprofile file
rcreds::set_default_rcreds_folder("~/.rcreds/credential_files")
rcreds::set_default_rcreds_folder("~/.rcreds/db_credential_files", DB=TRUE)
rcreds::set_default_rcreds_key_folder(folder="~/.rcreds/key_files")


library(rcreds)

creds_info <- "for_app123_login" ## some description that will be part of the filename
key_object <- create_key(bytes=32, depth=8, verbose=TRUE)

## Save Credentials
write_credentials_to_file(username="cosmo", password="too many secrets", key=key_object, info.file_name = creds_info, verbose=TRUE)

## Save key file to a different location. 
save_key(key=key_object, zArchive_existing=FALSE, overwrite_existing=TRUE, verbose=TRUE)

```


Then in a script that needs to use the credentials, read from disk and use the list elements.
```{r, echo=FALSE, results='asis'}

key_file <- '~/.rcreds/key_files/.crypt_key.rds'
creds_file <- "~/.rcreds/credential_files/for_app123_login.credentials.creds"


creds <- read_credentials_from_file(file_full_path=creds_file, key=key_file)

## SHOWING CONTENTS FOR DEMO PURPOSES. NORMALLY DON'T DO THIS
print(creds)

## Use the credentials by refering to the elements by name
some_login_function(username = creds$username, password=creds$password, separate_param="plain example")

## altenatively can use do.call
do.call(some_login_function, c(creds, list(separate_param="do.call example")))
```


## Troubleshooting

Since we are writing to and reading from files, the user under which `R` is running must have appropriate permissions to both: the file, and the folder in which the file is located.

When this is not the case you will receive an error that will (usually) end with `probable reason 'Permission denied'`
For example: 

    Error in gzfile(file, mode) : cannot open the connection
    In addition: Warning message:
    In gzfile(file, mode) :
      cannot open compressed file '/PATH/TO/FILE/file_name.crypt_key.rds', probable reason 'Permission denied'

NOTE: You will often see this when you create the key or creds file with one user and then try to use the file with a different user. eg, did you use `sudo R` to create the files?  

RESOLUTION:  Please ensure that your user has permissions on the folder and file. (On Mac OSX and Linux systems, use `chown` and/or `chmod`). [Stackoverflow](www.stackoverflow.com) has several questions and answers on this topic.


## Issues & Feedback

Please report any issues or bugs at [the package's github page](https://github.com/rsaporta/rcreds/issues)

All pull requests will be gladly considered. 

_For tips on pull requests, checkout [this helpful blog post](http://codeinthehole.com/tips/pull-requests-and-other-good-practices-for-teams-using-github/) by codeinthehole_

About

Tools to Use Secure Credentials Within R Scripts #rstats

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages