POST: storing and using httr2 cache tokens on CI#1173
POST: storing and using httr2 cache tokens on CI#1173drmowinckels wants to merge 21 commits intoropensci:mainfrom
Conversation
|
@maelle first draft ready for your feedback! |
maelle
left a comment
There was a problem hiding this comment.
Thank you!! I made some comments. I wonder whether a diagram would help. And a link to a real GHA example?
|
Hi @drmowinckels and @maelle, no rush, just let us know when this is ready to review for our editorial team or if you need any help from us to move forward. |
|
I'll get to this next week I think. We ended up with a completely different approach in the end, so needs a pretty big rewrite. |
Thanks for letting me know. No pressure and no rush. I was just going through our pending posts and want to get a sense of timing to schedule publications. |
|
@maelle did some updates, added what you suggested :) |
maelle
left a comment
There was a problem hiding this comment.
Yay!! I find it very clear especially knowing the pain and confusion that the Meetup API and OAuth create.
| title: "Cache Me If You Can – httr2 OAuth Token Management for CI/CD" | ||
| author: | ||
| - Athanasia Mo Mowinckel | ||
| - Maëlle Salmon |
There was a problem hiding this comment.
I wonder whether I should be an editor instead, given what my input was.
There was a problem hiding this comment.
I leave that to you, but I think of you as co-auther if that counts for something.
|
|
||
| ## Understanding httr2's OAuth flow | ||
|
|
||
| httr2's `req_oauth_auth_code()` handles [OAuth2](https://blog.r-hub.io/2021/01/25/oauth-2.0/) authentication for local development: |
There was a problem hiding this comment.
I obviously like that R-hub post but maybe link to https://httr2.r-lib.org/articles/oauth.html instead/as well?
Co-authored-by: Maëlle Salmon <maelle.salmon@yahoo.se>
Co-authored-by: Maëlle Salmon <maelle.salmon@yahoo.se>
Co-authored-by: Maëlle Salmon <maelle.salmon@yahoo.se>
Co-authored-by: Maëlle Salmon <maelle.salmon@yahoo.se>
Co-authored-by: Maëlle Salmon <maelle.salmon@yahoo.se>
Co-authored-by: Maëlle Salmon <maelle.salmon@yahoo.se>
| title: "Cache Me If You Can – httr2 OAuth Token Management for CI/CD" | ||
| author: | ||
| - Athanasia Mo Mowinckel | ||
| - Maëlle Salmon |
There was a problem hiding this comment.
I leave that to you, but I think of you as co-auther if that counts for something.
drmowinckels
left a comment
There was a problem hiding this comment.
minor changes
|
To whomever will be editor, we want to crosspost this to the R-Ladies blog, but have not set up the post there yet. I thought it would be best to get it ready here, and then set a publishing date together with the @rladies/blog team |
|
@drmowinckels, that sounds good. Is this ready for editorial review? If yes, then @steffilazerte will be the editor 😸 |
|
ready for review @steffilazerte . |
steffilazerte
left a comment
There was a problem hiding this comment.
Hi @drmowinckels!
This is a great post and a fascinating idea! I'm already thinking about how to incorporate it into my promoutils package so I don't have to deal with the httr2 token storage, thanks!
Overall, this is a very clear and well written post. I have one large suggestion regarding moving the "What we tried first" section to earlier, and most of the other comments are small wording tweaks, or add a bit of context to remind the reader what you're talking about.
For moving the "What we tried first" section, see my comments for specifics, but broadly, my suggestion is to:
- Move it to right before "How it works"
- Rename to "Why encrypted tokens?"
- Add the first paragraph of the "How it works" to the end of this section so the two sections flow from one into the other.
These are just suggestions, however, so pick and chose what works best for you!
We have a couple of options for dates, depending what @maelle thinks and how long you need to make any edits.
I'm away until April 24th, so we could publish April 28th, when I'm back, or if you're ready earlier, @maelle could publish on the 21st (or anytime next week that sounds good). Just let me know what works best for you (and @maelle, if that works for you!)
- post follows Content Guidelines
- post follows Style Guide
- title is in Title Case
- publication date is ok
- slug is ok
- alternative text of images is informative
- author metadata is provided with correct folder name for each language
- html not included in pull request of Rmd post
- I ran
roblog::ro_lint_md()on index.md - I ran
roblog::ro_check_urls()on index.md - I ran a spell-check on index.md
- YAML subject tags are ok ("tech notes" for tech notes; "community" for non-staff non-editor)
- YAML field 'editor' is filled with your name
- YAML field 'translator' is filled as needed
- YAML field 'interviewee' is filled as needed
- YAML field 'preface' is present if necessary
- YAML field 'params.doi' is filled with a new DOI
| 2. _Encrypted token file_ — for regular OAuth apps in CI | ||
| 3. _Interactive OAuth_ — the standard browser flow for local development | ||
|
|
||
|  |
There was a problem hiding this comment.
Should the "\n" be New Lines? Looks like that didn't work in the figure...
| req <- req |> | ||
| httr2::req_oauth_bearer_jwt( | ||
| client = meetupr_client(...), | ||
| claim = httr2::jwt_claim(...) | ||
| )) | ||
| return(req) |
There was a problem hiding this comment.
Just to match the rest
| req <- req |> | |
| httr2::req_oauth_bearer_jwt( | |
| client = meetupr_client(...), | |
| claim = httr2::jwt_claim(...) | |
| )) | |
| return(req) | |
| req <- req |> | |
| httr2::req_oauth_bearer_jwt( | |
| client = meetupr_client(...), | |
| claim = httr2::jwt_claim(...) | |
| )) | |
| return(req) |
| Our first approach — suggested by [Noam Ross](https://www.noamross.net/) on the rOpenSci Slack — was to base64-encode the raw httr2 cache file and store it as a CI environment variable. | ||
| This worked, but had drawbacks: environment variables have size limits on some CI providers, you had to store both the token content _and_ httr2's hash-based filename as separate secrets, and there was no natural way to write back a rotated token. | ||
|
|
||
| It is a bit surprising! |
There was a problem hiding this comment.
Was it really surprising? The next sentence seems to argue that this is expected? Perhaps either remove the "It is a bit surprising!" Statement, or tweak it to something like "It was a bit surprising, but made sense once we thought about it a bit more." (or similar).
| Instead of the encrypted file going stale after the access token expires, it stays current. | ||
| The caveat being, that every token refresh needs to be committed and pushed to the repo by the CI. | ||
|
|
||
| ### What we tried first |
There was a problem hiding this comment.
I wonder if this section should go right before you describe the encryption part (i.e. before the 'How it works' part). It seems to break the flow a bit here and seems out of order to talk about what you did first after you talk about what you did second 😁
If you do that, consider remaming this section to "Why encrypted tokens?"
| The encrypted file approach is simpler for users — commit one file, set one secret — and gives CI a place to write back the refreshed token. | ||
| By using an encrypted file in the repository, you sidestep this limitation. | ||
| The file acts as a renewable credential that CI can update and push, while the decryption password remains protected as a CI secret. | ||
| This pattern is not common in most documentation, but it works well for R packages and similar use cases. |
There was a problem hiding this comment.
If moving this section to earlier, consider adding a bit of the "How it works" introduction here so it flows directly into that section.
| The encrypted file approach is simpler for users — commit one file, set one secret — and gives CI a place to write back the refreshed token. | |
| By using an encrypted file in the repository, you sidestep this limitation. | |
| The file acts as a renewable credential that CI can update and push, while the decryption password remains protected as a CI secret. | |
| This pattern is not common in most documentation, but it works well for R packages and similar use cases. | |
| So we thought of another approach, using encrypted token files. The idea is simple: authenticate locally once, then encrypt and commit the token so CI can use it. Only the decryption password goes into CI secrets — the encrypted file itself lives in your repository. | |
| This is simpler for users — commit one file, set one secret — and gives CI a place to write back the refreshed token. | |
| By using an encrypted file in the repository, you sidestep the limitations of CI environmental variables. | |
| The file acts as a renewable credential that CI can update and push, while the decryption password remains protected as a CI secret. | |
| This pattern is not common in most documentation, but it works well for R packages and similar use cases. |
There was a problem hiding this comment.
Again I don't see this referenced... I think it can be used for the social media card, but then you need the YAML key socialImg
| JWT is straightforward — if you have the credentials, httr2 handles the rest. | ||
| The interesting part is the encrypted token path. | ||
| The one we wanted to use in our CI workflows! | ||
|
|
There was a problem hiding this comment.
I suggest moving the "What we tried first" section here, and renaming it "Why encrypted tokens?" (see my other comments below)
| @@ -0,0 +1,328 @@ | |||
| --- | |||
| title: "Cache Me If You Can – httr2 OAuth Token Management for CI/CD" | |||
| author: | ||
| - Athanasia Mo Mowinckel | ||
| - Maëlle Salmon | ||
| date: '2026-03-30' |
There was a problem hiding this comment.
Remember to adjust the date here and in the folder name
| output: hugodown::md_document | ||
| tags: | ||
| - oAuth | ||
| - tech notes |
There was a problem hiding this comment.
| - tech notes | |
| - tech notes | |
| - CI | |
| - API |
Maëlle and I describe how we set up meetupr package for CI/CD compatibility. Intended to be cross posted to R-Ladies blog, awaiting their blog team's decision.