Skip to content

Commit

Permalink
Merge pull request #6 from FRBCesab/2024-03-12-storing-secrets-with-t…
Browse files Browse the repository at this point in the history
…he-renviron-file

new post: storing secrets with .Renviron
  • Loading branch information
CamilleCoux authored Mar 14, 2024
2 parents 2954f40 + fcebfd1 commit 926365a
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
title: "Storing secrets with the .Renviron file"
author: "Nicolas Casajus"
date: "2024-03-12"
categories: [r, secret, .renviron, security]
image: "logo-r.png"
toc: true
draft: true
---


## Introduction

What is a secret? It is usually a password, an username or an API token (key) required by services. For instance, some {{< fa brands r-project >}} packages require an authentication method:

- [`usethis`](https://usethis.r-lib.org/) requires a token to control the [GitHub API](https://docs.github.com/en/rest)
- [`taxize`](https://docs.ropensci.org/taxize/) requires tokens to query API provided by several taxonomic databases
- [`rwosstarter`](https://frbcesab.github.io/rwosstarter/) requires a token to access the [Web of Science API](https://developer.clarivate.com/apis/wos-starter)
- [`rgbif`](https://docs.ropensci.org/rgbif/) requires an username and a password associated by a [GBIF](https://www.gbif.org/) account

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

According to the [documentation of the `httr`](https://httr.r-lib.org/articles/secrets.html) 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`](https://keyring.r-lib.org/) package and the operating system’s credential store.

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


::: {.callout-tip}
## Environment variable

According to [Wikipedia](https://en.wikipedia.org/wiki/Environment_variable),

> 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 [{{< fa brands r-project >}} startup process](https://rstats.wtf/r-startup.html) is complex but one special {{< fa brands r-project >}} file is interesting for our purpose: the `.Renviron` file. This file does not contain {{< fa brands r-project >}} code: it only contains environment variables that will be pass to {{< fa brands r-project >}} at startup. It looks like:

```txt
NAME1=value1
NAME2=value2
```

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

```{r}
#| eval: false
## 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 his/her projects.

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

```txt
GITHUB_PAT='ghp_9999zzz9999zzz'
```

**N.B.** add a new empty line at the end of this file otherwise {{< fa brands r-project >}} will ignore it.


## Accessing secrets

To retrieve the value of a secret (and any environment variable), just use the function [`Sys.getenv()`](https://stat.ethz.ch/R-manual/R-patched/library/base/html/Sys.getenv.html).

```{r}
#| eval: false
## 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 envrionment 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 {{< fa brands r-project >}} 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)


::: {.callout-important}
## `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><br>
<https://resources.numbat.space/using-.rprofile-and-.html><br>
<https://cran.r-project.org/web/packages/httr/vignettes/secrets.html><br>
<https://www.r-bloggers.com/2024/02/key-advantages-of-using-the-keyring-package/>

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 926365a

Please sign in to comment.