Repository navigation
Conversation
…t of child environments
# Conflicts: # cmd/volcano/grant_test.go
tkkhq
marked this pull request as ready for review
November 13, 2026 12:23
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved issues cause incorrect grant-error labeling for local requests, omit API codes from HTTP 426 responses, and can hang configuration tests on systems with small pipe buffers.
3 open issues
What changed in this PR
This PR extends delegated-grant support with file-descriptor token input and grant-specific API error codes, helping workers handle credentials safely and distinguish failures.
Changes:
- Adopt tokens into memory at startup and prevent child processes from inheriting adopted credentials.
- Print API error codes for delegated grants and skip telemetry events for adopted tokens.
- Update authentication checks, documentation, and tests for the new token source.
| File | Description |
|---|---|
| internal/telemetry/telemetry.go | Skip events when a token was adopted. |
| internal/telemetry/telemetry_test.go | Test telemetry suppression for adopted tokens. |
| internal/config/token_source.go | Read, validate, and adopt descriptor or grant tokens. |
| internal/config/token_source_unix_test.go | Test descriptor lifecycle, input limits, and stdin handling. |
| internal/config/token_source_test.go | Test environment handling and invalid token-source settings. |
| internal/config/config.go | Resolve adopted tokens before environment or saved credentials. |
| internal/cmd/connect/connect.go | Recognize adopted tokens in login checks. |
| internal/cmd/connect/connect_test.go | Cover connect refusals with adopted grants. |
| internal/cmd/auth/auth_test.go | Update expected grant-login guidance. |
| internal/auth/auth.go | Mention descriptor input in grant-login guidance. |
| docs/authentication.md | Document descriptor input and grant error-code output. |
| cmd/volcano/main.go | Adopt tokens at startup and render grant error codes. |
| cmd/volcano/grant_unix_test.go | Verify descriptor grants authenticate command requests. |
| cmd/volcano/grant_test.go | Test grant-only error-code output. |
Review effort: Balanced
…token cannot block
# Conflicts: # docs/authentication.md
…hipped, and test apply under a grant
… hints when the token came from it
tkkhq
changed the base branch from
feat/grant-migration-runs
to
feat/grant-invoke
November 15, 2026 02:30
This was referenced Nov 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Tracking
databases migration apply,baselineandruns, which work under a grant, so the worker usesapplyWhy
codein Hosting's error bodies but never prints it, so a Builder worker has to match message text to tellgrant_budget_exhausted,grant_reserved_variable,grant_permission_missing,grant_route_not_allowed,rate_limit_exceededanddelegated_grant_requiredapart.VOLCANO_TOKENis exposed while the CLI runs, and every process the CLI starts inherits it.Summary
Error code: <code>. Nothing else is reworded, and every other credential sees errors exactly as before. I chose this over appending(<code>)to every error, which would change the text for all usersVOLCANO_TOKEN_FD=<n>(internal/config/token_source.go). At startup, before anything reads the configuration,mainreads the token from that descriptor up to the first newline (16 KiB cap), so a writer that keeps its end open does not hold the CLI up, and unsets the variable. A descriptor of3or more is opened and closed after the read.0reads stdin throughos.Stdinand leaves it open, so the number can't pass to the next file the CLI opens;1and2are refused. This one option also covers "token on stdin". I chose it over--token-stdinbecause the CLI takes its credential from env vars, and several commands already read stdin for their own inputVOLCANO_TOKENis moved into memory and removed from the CLI's environment at startup, so processes the CLI starts (the telemetry flush, git, docker, the updater) don't inherit it. Other tokens stay inVOLCANO_TOKEN, because the telemetry flush reads an account token from there2, without echoing what was read: setting bothVOLCANO_TOKEN_FDandVOLCANO_TOKEN, a bad descriptor number, or an empty or oversized readVOLCANO_TOKEN/proc/<pid>/environ, which still shows the CLI's starting environment to same-user processes. OnlyVOLCANO_TOKEN_FDkeeps the grant out of the CLI's environment entirely, so the worker should use itVOLCANO_TOKEN_FD, or a grant fromVOLCANO_TOKEN) sends no telemetry event. The flush process can't see that token, and would otherwise send the saved login's token with the eventVOLCANO_TOKEN_FDorVOLCANO_TOKEN, in the LavaFlow and durable-approval sign-in hints, so a token from a descriptor is not answered with "unset VOLCANO_TOKEN"; the hint text forVOLCANO_TOKENis unchangedTestGrantMigrationApplyUsesOnlyARun: feat(databases): apply migrations in tracked runs #365'smigration applyunder a grant calls onlyGET /capabilities,POST …/migration-runsandGET …/migration-runs/{id}, each with the grantauthentication.mddescribesVOLCANO_TOKEN_FDand the code line, now in docs(cli): document delegated grants, exit code 6 and VOLCANO_TOKEN_FD volcano-docs#190Verification
go build ./...make check(openapi-generated-check,release-workflow-check,lintwith 0 issues,test)TestGrantErrorPrintsTheAPICode(the code line follows the unchanged error under a grant) andTestNonGrantErrorPrintsNoCodeLineTestAdoptTokenReadsTheDescriptorAndClosesIt,TestAdoptTokenTakesAGrantOutOfTheEnvironment(both runenvas a child process and check the token is absent),TestAdoptTokenLeavesOtherTokensInTheEnvironment,TestAdoptTokenRefusals(including descriptors1and2)TestAdoptTokenStopsAtTheFirstNewline(the writer stays open afterpg-…\n; fails on a 5 s timeout) andTestAdoptTokenReadsStdinAndLeavesItOpen(stdin still reads what follows the token's line)TestRecord_AdoptedTokenSendsNothingand the adopted-grant case ofTestConnectRefusesALoginThatVolcanoTokenWouldOverrideVOLCANO_API_URLon a closed port:VOLCANO_TOKEN_FD=2prints the refusal (exit2), and3< <(echo pg-x; sleep 5)returns at once_unix_test.gofiles and pass adup'd descriptor that no*os.Fileowns. Passing a pipe's ownFd()made two owners of one descriptor, and the second close hit an HTTP socket that reused the number (seen once inmake check). Rango test -count=5 ./internal/config ./cmd/volcanoafter the fix, andGOOS=windows go veton both packagesTestGrantFromATokenDescriptorrunscloud functions listthrough the real command tree with the grant on a pipe andVOLCANO_TOKENunset, and checks the request carried itVOLCANO_TOKEN_FD=3 volcano cloud functions list 3<<<"pg-…"(a fake grant), withVOLCANO_TOKENunset, against a local recording server: exit0, and the request carriedBearer pg-…runAsWorkerWith(from feat(databases): apply migrations through migration runs under a grant #478) is kept for the descriptor testsTestGrantFromATokenDescriptorIsNamedInSignInHints(lavaflow disableanddurable approvals approvewith a grant on a descriptor); it fails without the hint fixmake checkat816de9d7Decisions for Ted
Error code: <code>), not inside the error line, so no existing text changes. If the worker would rather parseError (<code>): …, that is a one-line change