Problem
The provider env map deny list added in #1781 covers names that are harmful because they carry a credential, shadow the job environment, or hook the interpreter. It does not cover the three names the inject step writes itself, and a later $GITHUB_ENV entry wins over an earlier one.
Established against the code
- The "Inject provider endpoint" step writes
ANTHROPIC_BASE_URL (bearer/api_key arm) and API_TIMEOUT_MS (both arms) through genv(), and only then emits the provider env map with .env | to_entries[] … >> "$GITHUB_ENV".
- Because the map is emitted last, a
providers.<name>.env key named ANTHROPIC_BASE_URL or API_TIMEOUT_MS silently overrides the value the step just computed from the entry's own base_url / timeout_ms.
- On the
bedrock_api_key arm the step deliberately exports no ANTHROPIC_BASE_URL, and warns that a stray base_url is ignored. An env map naming ANTHROPIC_BASE_URL there reinstates one while that warning still says base_url is ignored — the two signals contradict each other.
HOME is in the same family: it is not currently written by the step, but exporting it redirects ~/.aws, ~/.config/gh and similar lookups for every later step in the job.
Why it was not fixed in #1781
The deny list refuses the run, so every name added to it is a potential break for an existing consumer. #1781 already ships as a minor bump with an "action required on upgrade" note; widening the list further was a scope expansion past the design the operator settled for that issue, so it was recorded as deferred rather than folded in.
No privilege boundary is crossed by any of the three — both ANTHROPIC_BASE_URL and API_TIMEOUT_MS are maintainer-config-sourced, and the credential names that would cross one (ANTHROPIC_AUTH_TOKEN, AWS_BEARER_TOKEN_BEDROCK) are already denied. This is confusing precedence rather than a hole, which is why it is a follow-up and not a fix to #1781.
Open questions for refinement
- Deny all three, or only the two the step actually writes?
- Is silently overriding
ANTHROPIC_BASE_URL ever a legitimate escape hatch a consumer relies on — in which case a ::warning:: naming the override would be the better arm than a refusal?
- Should
HOME be grouped with the existing interpreter/loader-hook class, or named as its own class in the docs?
Relevant files
The "Inject provider endpoint" step in .github/workflows/devflow.yml, .github/workflows/devflow-implement.yml and .github/workflows/devflow-runner.yml (byte-identical, pinned by lib/test/run.sh); the #1773 inject-body block in lib/test/run.sh; .prflow/config.schema.json; docs/internal/cloud-setup.md; docs/external/docs/configuration/providers.md.
Problem
The provider
envmap deny list added in #1781 covers names that are harmful because they carry a credential, shadow the job environment, or hook the interpreter. It does not cover the three names the inject step writes itself, and a later$GITHUB_ENVentry wins over an earlier one.Established against the code
ANTHROPIC_BASE_URL(bearer/api_key arm) andAPI_TIMEOUT_MS(both arms) throughgenv(), and only then emits the providerenvmap with.env | to_entries[] … >> "$GITHUB_ENV".providers.<name>.envkey namedANTHROPIC_BASE_URLorAPI_TIMEOUT_MSsilently overrides the value the step just computed from the entry's ownbase_url/timeout_ms.bedrock_api_keyarm the step deliberately exports noANTHROPIC_BASE_URL, and warns that a straybase_urlis ignored. Anenvmap namingANTHROPIC_BASE_URLthere reinstates one while that warning still says base_url is ignored — the two signals contradict each other.HOMEis in the same family: it is not currently written by the step, but exporting it redirects~/.aws,~/.config/ghand similar lookups for every later step in the job.Why it was not fixed in #1781
The deny list refuses the run, so every name added to it is a potential break for an existing consumer. #1781 already ships as a
minorbump with an "action required on upgrade" note; widening the list further was a scope expansion past the design the operator settled for that issue, so it was recorded as deferred rather than folded in.No privilege boundary is crossed by any of the three — both
ANTHROPIC_BASE_URLandAPI_TIMEOUT_MSare maintainer-config-sourced, and the credential names that would cross one (ANTHROPIC_AUTH_TOKEN,AWS_BEARER_TOKEN_BEDROCK) are already denied. This is confusing precedence rather than a hole, which is why it is a follow-up and not a fix to #1781.Open questions for refinement
ANTHROPIC_BASE_URLever a legitimate escape hatch a consumer relies on — in which case a::warning::naming the override would be the better arm than a refusal?HOMEbe grouped with the existing interpreter/loader-hook class, or named as its own class in the docs?Relevant files
The "Inject provider endpoint" step in
.github/workflows/devflow.yml,.github/workflows/devflow-implement.ymland.github/workflows/devflow-runner.yml(byte-identical, pinned bylib/test/run.sh); the#1773inject-body block inlib/test/run.sh;.prflow/config.schema.json;docs/internal/cloud-setup.md;docs/external/docs/configuration/providers.md.