Skip to content

egress: a claim credential can require a placeholder before it injects - #307

Merged
CMGS merged 1 commit into
mainfrom
feat/inject-placeholder
Oct 3, 2026
Merged

CMGS merged 1 commit into
mainfrom
feat/inject-placeholder

Conversation

@CMGS

@CMGS CMGS commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

A claim credential (#302) injects on every intercepted request to its hosts. On a desktop box this also hands the credential to a browser browsing the same host, for example github.com while a user is signed in. This PR adds an optional placeholder to inject.

"GH_GIT": { "value": "Basic …", "guest": false,
            "inject": { "hosts": ["github.com"], "header": "Authorization", "placeholder": "Basic @GH_GIT@" } }
git config --global http.https://github.com/.extraHeader "Authorization: Basic @GH_GIT@"
  • With placeholder: the proxy replaces the header only when the guest's request carries exactly that value. Every other request to those hosts passes unchanged.
  • Without it: the old behavior, set on every intercepted request.
  • Not a secret: the placeholder stays in the guest and is returned by GET /env.
  • Validation: at most 256 bytes of header value, no control characters, no surrounding space. Anything else is a 400 at write time, with the same envelope checks as before (intercept coverage, tenant class, pool-secret header).
  • Change detection: a placeholder change counts as an inject change, for Equal and InjectsChanged.

Hot path: one Header.Get per placeholder credential on an intercepted request to a matching host. Nothing changes elsewhere.

Tests

  • types: placeholder validation (newline, surrounding space, over-long). A placeholder change is seen by Equal and InjectsChanged.
  • egress: TestInterceptInjectsAPlaceholderCredentialOnlyWhereTheGuestSentIt covers placeholder sent → replaced, header absent → untouched, a different value → untouched. With the placeholder clause removed it fails on the absent and different-value cases.
  • pool: the placeholder rides the env write into the proxy credential.
  • e2e: credsmoke gains a placeholder leg.

Hardware

Bare-metal testbed, isolated kit cocoon root, template rt:24.04-90230c0. scripts/credentials-e2e.sh with this branch's sandboxd and credsmoke: PASS, including the new line "a placeholder credential reached the origin only on the request that carried its placeholder", and the restart reattach leg.

Gates

gate result
golangci-lint v2.13.2, sandboxd, sdk/go and e2e, darwin and linux 0 issues. each
fmt --diff clean
asl -forwarder=false, both GOOS clean
go test types, egress, pool, server ok
-race types, egress, pool (golang:1.27.1 linux/arm64, non-root) ok

An inject entry may name a placeholder: the proxy then sets the header only
on intercepted requests whose header already carries exactly that value,
and leaves every other request to the same hosts untouched. A tool such as
git opts in per request (http.extraHeader with the placeholder), so a
browser signed in to the same host never receives the credential.
@CMGS
CMGS merged commit 858a80e into main Oct 3, 2026
1 check passed
@CMGS
CMGS deleted the feat/inject-placeholder branch October 3, 2026 03:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant