Gap cloud-24 · missing-coverage · confidence: verified · tracked in #242
Baseline: Midge 7d39f86 (0.1.1) vs Pants 2507c66. Midge paths are relative to the midge repo, Pants paths to this repo. Midge behavior is used as the proxy for the not-yet-extracted lsm-spec behavioral contract.
Prior: G10 (partially fixed: code is present, tests are missing), #7 (related)
Midge: src/storage/providers/gcs.rs tests
should_read_url_sourced_external_account_subject_token_with_headers (:3220),
should_send_workforce_user_project_in_sts_options (:3129),
should_follow_external_account_impersonation_contract (:3168; STS scope becomes cloud-platform, the
impersonation call carries Authorization: Bearer <sts token>, "lifetime":"900s", and devstorage scope),
should_reject_empty_json_external_account_subject_token (:3245),
should_reject_missing_malformed_or_expired_impersonation_expiry (:3405),
should_reject_executable_external_account_credentials (:3285),
should_reject_aws_external_account_before_treating_metadata_url_as_subject_token (:3267).
Implementation: external_account_subject_token gcs.rs:414-456.
Pants: every path exists in
src/Pants.Core/Cloud/Internal/Providers/Credentials/Gcs/GcsExternalAccountTokenProvider.cs:
URL source plus headers at :132-180, workforce options={"userProject":..} at :76-84, impersonation
scope/bearer/lifetime at :60-65, :201-225 and :302-322, and impersonation expiry validation at :345-359.
Executable rejection is at :33-37 and :103-109. The AWS environment_id source is rejected before the URL
branch at :103-109. An empty JSON subject token is rejected at :279-298 because GetRequiredString treats
whitespace as missing (RefreshingGcsTokenProvider.cs:324-331), but the error says the field is "missing"
rather than "empty". The only external-account test is
test/Pants.Tests/Cloud/GcsCredentialSourceTests.cs ShouldExchangeFileSourcedExternalAccountCredentialFromAdc,
which covers a file-sourced text token only.
Why it matters: federated identity runs on every GKE, EKS, and Azure-hosted deployment that uses workload identity. A
regression would either break authentication or silently send the wrong scope or billing project, and no test would catch it.
Acceptance criteria:
- A URL-sourced JSON subject token is fetched with each configured header, and the test asserts both the header and the parsed token.
- A
workforce_pool_user_project produces the form field options={"userProject":"..."} on the STS request.
- With impersonation, the STS request uses the cloud-platform scope. The impersonation POST carries the Bearer STS token,
lifetime taken from token_lifetime_seconds, and devstorage scope. Lifetimes outside 600-43200 are rejected.
- Impersonation responses with a missing, malformed, or past
expireTime, or an empty accessToken, fail with PantsIOException.
- Whitespace-only JSON and text subject tokens fail before any STS request is sent.
executable at the root or in the source, and environment_id together with a url, are rejected with no HTTP request issued.
- No test output or exception message contains the subject token, the STS token, or header values.
Prior: G10 (partially fixed: code is present, tests are missing), #7 (related)
Midge:
src/storage/providers/gcs.rstestsshould_read_url_sourced_external_account_subject_token_with_headers(:3220),should_send_workforce_user_project_in_sts_options(:3129),should_follow_external_account_impersonation_contract(:3168; STS scope becomes cloud-platform, theimpersonation call carries
Authorization: Bearer <sts token>,"lifetime":"900s", and devstorage scope),should_reject_empty_json_external_account_subject_token(:3245),should_reject_missing_malformed_or_expired_impersonation_expiry(:3405),should_reject_executable_external_account_credentials(:3285),should_reject_aws_external_account_before_treating_metadata_url_as_subject_token(:3267).Implementation:
external_account_subject_tokengcs.rs:414-456.Pants: every path exists in
src/Pants.Core/Cloud/Internal/Providers/Credentials/Gcs/GcsExternalAccountTokenProvider.cs:URL source plus headers at :132-180, workforce
options={"userProject":..}at :76-84, impersonationscope/bearer/lifetime at :60-65, :201-225 and :302-322, and impersonation expiry validation at :345-359.
Executable rejection is at :33-37 and :103-109. The AWS
environment_idsource is rejected before the URLbranch at :103-109. An empty JSON subject token is rejected at :279-298 because
GetRequiredStringtreatswhitespace as missing (RefreshingGcsTokenProvider.cs:324-331), but the error says the field is "missing"
rather than "empty". The only external-account test is
test/Pants.Tests/Cloud/GcsCredentialSourceTests.csShouldExchangeFileSourcedExternalAccountCredentialFromAdc,which covers a file-sourced text token only.
Why it matters: federated identity runs on every GKE, EKS, and Azure-hosted deployment that uses workload identity. A
regression would either break authentication or silently send the wrong scope or billing project, and no test would catch it.
Acceptance criteria:
workforce_pool_user_projectproduces the form fieldoptions={"userProject":"..."}on the STS request.lifetimetaken fromtoken_lifetime_seconds, and devstorage scope. Lifetimes outside 600-43200 are rejected.expireTime, or an emptyaccessToken, fail with PantsIOException.executableat the root or in the source, andenvironment_idtogether with aurl, are rejected with no HTTP request issued.