Skip to content

PPM SSO#848

Open
gaborcsardi wants to merge 14 commits into
mainfrom
feature/ppm-sso
Open

PPM SSO#848
gaborcsardi wants to merge 14 commits into
mainfrom
feature/ppm-sso

Conversation

@gaborcsardi
Copy link
Copy Markdown
Member

@gaborcsardi gaborcsardi force-pushed the main branch 2 times, most recently from 98336c1 to 3be8440 Compare March 11, 2026 09:49
@jmwoliver
Copy link
Copy Markdown

I've been testing this and it works great! It prompts me for the browser the first time and then uses the cached token on subsequent requests. I also tested install.packages() failing against an authenticated repo. Here's the output from testing this:

% rm ~/.ppm/tokens.toml
% R
> Sys.setenv(PACKAGEMANAGER_ADDRESS = "https://solo.packagemanager.posit.co")
> options(repos = c(PPM  = "https://__token__@solo.packagemanager.posit.co/cran-auth/latest"))
> pak::pkg_install("shiny")
✔ Loading metadata database ... done

→ Will update 1 package.
→ The package (1.90 MB) is cached.
+ rlang 1.2.0 → 1.2.0 🔧
? Do you want to continue (Y/n)
ℹ No downloads are needed, 1 pkg (1.90 MB) is cached
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Got rlang 1.2.0 (aarch64-apple-darwin20) (1.62 MB)
✔ Installed rlang 1.2.0  (35ms)
✔ 1 pkg + 29 deps: kept 15, upd 1, dld 1 (1.62 MB) [11.9s]
> pak::pkg_install("tidyverse")

→ Will update 17 packages.
→ Will download 5 CRAN packages (3.72 MB), cached: 12 (19.31 MB).
+ data.table 1.18.2.1 → 1.18.4 🔧
+ dplyr      1.2.0    → 1.2.1  🔧
+ haven      2.5.5    → 2.5.5  🔧 ⬇ (1.13 MB)
+ lubridate  1.9.5    → 1.9.5  🔧
+ readr      2.2.0    → 2.2.0  🔧
+ readxl     1.4.5    → 1.4.5  🔧 ⬇ (1.09 MB)
+ rlang      1.2.0    → 1.2.0  🔧
+ S7         0.2.2    → 0.2.2  🔧
+ tidyr      1.3.2    → 1.3.2  🔧
+ tidyverse  2.0.0    → 2.0.0   ⬇ (428.84 kB)
+ timechange 0.4.0    → 0.4.0  🔧
+ tzdb       0.5.0    → 0.5.0  🔧
+ uuid       1.2-2    → 1.2-2  🔧 ⬇ (76.14 kB)
+ vctrs      0.7.2    → 0.7.3  🔧
+ vroom      1.7.0    → 1.7.1  🔧
+ xml2       1.5.2    → 1.5.2  🔧 ⬇ (994.78 kB)
+ yaml       2.3.12   → 2.3.12 🔧
? Do you want to continue (Y/n) y
ℹ Getting 5 pkgs (3.72 MB), 12 (19.31 MB) cached
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Got readr 2.2.0 (aarch64-apple-darwin20) (785.42 kB)
✔ Got dplyr 1.2.1 (aarch64-apple-darwin20) (1.52 MB)
✔ Got readxl 1.4.5 (aarch64-apple-darwin20) (400.20 kB)
✔ Got haven 2.5.5 (aarch64-apple-darwin20) (382.03 kB)
✔ Got uuid 1.2-2 (aarch64-apple-darwin20) (48.90 kB)
✔ Got timechange 0.4.0 (aarch64-apple-darwin20) (172.56 kB)
✔ Got lubridate 1.9.5 (aarch64-apple-darwin20) (991.33 kB)
✔ Got vroom 1.7.1 (aarch64-apple-darwin20) (923.27 kB)
✔ Got S7 0.2.2 (aarch64-apple-darwin20) (322.71 kB)
✔ Got xml2 1.5.2 (aarch64-apple-darwin20) (714.49 kB)
✔ Got tidyr 1.3.2 (aarch64-apple-darwin20) (1.16 MB)
✔ Got tzdb 0.5.0 (aarch64-apple-darwin20) (676.01 kB)
✔ Got rlang 1.2.0 (aarch64-apple-darwin20) (1.62 MB)
✔ Got vctrs 0.7.3 (aarch64-apple-darwin20) (1.84 MB)
✔ Got tidyverse 2.0.0 (aarch64-apple-darwin20) (427.37 kB)
✔ Got yaml 2.3.12 (aarch64-apple-darwin20) (111.84 kB)
✔ Got data.table 1.18.4 (aarch64-apple-darwin20) (2.93 MB)
✔ Downloaded 17 packages (15.03 MB) in 3.8s
✔ Installed data.table 1.18.4  (313ms)
✔ Installed dplyr 1.2.1  (312ms)
✔ Installed haven 2.5.5  (341ms)
✔ Installed lubridate 1.9.5  (338ms)
✔ Installed readr 2.2.0  (335ms)
✔ Installed readxl 1.4.5  (332ms)
✔ Installed rlang 1.2.0  (327ms)
✔ Installed S7 0.2.2  (315ms)
✔ Installed tidyr 1.3.2  (312ms)
✔ Installed tidyverse 2.0.0  (308ms)
✔ Installed timechange 0.4.0  (301ms)
✔ Installed tzdb 0.5.0  (298ms)
✔ Installed uuid 1.2-2  (291ms)
✔ Installed vctrs 0.7.3  (353ms)
✔ Installed vroom 1.7.1  (78ms)
✔ Installed xml2 1.5.2  (66ms)
✔ Installed yaml 2.3.12  (32ms)
✔ 1 pkg + 95 deps: kept 47, upd 17, dld 17 (15.03 MB) [9.1s]
> install.packages("ggplot2")
Warning: unable to access index for repository https://__token__@solo.packagemanager.posit.co/cran-auth/latest/src/contrib:
  cannot open URL 'https://__token__@solo.packagemanager.posit.co/cran-auth/latest/src/contrib/PACKAGES'
