Skip to content

Order of cred_funs in gargle_env - error if not interactive gargle 1.2.0 break #187

@muschellij2

Description

@muschellij2

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions