diff --git a/.github/workflows/gcp-iap-operator.yml b/.github/workflows/gcp-iap-operator.yml index 49c58c6..033b278 100644 --- a/.github/workflows/gcp-iap-operator.yml +++ b/.github/workflows/gcp-iap-operator.yml @@ -31,7 +31,8 @@ concurrency: env: PROJECT_ID: teleo-501523 - WORKLOAD_IDENTITY_PROVIDER: projects/785938879453/locations/global/workloadIdentityPools/github-actions/providers/teleo-iap-operator + STATUS_WORKLOAD_IDENTITY_PROVIDER: projects/785938879453/locations/global/workloadIdentityPools/github-actions/providers/living-ip-github + CLONE_WORKLOAD_IDENTITY_PROVIDER: projects/785938879453/locations/global/workloadIdentityPools/github-actions/providers/teleo-iap-operator STATUS_SERVICE_ACCOUNT: sa-teleo-iap-status@teleo-501523.iam.gserviceaccount.com CLONE_SERVICE_ACCOUNT: sa-teleo-iap-clone-operator@teleo-501523.iam.gserviceaccount.com EXPECTED_WORKFLOW_REF: living-ip/teleo-infrastructure/.github/workflows/gcp-iap-operator.yml@refs/heads/main @@ -74,14 +75,17 @@ jobs: status) [[ "${TARGET_DB}" == "teleo_clone_status" ]] || exit 2 service_account="${STATUS_SERVICE_ACCOUNT}" + workload_identity_provider="${STATUS_WORKLOAD_IDENTITY_PROVIDER}" ;; direct-claim-replay|cleanup-clone) [[ "${TARGET_DB}" != "teleo_clone_status" ]] || exit 2 service_account="${CLONE_SERVICE_ACCOUNT}" + workload_identity_provider="${CLONE_WORKLOAD_IDENTITY_PROVIDER}" ;; *) exit 2 ;; esac printf 'service_account=%s\n' "${service_account}" >> "${GITHUB_OUTPUT}" + printf 'workload_identity_provider=%s\n' "${workload_identity_provider}" >> "${GITHUB_OUTPUT}" install -d -m 0700 "${RESULT_DIR}" : > "${RESULT_DIR}/result.json" chmod 0600 "${RESULT_DIR}/result.json" @@ -172,7 +176,7 @@ jobs: id: auth uses: google-github-actions/auth@v3 with: - workload_identity_provider: ${{ env.WORKLOAD_IDENTITY_PROVIDER }} + workload_identity_provider: ${{ steps.validate.outputs.workload_identity_provider }} service_account: ${{ steps.validate.outputs.service_account }} create_credentials_file: true cleanup_credentials: true diff --git a/tests/test_gcp_iap_operator_access.py b/tests/test_gcp_iap_operator_access.py index 46d58de..7f133ac 100644 --- a/tests/test_gcp_iap_operator_access.py +++ b/tests/test_gcp_iap_operator_access.py @@ -122,6 +122,18 @@ def test_workflow_accepts_only_fixed_operation_and_bounded_ids() -> None: assert forbidden_input not in inputs +def test_workflow_routes_status_through_live_provider_without_weakening_clone_operations() -> None: + workflow = load_workflow() + env = workflow["env"] + source = WORKFLOW.read_text(encoding="utf-8") + + assert env["STATUS_WORKLOAD_IDENTITY_PROVIDER"].endswith("/providers/living-ip-github") + assert env["CLONE_WORKLOAD_IDENTITY_PROVIDER"].endswith("/providers/teleo-iap-operator") + assert 'workload_identity_provider="${STATUS_WORKLOAD_IDENTITY_PROVIDER}"' in source + assert 'workload_identity_provider="${CLONE_WORKLOAD_IDENTITY_PROVIDER}"' in source + assert "workload_identity_provider: ${{ steps.validate.outputs.workload_identity_provider }}" in source + + def test_workflow_uses_wif_official_actions_and_sanitized_short_retention() -> None: workflow = load_workflow() assert workflow["permissions"] == {"contents": "read", "id-token": "write"}