Warning: unable to access index for repository https://__token__@solo.packagemanager.posit.co/cran-auth/latest/bin/macosx/big-sur-arm64/contrib/4.5:
  cannot open URL 'https://__token__@solo.packagemanager.posit.co/cran-auth/latest/bin/macosx/big-sur-arm64/contrib/4.5/PACKAGES'
Warning message:
package ‘ggplot2’ is not available for this version of R

A version of this package for your version of R might be available elsewhere,
see the ideas at
https://cran.r-project.org/doc/manuals/r-patched/R-admin.html#Installing-packages
                                                                                                                                                                                                           
% cat ~/.ppm/tokens.toml
[[connection]]
url = "https://solo.packagemanager.posit.co"
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...."
method = "sso"

There are a few small issues I noticed:

1. TOML field names don't match the rest of the ecosystem. pak writes:

[[connection]]
url = "..."
token = "..."
method = "sso"

but both rspm login sso and posit-keyring use [[connections]] (plural), address, and auth_type. As-is, a token pak writes is invisible to the other two tools (and vice versa). The connection, url, and method fields should be updated to match the others.

2. The manual TOML writer drops unknown fields, which corrupts other tools' entries. The write function hand-builds the file emitting only the three fields it knows about, for every entry in the file:

for (conn in existing_data$connection) {
  output_lines <- c(output_lines,
    "[[connection]]",
    paste0("url = \"", conn$url, "\""),
    paste0("token = \"", conn$token, "\""),
    paste0("method = \"", conn$method, "\""),
    "")
}

So if a user runs rspm login sso against a Snowflake-backed PPM (which writes snowflake_connection = "..." per entry) and then runs pak::pkg_install(...) against a different host, pak rewrites the file and the Snowflake field on the other entry is silently gone. pak should be able to add back all fields that exist. We should probably also add support for the optional snowflake_connection field in pak, but I haven't really thought that through yet.

3. File permissions aren't set. rspm and posit-keyring both chmod 0600 on every write (and 0700 on the ~/.ppm dir), but pak doesn't.

4. The "Found credentials for repo ... (SSO)" alert fires once per concurrent download. On a tidyverse install with parallel downloads, I got that line 17 times in a row, once per worker:

✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
✔ Found credentials for repo <https://__token__@solo.packagemanager.posit.co/cran-auth/latest> (SSO).
... (15 more times)

We could probably suppress those to have it only appear once in the logs, but not a big deal.

@gaborcsardi
Copy link
Copy Markdown
Member Author

gaborcsardi commented May 12, 2026

Thanks for the feedback!

The meaningful work of this is now happening at r-lib/pkgcache#136
I'll update pak soonish, I think it is mostly ready in pkgcache.

  1. TOML field names don't match the rest of the ecosystem. pak writes:

These are from https://github.com/r-lib/keyring/pull/178/changes#diff-966604c4bb47e72a366ca9a1e1d0e349b763d672f0893cdee30f4db6368e9377R297-R300 So I guess in the meanwhile you have changed this. In any case, we can change the keys, no problem.

  1. The manual TOML writer drops unknown fields,

I fixed this already.

  1. File permissions aren't set.

I fixed this as well.

  1. The "Found credentials for repo ... (SSO)" alert fires once per concurrent download.

Fixed this as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants