Session info and security through obscurity

R
meta
Do we need full paths everywhere?
Author

Josh

Published

2025-03-03

In my work at the Data Lab, I have become accustomed to always including session information at the end of a computational notebook. It is kind a minimal step toward reproducibility to record what versions of all of the R packages were used to generate the output.1

1 We also use renv as much as possible to make it easier to reproduce the environment we are using, but it is nice to have both.

The {session_info} package makes some of the formatting and information provided nicer, so I try to use that most places, including on this blog, though I will happily fall back to the built in sessionInfo() function if I don’t want to add dependencies.

That said, there is one thing that does annoy me, which is that the paths that are printed are full paths. I get it, but I don’t particularly like it, because it seems a minor breach of best security practices to be printing full paths on your computer all over the place. I mean, we all do it, but it doesn’t mean I like it. I also don’t think this information is particularly useful to anyone, so it seems kind of silly to include it.

For this blog then, I wanted to strip out as much of that info as possible. Since I use {renv} most of the time, I expect most paths to be nestled somewhere under the path given by renv::paths$root(). Anything else in the project directory will be somewhere inside the path defined by here::here() (the core function of the wonderful {here} package). So I start by stripping those out, as well as anything under a common home path, replacing the values with the environment variable that they would use.

Here is the function I wrote to do that2:

2 The last str_replace() strips out anything in /User or /home subdirectories, which may not actually be the same as ${HOME}, but it is likely somebody’s home. So that seemed reasonable to me.

strip_paths <- function(path) {
  # replace user paths with variables
  path |>
    stringr::str_replace(
      stringr::fixed(renv::paths$root()),
      "${RENV_PATHS_ROOT}"
    ) |>
    stringr::str_replace(
      stringr::fixed(here::here()),
      "${PROJECT_ROOT}"
    ) |>
    stringr::str_replace(
      stringr::fixed(paste0(fs::path_home(), "/")),
      "${HOME}/"
    ) |>
    stringr::str_replace(
      stringr::regex(
        "/(Users|home)/[^/]+/",
        ignore_case = TRUE
      ),
      "${HOME}/"
    )
}

I then use that function to relabel the factors in the $packages$library slot of the object created by sessioninfo::session_info(). Print that out instead of the original object, and there we are.

You can see the full code and results below. It’s not perfect, but it seems to do what I want, at least for now.

R session information
Code
strip_paths <- function(path) {
  # replace user paths with variables
  path |>
    stringr::str_replace(
      stringr::fixed(renv::paths$root()),
      "${RENV_PATHS_ROOT}"
    ) |>
    stringr::str_replace(
      stringr::fixed(here::here()),
      "${PROJECT_ROOT}"
    ) |>
    stringr::str_replace(
      stringr::fixed(paste0(fs::path_home(), "/")),
      "${HOME}/"
    ) |>
    stringr::str_replace(
      stringr::regex(
        "/(Users|home)/[^/]+/",
        ignore_case = TRUE
      ),
      "${HOME}/"
    )
}


si <- sessioninfo::session_info()
si$packages$library <- forcats::fct_relabel(
  si$packages$library,
  strip_paths
)
si$platform$pandoc <- strip_paths(si$platform$pandoc)
si$platform$quarto <- strip_paths(si$platform$quarto)

si
─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.6.1 (2026-06-24)
 os       macOS Golden Gate 27.0.1
 system   aarch64, darwin23
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       America/New_York
 date     2026-10-04
 pandoc   3.8.3 @ ${HOME}/.pixi/envs/quarto/bin/ (via rmarkdown)
 quarto   1.9.38 @ ${HOME}/.pixi/envs/quarto/bin/quarto

─ Packages ───────────────────────────────────────────────────────────────────
 ! package     * version date (UTC) lib source
 P cli           3.6.6   2026-04-09 [?] CRAN (R 4.6.0)
 P digest        0.6.39  2025-11-19 [?] CRAN (R 4.6.0)
 P evaluate      1.0.5   2025-08-27 [?] CRAN (R 4.6.0)
 P fastmap       1.2.0   2024-05-15 [?] CRAN (R 4.6.0)
 P htmltools     0.5.9   2025-12-04 [?] CRAN (R 4.6.0)
 P htmlwidgets   1.6.4   2023-12-06 [?] CRAN (R 4.6.0)
 P jsonlite      2.0.0   2025-03-27 [?] CRAN (R 4.6.0)
 P knitr         1.52    2026-09-06 [?] CRAN (R 4.6.1)
 P otel          0.2.0   2025-08-29 [?] CRAN (R 4.6.0)
 P renv          1.3.0   2026-09-29 [?] CRAN (R 4.6.1)
 P rlang         1.3.0   2026-07-05 [?] CRAN (R 4.6.1)
 P rmarkdown     2.32    2026-09-01 [?] CRAN (R 4.6.1)
 P sessioninfo   1.2.4   2026-06-04 [?] CRAN (R 4.6.0)
 P xfun          0.61    2026-09-16 [?] CRAN (R 4.6.1)
 P yaml          2.3.12  2025-12-10 [?] CRAN (R 4.6.0)

 [1] ${PROJECT_ROOT}/renv/library/macos/R-4.6/aarch64-apple-darwin23
 [2] ${RENV_PATHS_ROOT}/sandbox/macos/R-4.6/aarch64-apple-darwin23/46003b10

 P ── Loaded and on-disk path mismatch.

──────────────────────────────────────────────────────────────────────────────