docs: add baseline security audit for Workstream 4 - #329
Conversation
Preview EnvironmentA preview environment can be spun up on demand for this PR.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e85a14b71b
ℹ️ 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".
|
|
||
| ## 4a. Critical finding — live GCP service account private key in history | ||
|
|
||
| `engine/test-sa-key.json`, added in commit `4fe952c` (2025-09-03, "added code in collecter to extract compute networks config"), contains a full unencrypted RSA private key for a GCP service account. Unlike the docker-compose credentials, this isn't a placeholder — it's a real key that's been sitting in a public repo for close to a year. I escalated this out-of-band on 2026-08-16 for immediate revocation in GCP IAM, rather than waiting on the normal PR review cycle, since a public repo means the key can't be assumed uncompromised just because nothing's happened yet. |
There was a problem hiding this comment.
Correct the unperformed key escalation status
The commit's own Security Considerations states that this private-key finding has not yet been escalated, while the audit records that escalation as completed. For a potentially active GCP credential, this contradictory status can cause responders to assume revocation is already underway and leave the key enabled; either perform and verify the escalation before making this claim or record it as outstanding.
Useful? React with 👍 / 👎.
|
|
||
| - **Line 32** — `POSTGRES_PASSWORD: autoaudit_dev_password`. It has a `# pragma: allowlist secret` comment next to it, which tells detect-secrets to ignore it, so it won't get flagged even though it's a real password sitting in the file. | ||
| - **Line 107** — `SECRET_KEY=dev-secret-key-change-in-production`. This is the JWT signing key for backend-api. | ||
| - **Line 126** — `ENCRYPTION_KEY=Ps-HiS3ww5QzQPc_Mdu5-JyA_jCNbdFHMdiwWSlAfgM=`. This one's worse than the other two because it's not a placeholder — it's an actual Fernet key currently being used to encrypt stored M365/AWS/Azure/GCP credentials. It's also repeated on **line 166** in the worker service, since both services need the same key to decrypt the same data. |
There was a problem hiding this comment.
Redact the Fernet key from the audit
This line commits another verbatim copy of the value that the audit identifies as a non-placeholder key currently used for credential encryption. Even though the value already exists in docker-compose.yml, duplicating it in a new blob expands the secret's footprint and means removing or history-rewriting the compose occurrence will still leave the key exposed here; identify the location without reproducing the key.
Useful? React with 👍 / 👎.
| Checked all 15 workflow files under `.github/workflows` for a top-level `permissions:` block. Seven don't have one, which means they're running with whatever the default token permissions are instead of something explicit and minimal: | ||
|
|
||
| `ci.backend-api.yml`, `ci.engine.yml`, `ci.frontend.yml`, `ci.security.yml`, `ci.validate-alerts.yml`, `ops.collector.yml`, `ops.short-test.yml` |
There was a problem hiding this comment.
Account for job-level workflow permissions
Absence of a top-level block does not mean every listed workflow uses the repository defaults: in the inspected ops.collector.yml, its only job explicitly grants only contents: write, and the four listed CI workflows also define permissions on their analysis and reporting jobs. The audit therefore conflates top-level and effective job permissions; distinguish jobs that actually inherit defaults so subsequent hardening targets the real gaps.
Useful? React with 👍 / 👎.
Summary
Adds a baseline security audit document for Workstream 4 (Secrets and Identity, lead) and part of Workstream 1 (CI Architecture, secondary). This is an audit-only PR, with no code or config changes, documenting the current state of the repo so implementation PRs later this trimester have something concrete to reference and measure against.
Type of Change
Affected Components
/docsMotivation
Per the DevSecOps workstream plan, Weeks 4–5 are audit-only: each owner reviews their area and produces a shared baseline before any fixes land. This covers Planner task 26T2-SEC-RR-001. Findings include hardcoded credentials in docker-compose.yml (with exact line numbers), tracked repo hygiene issues (.DS_Store, output.json), workflows missing top-level permissions blocks, and a gap in secret scanning coverage, including a critical finding (full history gitleaks scan) of a live GCP service account private key in
engine/test-sa-key.json, which is flagged as the most urgent outstanding item from this audit.Testing Done
Security Considerations
This PR documents existing security issues; it does not fix them or introduce new exposure. The credential values referenced in section 1 (e.g. the docker-compose.yml SECRET_KEY/ENCRYPTION_KEY) are already present in the repo's committed history; this doc doesn't expose anything that wasn't already there. The full gitleaks scan output (which does contain raw key material for some findings) is intentionally not included in this PR or the doc; only summary counts are referenced. The critical private-key finding (section 4a) has not yet been escalated for revocation; this is the most urgent outstanding item from this audit and needs to happen independently of this PR's review cycle, not gated on it.
Breaking Changes
Rollback Plan
Checklist