Storing secrets with the .Renviron file

r
secret
.renviron
security
Author

Nicolas Casajus

Published

March 12, 2024

Introduction

What is a secret? It is usually a password, an username or an API token (key) required by services. For instance, some packages require an authentication method:

It’s tempting to record secrets as variables in R scripts. But keep in mind this:
Never share your secrets with anyone (this also includes GitHub).

According to the documentation of the httr package, there is three secure ways to store your secrets:

  • Ask for the secret each time (no permanent storage).
  • Store the secret as an environment variable.
  • Use the keyring package and the operating system’s credential store.

Here we will see how to easily store secret as an environment variable.

Environment variable

According to Wikipedia,

An environment variable is a user-definable value that can affect the way running processes will behave on a computer.

In short, it is a way to pass information to a program. Environment variable are used by many programs and operating systems and are made up of a name-value pair.

The .Renviron file

The startup process is complex but one special file is interesting for our purpose: the .Renviron file. This file does not contain code: it only contains environment variables that will be pass to at startup. It looks like:

NAME1=value1
NAME2=value2

We can use this file to store our secrets. To open (and create if necessary) the .Renviron file, run this command:

## Create (if required) and open ~/.Renviron file ----
utils::file.edit("~/.Renviron")

## Alternatively,
usethis::edit_r_environ()

This command will create an .Renviron file at the user level (i.e. in his/her HOME directory) and all environment variables defined inside will be available for all sessions.

To store a new secret, just add a new line. For instance:

GITHUB_PAT='ghp_9999zzz9999zzz'

N.B. add a new empty line at the end of this file otherwise will ignore it.

Accessing secrets

To retrieve the value of a secret (and any environment variable), just use the function Sys.getenv().

## Get secret value ----
Sys.getenv("GITHUB_PAT")

## Handle this secret securely ----
github_pat <- Sys.getenv("GITHUB_PAT")

N.B. by running Sys.getenv() without argument you will print all available environment variables.

To go further

A .Renviron file can be created at three different levels:

  • at the system level (named .Renviron.site)
  • at the user level (~/.Renviron)
  • at the project level (.Renviron)

At startup will first read .Renviron.site, then ~/.Renviron and finally the .Renviron of the project. This means that if the same environment variable is defined in ~/.Renviron (user level) and in the .Renviron of the project, the value defined in the .Renviron of the project will overwrite the one defined at the user level.

  • If you want to store a secret that be shared among projects, store it in the ~/.Renviron (user level)
  • If you want to store a secret specific to a project, store it in the .Renviron (project level)
git and .Renviron

If you create a .Renviron file at the project level, do not forget to add this file to the .gitignore. Otherwise your secret will be published on GitHub.

Resources

https://rstats.wtf/r-startup.html
https://resources.numbat.space/using-.rprofile-and-.html
https://cran.r-project.org/web/packages/httr/vignettes/secrets.html
https://www.r-bloggers.com/2024/02/key-advantages-of-using-the-keyring-package/