[rush] Feature: git token management for build cache
Summary
At a security-focused company, your security dept is loathe to have "security through obscurity", with open-air S3 buckets or blob storage containing things like code coverage reports, rush build cache entries, etc. However, managing developer access to these resources can be painful -- using tools like gimme-creds to get temporary session tokens every 8 hours, dealing with the AWS errors that occur if you forget, clicking "Yes" on your phone's Okta Verify app, etc. etc.
Instead, we could store temporary read-only tokens for developer use in git, in a private repo that all developers at the company have access to. Tokens in the repo are refreshed regularly by an automated process, and are designed to expire after 8 / 24 / 72 hours (whatever you can get past your security folks -- roughly coinciding with the time a developer leaving the company would lose access to github).
Note: fastlane users will note that this design is extremely similar to fastlane's, and in fact maybe fastlane could be utilized in some way? The only issue there is that fastlane is written in Ruby so you would automatically be buying into a node + ruby environment.
Details
I'd like to see this designed as a standalone CLI tool (perhaps part of rushstack, but not inside rush), with some key commands:
Init
$ git-token init <directory>
Create a new git tokens repository template for the user, with example github action workflows, boilerplate YAML configuration files, instructions, and whatever else might be required to setup the git-tokens developer experience.
Get Token
$ git-token get https://github.com/Acme/git-tokens rush-build-cache-s3
{
"provider": "aws-session-token",
"access_key_id": ".....",
"secret_access_key": "....",
"session_token": "...."
}
This command seamlessly obtains the latest version of the specified token from the specified git-tokens repository, returning a JSON blob. The JSON blob contains provider, indicating the type of token is returned; the remaining fields in the blob are determined by the provider type.
This command performs a read request and only requires that the caller does have access to the target git repo.
Refresh Token
$ git-token refresh https://github.com/Acme/git-tokens rush-build-cache-s3
{
"provider": "aws-session-token",
"access_key_id": ".....",
"secret_access_key": "....",
"session_token": "...."
}
This command performs a "refresh" for the specified token, using the provider's refresh implementation, which may require various access tokens of their own (which will need to be provided as environment variables or through some other mechanism). Once the new token is obtained, it will also be committed to the main branch of the target git-repo for download.
Note: optionally, we could consider breaking this up into two operations, "refresh" and "commit"... to be determined.
Workflow Overview
- A variety of different "tokens", each configured with one of the supported "providers", is configured in the git-tokens repo.
- A periodic github action workflow (or alternate method of cron job) is configured to refresh each token on the desired schedule (possibly different for different tokens).
- Ensure developers have read access to this repo.
- For rush, ideally, a new build-cache authorization approach is added: git-token, with the target git-tokens repo and name of the token to use for authorization. (Note that this doesn't replace the cache provider: you would specify azure blob storage, or s3 bucket, but that git-token would be used to obtain the credentials.) (Also note: rush could perhaps include this as a library bundled inside itself instead of executing a child process.)
This tool as described would also be usable by non-Rush consumers... for example, a Kotlin repo could directly call the git-token cli at the top of a build.gradle file to obtain the latest read-only private maven registry token.
Standard questions
Please answer these questions to help us investigate your issue more quickly:
| Question | Answer |
|---|---|
@microsoft/rush globally installed version? |
n/a |
rushVersion from rush.json? |
n/a |
useWorkspaces from rush.json? |
n/a |
| Operating system? | Mac |
| Would you consider contributing a PR? | Yes |
Node.js version (node -v)? |
16 |
The Azure Storage build cache functionality has support for interactive login and caching of the user-specific credential that it gets back, but I couldn't find a way to do something similar for S3. This could be a nice compromise. Given that your team is using S3 (and we're using Azure Storage), it probably make sense for your team to drive this feature.