Skip to content

Disable GCP collector auto-commit pipeline and remove leaked infra data - #327

Open
Irusha-ag wants to merge 3 commits into
mainfrom
fix/disable-leaking-gcp-collector
Open

Disable GCP collector auto-commit pipeline and remove leaked infra data#327
Irusha-ag wants to merge 3 commits into
mainfrom
fix/disable-leaking-gcp-collector

Conversation

@Irusha-ag

Copy link
Copy Markdown

ops.collector.yml ran on every push to engine-development, using a long-lived service account key (secrets.GCP_CREDENTIALS) to pull a full snapshot of the coastal-stone-470308-a0 GCP project (IAM policy, bucket policies, networks, firewalls, compute/SQL/BigQuery/Dataproc/DNS) and auto-commit it back into the repo in plaintext.

This disables the push trigger (manual workflow_dispatch only) until the credential is rotated and the workflow is redesigned to use Workload Identity Federation instead of a stored key, and to stop committing live infra data into git history at all. Also removes the 9 files of infra data that pipeline had already committed into the current tree.

Threat model: a long-lived, broadly-scoped service account key stored in repo secrets and used automatically on every push gives anyone with repo/fork read access (41 forks currently) a live map of the project's IAM bindings, network topology, and firewall rules - reconnaissance an attacker would otherwise have to earn.

Summary

Disables an active GitHub Actions workflow (ops.collector.yml) that was automatically pulling a live snapshot of a real GCP project's infrastructure (IAM policy, network topology, firewall rules, SQL/BigQuery/Dataproc details, DNS zones) and committing it back into the repo in plaintext on every push to engine-development. Also removes the 9 files of that data currently sitting in the repo.

Type of Change

  • CI/CD / infrastructure
  • Security

Affected Components

  • /.github/workflows

Motivation

Full-history secret scan (gitleaks) as part of Workstream 4 (secrets and identity) found a real GCP service account private key committed in history (engine/test-sa-key.json, later deleted but still recoverable from git log). Tracing where that key came from led to ops.collector.yml, which used a long-lived key stored in secrets.GCP_CREDENTIALS to pull and auto-commit a full infra snapshot on every push to engine-development. That branch no longer exists, so the trigger is currently dormant - but the workflow, the auto-commit logic, and the still-valid credential all remain. If a branch named engine-development is ever recreated, the leak resumes immediately.
A teammate already flagged this workflow as dead and needing review back in May, but it was never removed.

Testing Done

  • No tests required — explain why:

this only changes a workflow trigger and removes files. Confirmed via grep that no code, test, or other CI workflow references the removed engine/legacy/test-configs/*.json files, so nothing breaks. Confirmed docker compose config / other workflows are unaffected by this change (unrelated files). Did not run the collector workflow itself (would require the still-live GCP_CREDENTIALS, which is exactly what needs rotating).

Security Considerations

Yes. This closes the reactivation path (branch name is gone, but the trigger would fire again the moment it exists) and removes the 9 files of live infra data already committed. It does not rotate GCP_CREDENTIALS itself - that key is still valid and could be used outside GitHub entirely (e.g. locally with gcloud), so it still needs to be rotated in GCP IAM by whoever owns project coastal-stone-470308-a0, independent of this PR.

Breaking Changes

  • [x ] Yes — describe below:

ops.collector.yml no longer runs automatically on push to engine-development. It's now workflow_dispatch (manual) only. Anyone who relied on it running automatically will need to trigger it by hand until it's redesigned and the push trigger is restored

Rollback Plan

  • Requires additional steps — describe below:

A plain revert would restore the auto-leak behavior, which is the thing this PR exists to stop. If this needs to be undone, first confirm GCP_CREDENTIALS has been rotated and the team has accepted the ongoing exposure risk, then revert.

Checklist

  • Code follows project conventions
  • No secrets, credentials, or tokens committed
  • Relevant documentation updated (if applicable)
  • [x ] CI/CD workflows pass on this branch
  • [x ] PR is focused on one thing

ops.collector.yml ran on every push to engine-development, using a
long-lived service account key (secrets.GCP_CREDENTIALS) to pull a full
snapshot of the coastal-stone-470308-a0 GCP project (IAM policy, bucket
policies, networks, firewalls, compute/SQL/BigQuery/Dataproc/DNS) and
auto-commit it back into the repo in plaintext.

This disables the push trigger (manual workflow_dispatch only) until the
credential is rotated and the workflow is redesigned to use Workload
Identity Federation instead of a stored key, and to stop committing live
infra data into git history at all. Also removes the 9 files of infra
data that pipeline had already committed into the current tree.

Threat model: a long-lived, broadly-scoped service account key stored in
repo secrets and used automatically on every push gives anyone with
repo/fork read access (41 forks currently) a live map of the project's
IAM bindings, network topology, and firewall rules - reconnaissance an
attacker would otherwise have to earn.
@Irusha-ag
Irusha-ag requested a review from a team as a code owner August 11, 2026 14:02
@github-actions

Copy link
Copy Markdown
Contributor

Preview Environment

A preview environment can be spun up on demand for this PR.

Action Label Includes
Spin up preview deploy-preview Frontend, backend, database, Redis, OPA, worker
Spin up preview with M365 deploy-preview-m365 Everything above + PowerShell service for Exchange/Teams scan testing
Tear down preview teardown-preview Stops the environment early

The environment will also be torn down automatically when the PR is closed or merged.
Preview URLs will appear in a follow-up comment once the deploy completes (~5–8 min).
M365 scans require real tenant credentials added through the frontend UI.

@github-actions

Copy link
Copy Markdown
Contributor

CI: Engine

Job Result
Security analysis (CodeQL) success
Lint success
Tests success

All checks passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ef77ef123

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread .github/workflows/ops.collector.yml
Comment thread engine/legacy/test-configs/iam_policy.json
Removing the push trigger alone left the workflow reachable via manual
workflow_dispatch, and the job body still authenticates with
secrets.GCP_CREDENTIALS and still pushes collected data to the repo -
so a manual "Run workflow" click would have done the exact same thing
the push trigger did. Added `if: false` at the job level so the job
cannot execute through any trigger until it's properly redesigned.

Verified with actionlint (via Docker): the file is valid, and the only
finding is the expected "constant false condition" style note, which
is precisely the intent.
engine/legacy/engine/aggregator.py reads these files (CONFIGS =
engine/legacy/test-configs) to evaluate the legacy CIS GCP rego rules,
and ci.opa-eval.yml runs that aggregator on every push/PR. Deleting the
files outright (previous commit) would have broken that pipeline with
missing-input errors instead of compliance reports.

Restored all 9 files with the real project ID (coastal-stone-470308-a0),
personal email, and project number replaced by synthetic placeholders.
Structure, roles, and relationships are unchanged, so the rego rules
exercise identical logic paths.

Verified in Docker (python3 + real opa CLI, mirroring ci.opa-eval.yml):
aggregator.py produces the same 44 evaluated / 7 errored rule outcome
against the sanitized fixtures as it does against the original data -
the 7 errors are pre-existing rego issues unrelated to this change, not
something this introduces.
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