Startup with Secrets – A Poor Man’s Approach

[This article was first published on JottR on R, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

New release: startup 0.10.0 is now on CRAN.

If your R startup files (.Renviron and .Rprofile) get long and windy, or if you want to make parts of them public and other parts private, then you can use the startup package to split them up in separate files and directories under .Renviron.d/ and .Rprofile.d/. For instance, the .Rprofile.d/repos.R file can be solely dedicated to setting in the repos option, which specifies from which web servers R packages are installed from. This makes it easy to find and easy to share with others (e.g. on GitHub). To make use of startup, install the package and then call startup::install() once. For an introduction, see Start Me Up.

ZX Spectrum animation startup::startup() is cross platform.

Several R packages provide APIs for easier access to online services such as GitHub, GitLab, Twitter, Amazon AWS, Google GCE, etc. These packages often rely on R options or environment variables to hold your secret credentials or tokens in order to provide more or less automatic, batch-friendly access to those services. For convenience, it is common to set these secret options in ~/.Rprofile or secret environment variables in ~/.Renviron – or if you use the startup package, in separate files. For instance, by adding a file ~/.Renviron.d/private/github containing:

## GitHub token used by devtools
GITHUB_PAT=db80a925a60ee5b57f323c7b3719bbaaf9f96b26

then, when you start R, environment variable GITHUB_PAT will be accessible from within R as:

> Sys.getenv("GITHUB_PAT")
[1] "db80a925a60ee5b57f323c7b3719bbaaf9f96b26"

which means that also devtools can make use of it.

IMPORTANT: If you’re on a shared file system or a computer with multiple users, you want to make sure no one else can access your files holding “secrets”. If you’re on Linux or macOS, this can be done by:

$ chmod -R go-rwx ~/.Renviron.d/private/

Also, keeping “secrets” in options or environment variables is not super secure. For instance, if your script or a third-party package dumps Sys.getenv() to a log file, that log file will contain your “secrets” too. Depending on your default settings on the machine / file system, that log file might be readable by others in your group or even by anyone on the file system. And if you’re not careful, you might even end up sharing that file with the public, e.g. on GitHub.

Having said this, with the above setup we at least know that the secret token is only loaded when we run R and only when we run R as ourselves. Starting with startup 0.10.0 (*), we can customize the startup further such that secrets are only loaded conditionally on a certain environment variable. For instance, if we instead of putting our secret files in a folder named:

~/.Renviron.d/private/SECRET=develop/

because then (i) that folder will not be visible to anyone else because we already restricted access to ~/.Renviron.d/private/ and (ii) the secrets defined by files of that folder will only be loaded during the R startup if and only if environment variable SECRET has value develop. For example,

$ SECRET=develop Rscript -e "Sys.getenv('GITHUB_PAT')"
[1] "db80a925a60ee5b57f323c7b3719bbaaf9f96b26"

will load the secrets, but none of:

$ Rscript -e "Sys.getenv('GITHUB_PAT')"
[1] ""

$ SECRET=runtime Rscript -e "Sys.getenv('GITHUB_PAT')"
[1] ""

In other words, with the above approach, you can avoid loading secrets by default and only load them when you really need them. This lowers the risk of exposing them by mistake in log files or to R code you’re not in control of. Furthermore, if you only need GITHUB_PAT in interactive devtools sessions, name the folder:

~/.Renviron.d/private/interactive=TRUE,SECRET=develop/

and it will only be loaded in an interactive session, e.g.

$ SECRET=develop Rscript -e "Sys.getenv('GITHUB_PAT')"
[1] ""

and

$ SECRET=develop R --quiet

> Sys.getenv('GITHUB_PAT')
[1] "db80a925a60ee5b57f323c7b3719bbaaf9f96b26"

To repeat what already been said above, storing secrets in environment variables or R variables provides only very limited security. The above approach is meant to provide you with a bit more control if you are already storing credentials in ~/.Renviron or ~/.Rprofile. For a more secure approach to store secrets, see the keyring package, which makes it easy to “access the system credential store from R” in a cross-platform fashion, provides a better alternative.

What’s new in startup 0.10.0?

  • Renviron and Rprofile startup files that use <key>=<value> filters with non-declared keys are now(*) skipped (which makes the above possible).

  • startup(debug = TRUE) report on more details.

  • A startup script can use startup::is_debug_on() to output message during the startup process conditionally on whether the user chooses to display debug message or not.

  • Added sysinfo() flags microsoftr, pqr, rstudioterm, and rtichoke, which can be used in directory and file names to process them depending on in which environment R is running.

  • restart() works also in the RStudio Terminal.

(*) In startup (< 0.10.0), ~/.Renviron.d/private/SECRET=develop/ would be processed not only when SECRET had value develop but also when it was undefined. In startup (>= 0.10.0), files with such <key>=<value> tags will now be skipped when that key variable is undefined.

To leave a comment for the author, please follow the link and comment on their blog: JottR on R.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)