-
Notifications
You must be signed in to change notification settings - Fork 39
Description
I'm trying to auth with a cached token, while on GCE. I have an OAuth token, which I read in and then pass into token_fetch (technically @MarkEdmondson1234 googleAuthR is inherently calling token_fetch), but getting different behavior in interactive in RStudio (uses OAuth) vs. non-interactive (uses gce_credentials). The behavior is also different in Terminal R vs. RStudio on the same machine (due to GCE inheritance it seems).
I saw this change after upgrading to 1.2.0 (also RSPM uses it, so it bit me when using a rocker container). I don't know if the order of cred_funs would be the best fix for this, but figured that would be an easy one. I'm not sure if a Token2.0 is passed to token_fetch it is intended to use it, but I found this case it is not.
Interactive
path_to_token = "~/token.rds"
#>
library(gargle)
token = readRDS(path_to_token)
print(token)
#>
#> ── <Token (via gargle)> ─────────────────────────────────────────────────────────────────
#> oauth_endpoint: google
#> app: XXXXXXXXXXXXXXXX
#> email: '[email protected]'
#> scopes: ...analytics, ...analytics.edit, ...analytics.manage.users, ...analytics.readonly, ...analytics.user.deletion, ...userinfo.email
#> credentials: access_token, expires_in, refresh_token, scope, token_type, id_token
#> email = token$email
#>
options(gargle_verbosity = "debug")
credentials_byo_oauth2(token = token, email = email)
#> → trying `credentials_byo_oauth()`
#> → putting token into the cache:
#> ~/.cache/gargle
#>
#> ── <Token (via gargle)> ─────────────────────────────────────────────────────────────────
#> oauth_endpoint: google
#> app: XXXXXXXXXXXXXXXX
#> email: '[email protected]'
#> scopes: ...analytics, ...analytics.edit, ...analytics.manage.users, ...analytics.readonly, ...analytics.user.deletion, ...userinfo.email
#> credentials: access_token, expires_in, refresh_token, scope, token_type, id_token
fetched = token_fetch(email = email, token = token)
#> → trying `token_fetch()`
#> → trying `credentials_service_account()`
#> → Error caught by `token_fetch()`:
#> parse error: premature EOF
#>
#> (right here) ------^
#> → trying `credentials_app_default()`
#> → trying `credentials_gce()`
#> → trying `credentials_byo_oauth()`
#> → putting token into the cache:
#> ~/.cache/gargle
fetched
#>
#> ── <Token (via gargle)> ─────────────────────────────────────────────────────────────────
#> oauth_endpoint: google
#> app: XXXXXXXXXXXXXXXX
#> email: '[email protected]'
#> scopes: ...analytics, ...analytics.edit, ...analytics.manage.users, ...analytics.readonly, ...analytics.user.deletion, ...userinfo.email
#> credentials: access_token, expires_in, refresh_token, scope, token_type, id_token
#> > fetched$app
#> <oauth_app> XXXXXXXXXXXXX
#> key: 192019824XX-XXXXXXXX.apps.googleusercontent.com
#> secret: <hidden>So you can see above that token_fetch gets to credentials_byo_oauth, bypassing credentials_gce. So I guess the interactive session doesn't inherit what's needed from GCE. This is not the case when running R from the terminal. Thus, interactive auth is different in RStudio vs. terminal R/Non-interactive if an OAuth token is passed on GCE. Unluckily for me, the auth in the default GCE account doesn't have the permissions needed for the scopes I need/have with the OAuth.
Non-Interactive (Reprex)
path_to_token = "~/token.rds"
library(gargle)
token = readRDS(path_to_token)
print(token)
#>
#> ── <Token (via gargle)> ────────────────────────────────────────────────────────
#> oauth_endpoint: google
#> app: XXXXXXXXXXXXXXXX
#> email: '[email protected]'
#> scopes: ...analytics, ...analytics.edit, ...analytics.manage.users, ...analytics.readonly, ...analytics.user.deletion, ...userinfo.email
#> credentials: access_token, expires_in, refresh_token, scope, token_type, id_token
email = token$email
options(gargle_verbosity = "debug")
credentials_byo_oauth2(token = token, email = email)
#> trying `credentials_byo_oauth()`
#> putting token into the cache:
#> '~/.cache/gargle'
#>
#> ── <Token (via gargle)> ────────────────────────────────────────────────────────
#> oauth_endpoint: google
#> app: XXXXXXXXXXXXXXXX
#> email: '[email protected]'
#> scopes: ...analytics, ...analytics.edit, ...analytics.manage.users, ...analytics.readonly, ...analytics.user.deletion, ...userinfo.email
#> credentials: access_token, expires_in, refresh_token, scope, token_type, id_token
fetched = token_fetch(email = email, token = token)
#> trying `token_fetch()`
#> trying `credentials_service_account()`
#> Error caught by `token_fetch()`:
#> parse error: premature EOF
#>
#> (right here) ------^
#> trying `credentials_external_account()`
#> aws.ec2metadata not installed; can't detect whether running on EC2 instance
#> trying `credentials_app_default()`
#> trying `credentials_gce()`
fetched
#> <GceToken>
fetched$app
#> <oauth_app> google
#> key: KEY
#> secret: <hidden>In the terminal R/non-interactive session, it hits credentials_gce, which then succeeds, and returns the token from the GCE worker. Note, this also results in a different app for the token (which is expected)
Created on 2021-08-13 by the reprex package (v2.0.0)
Session info
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#> setting value
#> version R version 4.1.0 (2021-05-18)
#> os Debian GNU/Linux 10 (buster)
#> system x86_64, linux-gnu
#> ui X11
#> language (EN)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz Etc/UTC
#> date 2021-08-13
#>
#> ─ Packages ───────────────────────────────────────────────────────────────────
#> package * version date lib source
#> askpass 1.1 2019-01-13 [2] CRAN (R 4.1.0)
#> cli 3.0.1 2021-07-17 [1] CRAN (R 4.1.0)
#> crayon 1.4.1 2021-02-08 [2] CRAN (R 4.1.0)
#> curl 4.3.2 2021-06-23 [1] CRAN (R 4.1.0)
#> digest 0.6.27 2020-10-24 [2] CRAN (R 4.1.0)
#> ellipsis 0.3.2 2021-04-29 [2] CRAN (R 4.1.0)
#> evaluate 0.14 2019-05-28 [2] CRAN (R 4.1.0)
#> fansi 0.5.0 2021-05-25 [2] CRAN (R 4.1.0)
#> fs 1.5.0 2020-07-31 [2] CRAN (R 4.1.0)
#> gargle * 1.2.0.9000 2021-08-13 [1] Github (r-lib/gargle@083acb1)
#> glue 1.4.2 2020-08-27 [2] CRAN (R 4.1.0)
#> highr 0.9 2021-04-16 [2] CRAN (R 4.1.0)
#> htmltools 0.5.1.1 2021-01-22 [2] CRAN (R 4.1.0)
#> httr 1.4.2 2020-07-20 [2] CRAN (R 4.1.0)
#> jsonlite 1.7.2 2020-12-09 [2] CRAN (R 4.1.0)
#> knitr 1.33 2021-04-24 [2] CRAN (R 4.1.0)
#> lifecycle 1.0.0 2021-02-15 [2] CRAN (R 4.1.0)
#> magrittr 2.0.1 2020-11-17 [2] CRAN (R 4.1.0)
#> openssl 1.4.4 2021-04-30 [2] CRAN (R 4.1.0)
#> pillar 1.6.1 2021-05-16 [2] CRAN (R 4.1.0)
#> pkgconfig 2.0.3 2019-09-22 [2] CRAN (R 4.1.0)
#> R6 2.5.0 2020-10-28 [2] CRAN (R 4.1.0)
#> reprex 2.0.0 2021-04-02 [2] CRAN (R 4.1.0)
#> rlang 0.4.11 2021-04-30 [2] CRAN (R 4.1.0)
#> rmarkdown 2.9 2021-06-15 [2] CRAN (R 4.1.0)
#> rstudioapi 0.13 2020-11-12 [2] CRAN (R 4.1.0)
#> sessioninfo 1.1.1 2018-11-05 [2] CRAN (R 4.1.0)
#> stringi 1.6.2 2021-05-17 [2] CRAN (R 4.1.0)
#> stringr 1.4.0 2019-02-10 [2] CRAN (R 4.1.0)
#> tibble 3.1.2 2021-05-16 [2] CRAN (R 4.1.0)
#> utf8 1.2.1 2021-03-12 [2] CRAN (R 4.1.0)
#> vctrs 0.3.8 2021-04-29 [2] CRAN (R 4.1.0)
#> withr 2.4.2 2021-04-18 [2] CRAN (R 4.1.0)
#> xfun 0.24 2021-06-15 [2] CRAN (R 4.1.0)
#> yaml 2.2.1 2020-02-01 [2] CRAN (R 4.1.0)
#>
#> [1] /home/jupyter/.R/library
#> [2] /usr/local/lib/R/site-library
#> [3] /usr/lib/R/site-library
#> [4] /usr/lib/R/library