feat(auth): add --experimental-auth-token-file for short-lived OAuth2 access tokens#4871
feat(auth): add --experimental-auth-token-file for short-lived OAuth2 access tokens#4871asdiamond wants to merge 1 commit into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request introduces an experimental feature to authenticate with GCS using an OAuth2 token file via the experimental-auth-token-file flag. It includes the necessary configuration, validation to prevent concurrent usage with other authentication methods, and a custom oauth2.TokenSource implementation that reads and parses the token from a JSON file. However, a critical compilation error was identified in internal/auth/file_token_source.go because oauth2.Token does not contain an ExpiresIn field. A review comment suggests using an auxiliary struct to correctly unmarshal and map the JSON fields.
|
@googlebot I signed it! |
Adds an experimental flag that points at a file containing an OAuth2
token response in JSON format ({"access_token": ..., "expires_in": ...,
"token_type": "Bearer"}), to be used directly as the GCS credential.
This supports short-lived sandbox environments where an orchestrator
mints a downscoped access token (e.g. via STS Credential Access
Boundaries) and hands it to gcsfuse, without shipping a long-lived
service account key into the sandbox or running a localhost HTTP
server just to satisfy --token-url.
Behavior:
- The token file is read eagerly, so mounting fails if the token is
missing, malformed, or expired.
- The relative expires_in field is anchored to the read time; an
absolute expiry field takes precedence when present.
- The file is re-read when the token expires, so an external process
may refresh the credential by rewriting the file.
- The flag is rejected when combined with key-file or token-url.
Fixes GoogleCloudPlatform#4686
95c684f to
e0618ec
Compare
Fixes #4686
What
Adds
--experimental-auth-token-file <path>(config:gcs-auth.experimental-auth-token-file), a flag that points at a file containing an OAuth2 token response in JSON format, used directly as the GCS credential:This targets short-lived sandbox environments (Firecracker microVM providers like e2b, Modal, Daytona) where an orchestrator mints a downscoped, prefix-scoped access token (e.g. via STS Credential Access Boundaries) and hands it to gcsfuse inside the sandbox — without shipping a long-lived SA key into an environment executing untrusted code, and without running a localhost HTTP server just to satisfy
--token-url.Design decisions (per maintainer guidance on #4686)
--experimental-auth-token-file(@trinadhkotturu preferredauth-token-file, @anushka567 asked for theexperimental-prefix for external contributions).--token-urlendpoints return (@anushka567's recommendation). The relativeexpires_infield is anchored to the file read time; an absoluteexpiryfield (RFC 3339), when present, takes precedence.oauth2.ReuseTokenSource, so the file is re-read when the cached token expires. An external process may therefore refresh the credential by rewriting the file; if the file isn't refreshed, requests fail with an "invalid or expired token" error rather than hitting GCS with a stale credential.--key-fileor--token-urlis rejected at config validation time, to fail early instead of silently picking one. Happy to relax this to a documented precedence order if you'd prefer.Changes
cfg/params.yaml+ regeneratedcfg/config.go(viago generate): new param, typeresolvedPath.internal/auth/file_token_source.go: newfileTokenSource+NewTokenSourceFromTokenFile, mirroring the existingproxyTokenSourcestructure.internal/storage/storageutil/auth_client_option.go: token-file branch inGetClientAuthOptionsAndToken(google-lib-auth flow).internal/auth/auth.go/internal/storage/storageutil/client.go: token-file support in the legacyGetTokenSourceflow; also replaced the deprecatedgolang.org/x/net/contextimport withcontextinclient.goto satisfy thegovetinline check on the touched line.cfg/validate.go:isValidGcsAuthConfigmutual-exclusion check.internal/auth/file_token_source_test.go(valid/expired/no-expiry/malformed/missing/empty-token/re-read cases),storageutil/auth_client_option_test.go,cfg/validate_test.go, and a happy-path + conflict cases incmd/root_test.go, per the dev guide.Testing
go test ./cmd/... ./cfg/... ./internal/auth/... ./internal/storage/storageutil/...passes on linux/amd64 (Docker, golang:1.26).go test -run=PATTERN_THAT_DOES_NOT_MATCH_ANYTHING ./...(buildTest) compiles cleanly on linux/amd64.golangci-lint run -E=unused --new-from-rev=masterreports 0 issues on the touched packages.🤖 Generated with Claude Code