Skip to content

Drata SOC 2 Remediation Board — Ordermatic (corrected)

Status Verified board — supersedes the assumptions in the handoff spec
As of 2026-06-26 · 35 FAILED / 17 PASSED (52 monitoring tests)
Method Multi-agent verification against the live repo + GitHub API + Drata API (not the spec’s assumptions)
Companion soc2-readiness.md (CC1–CC9 strategy), branch-protection-proposal.md, out-of-scope-tests.md

The headline correction: several failing tests the spec marked “already shipped, just needs Drata to rescan” are not actually deployed. The clearest case is Wave 0 — PR #1926 merged the Cloud Armor / load-balancer Terraform but it was never terraform apply-ed, so the WAF/LB does not exist in ordermatic-prod and live traffic still flows through the Cloud Run domain-mapping (ghs.googlehosted.com), not an LB. No rescan can pass it. That “merged ≠ applied” trap recurs across the monitoring, HA, and firewall rows: writing Terraform is not the fix; applying it is.

Two structural truths shape the infra tests:

  • The primary application database is Neon (external), the queue layer is Temporal + Redis, and object storage is Cloudflare R2 — none are GCP resources, so Drata’s read-only GCP connector (dratareadonly@ordermatic-prod) literally cannot see them. Tests like DB CPU/IO/storage and queue-age need a non-GCP control or an N/A justification, not a GCP alert policy.
  • The branch protection the deploy pipeline assumes does not exist. main has no protection (GET branches/main/protection → 404); the one repo ruleset (6222454, “Pull-Requests Only”, active) has an empty include[] so it targets no branch and requires 0 approvals; GitHub org-wide 2FA is OFF. The controls are claimed in DRAFT policy but not enforced in the platform.

The 35 tests sort into: (a) already satisfied in code (Public SSH Denied, unique VCS accounts); (b) agent-preps / human-applies (monitoring alerts, branch protection, WAF/LB apply); (c) human-only console or decision work (Workspace/GCP MFA, bucket versioning, queue-age control, background-check vendor); (d) people/Wave-3 artifacts already drafted in PR #1932 that flip on Drata publish + sign-off; (e) 3 proposed N/A.

Owner key: 🤖 agent · 🤝 agent-preps / human-applies · 👤 human · 🚫 propose N/A.

# Test Verified reality Concrete next action Owner Conf
1 Web Application Firewall in Place Cloud Armor TF (#1926) merged, never applied; no securityPolicy in ordermatic-prod; ingress is Cloud Run ghs, not an LB Run the gated cutover gcp-edge-lb-cutover.md (apply LB+Armor → flip DNS → enforce), then rescan 🤝 high
2 Load Balancer Used Same as #1 — no global forwarding rule / backend service exists yet Same cutover; LB + WAF land together 🤝 high
3 Infrastructure Instance CPU Monitored Zero google_monitoring_alert_policy in repo; Better Stack has only an error-rate alert + uptime (invisible to Drata’s GCP connector) Add google_monitoring_alert_policy on compute…/instance/cpu/utilization (>0.85/5m) + notification channel; apply 🤝 high
4 Database CPU Monitored No alert; only GCP DB is Cloud SQL erp-prod-ln (Dagster/Temporal). App DB = Neon (external, invisible to GCP connector) Alert on cloudsql…/cpu/utilization for erp-prod-ln; separately decide Neon control or N/A 🤝 high
5 Database Read I/O Monitored No alert; same Neon-is-external gap Alert on cloudsql…/disk/read_ops_count; flag Neon 🤝 high
6 Database Free Storage Space Monitored No alert; Cloud SQL + postgres-VM disk metrics unalerted Alert on cloudsql…/disk/utilization (>0.85); flag Neon 🤝 high
7 Messaging Queue Message Age Monitored No GCP-native queue exists (no Pub/Sub / Cloud Tasks); async = Temporal + Redis — no metric for Drata to read Decision: Temporal schedule-to-start custom metric, Redis depth alert, or N/A with durability justification 👤 med
8 Cloud Storage Buckets Versioned Zero google_storage_bucket in TF; object storage is R2/S3; real GCS buckets were gcloud-created Identify flagged buckets; gsutil versioning set on each (or import to TF). Not a rescan 👤 high
9 Public SSH Denied Satisfied in code — only SSH rule restricts tcp:22 to IAP range 35.235.240.0/20; no 0.0.0.0/0 Read-only gcloud compute firewall-rules list to confirm no legacy default-allow-ssh; likely green on rescan 👤 high
10 Zone Redundancy Cloud Run regional (multi-zone); app DB = Neon/external; Cloud SQL is hardcoded ZONAL Decide: Neon → N/A w/ external evidence, or flip Cloud SQL availability_type → REGIONAL (cost + restart, sign-off) 🤝 high
11 Formal Code Review Process False — main unprotected (404); ruleset 6222454 active but empty include[] (targets nothing, 0 approvals); staging requires 0 reviews branch-protection-proposal.md §3a (staging: 1 review + checks) + a ruleset that actually targets main 🤝 high
12 Only Authorized Employees Change Code Partial — private repo, 2 collaborators; no branch-level push restriction (either could push main) Restrict-push on main (Model A: promotion bot + admin); audit the 2 collaborators 🤝 med
13 Production Code Changes Restricted False at SCM — main has no protection/required-check/force-push block; auto-deploy-main.yml’s “protection allows the token” comment references protection that doesn’t exist Proposal §3b ruleset on main (block force-push/deletion, linear history, required promotion-guard) + restrict-push; test FF promotion before relying — revert on break ([[prod-promotion-deploy-trigger-gap]]) 🤝 high
14 MFA on Version Control System GitHub org 2FA = OFF (two_factor_requirement_enabled:false, team plan supports it); 2 human members Confirm both members have personal 2FA → flip Org → Authentication security → require 2FA → rescan 🤝 high
15 MFA on Identity Provider IdP = Google Workspace; 2-Step enforcement is console-only, not verifiable from repo admin.google.com → Security → 2-Step → enforce for all OUs; attach evidence 👤 high
16 MFA on Cloud Infrastructure GCP human logins ride Workspace identities; console-only Verify in Google Admin / GCP org policy; fixing #15 likely satisfies this 👤 high
17 Employees have Unique Infrastructure Accounts GCP owner = individual david@; full uniqueness across GCP/Neon/Infisical/1P is console-only Agent pre-builds checklist from org-chart; human attests per system in the quarterly access review 🤝 med
18 Employees have Unique Version Control Accounts Passes for accounts that exist — GitHub org = 2 human members, both User (dboone31=David, fromerom-braintly=Fabio); no shared logins Map the 2 in Drata personnel; likely green on rescan 🤝 high
19 Job Descriptions Drafted in #1932 Publish to Drata + owner sign-off 🤝 high
20 Engineering Job Description Drafted (eng JD) in #1932 Publish + sign-off 🤝 high
21 Performance Evaluation Process Drafted in #1932 Publish + sign-off 🤝 high
22 New Hire Contracts Security terms drafted in #1932 (needs legal) Finalize w/ counsel; publish + sign-off 🤝 high
23 MSAs Offered to Customers MSA security clause drafted in #1932 (needs legal) Finalize w/ counsel; publish + sign-off 🤝 high
24 Maintains Organization Chart Drafted in #1932; roster reconciled 2026-06-26 Publish + sign-off 🤝 high
25 Security Awareness Training Completed In scope; 8 humans Assign Drata training; all 8 complete 👤 high
26 Employee Background Checks In scope; blocked on vendor Approve Drata’s broker (Certn/KarmaCheck); run 👤 high
27 Contractor Background Checks Same — blocked on vendor Approve vendor; run for the 2 contractors 👤 high
28 Malware Detection Software Installed Flips on Drata Agent install Install Drata Agent on the 8 laptops 👤 high
29 Security Patches Auto-Applied Flips on Drata Agent install Install Drata Agent 👤 high
30 Screen Lock Required Flips on Drata Agent install Install Drata Agent 👤 high
31 Hard-Disk Encryption Enabled Flips on Drata Agent install Install Drata Agent 👤 high
32 Password Manager Records Flips on Drata Agent install Install Drata Agent 👤 high
33 Independent Board of Directors Founder-led governance; no independent board Mark N/A w/ justification (out-of-scope-tests.md) 🚫 high
34 Infrastructure Accounts Properly Removed Offboarding test; no terminations yet Mark N/A until first termination 🚫 high
35 Terminated Version Control Accounts Removed Same — no terminations yet Mark N/A until first termination 🚫 high

3. Spec corrections (where the handoff was wrong, verified)

Section titled “3. Spec corrections (where the handoff was wrong, verified)”
  1. Wave 0 is not a rescan. WAF/LB Terraform was merged but never applied; the resources don’t exist in ordermatic-prod. (#1926 precedent — generalizes to every TF row.)
  2. “Create an alert policy” understates the monitoring blocker. The repo has zero monitoring alert policies, and the app DB (Neon), queue (Temporal/Redis), and object store (R2) are not GCP resources — Drata’s GCP connector can’t see them. Several of these need a non-GCP control or N/A, not a GCP alert.
  3. The branch protection the deploy workflow relies on is fictional. auto-deploy-main.yml says “main’s branch protection allows this workflow’s token to push; humans cannot” — but main protection is 404. main is wide open.
  4. The one ruleset is inert, not protective. Ruleset 6222454 (“Pull-Requests Only”, active) has an empty include[] → targets no branch, 0 approvals.
  5. Org 2FA was assumed enforced; it’s OFF. two_factor_requirement_enabled:false — a config gap, not a plan limit.
  6. Bucket versioning is not a code/rescan fix — there are zero google_storage_bucket resources to detect or toggle.
  7. Zone Redundancy / Cloud SQL HA assumed a GCP-managed app DB — the app DB is Neon (external), and the Cloud SQL that exists is ZONAL.
  8. “Public SSH Denied” is already satisfied in code — just verify no legacy rule survives outside TF.

4. Fastest path to green (ordered by tests-cleared-per-action)

Section titled “4. Fastest path to green (ordered by tests-cleared-per-action)”
  1. Drata Agent on the 8 laptops → clears 5 (Wave 2: #28–32). Highest leverage on the board.
  2. Publish the 6 people artifacts (#1932) to Drata + sign-off → clears 6 (#19–24).
  3. Flip GitHub org-wide 2FA (after both members enable personal 2FA) → clears #14; cheap, console-only.
  4. Mark the 3 N/A (#33–35) with justification → clears 3, zero eng work.
  5. Apply GitHub branch protection (proposal §3a/§3b: real staging review gate + a ruleset that actually targets main with FF-bot bypass) → clears 3 (#11–13). Test FF promotion before relying; revert on break.
  6. Confirm Workspace 2SV enforcement (admin console + evidence) → clears 2 (#15–16, GCP rides Workspace).
  7. Apply the WAF/LB cutover (Wave 0) → clears 2 (#1–2); high audit weight.
  8. Build + apply the GCP monitoring module (4 alert policies + channel) → clears the GCP-visible DB/instance tests (#3–6); separately raise the Neon-gap + queue-age (#7) decisions.
  9. Verify-only quick wins: confirm no legacy default-allow-ssh (#9, likely already green) + map the 2 GitHub accounts in Drata (#18, already green).
  10. Approve a background-check vendor → unblocks 2 (#26–27); assign training (#25) in parallel.

Longer poles needing a human decision: bucket versioning (#8 — identify + gsutil per bucket), Zone Redundancy scope (#10 — Neon N/A vs. Cloud SQL → REGIONAL with cost sign-off), and the queue-age control (#7).

5. The recurring caveat: merged ≠ applied

Section titled “5. The recurring caveat: merged ≠ applied”

For every 🤝 infra row (WAF/LB, monitoring alerts, Cloud SQL HA), the agent can write and PR the Terraform, but a human must terraform apply (gcloud/IAM/TF applies are classifier-gated). Drata only sees the resource once it exists in ordermatic-prod. Don’t trigger a Drata rescan until the apply has landed — there’s nothing to find otherwise.

6. Refinements (laziest path / reuse what exists)

Section titled “6. Refinements (laziest path / reuse what exists)”
  • WAF (#1–2): try the Cloudflare WAF before the GCP Cloud Armor LB. The zone is already on Cloudflare (DNS-only today). Enabling Cloudflare proxy + managed WAF is one toggle vs. the multi-phase GCP Cloud Armor LB cutover (#1926: NEG, cert, anycast IP, DNS flip, ingress lockdown). Build the GCP LB only if Drata won’t credit the Cloudflare WAF — confirm Drata’s detection path first.
  • N/A (#33–35): use the Drata UI, not the API. The Public API only offers enabled=false (disable), which is not a formal “Not Applicable.” In the Drata UI, mark each test Not Applicable with the rationale from out-of-scope-tests.md. Re-enable the two offboarding tests at the first termination.
  • CC6/CC7 evidence: attach the existing CASA assessment; don’t re-document. Tenant isolation, encryption (AES-256-GCM/PBKDF2), TLS, and the supply-chain gate are already assessed in casa-self-assessment.md. Map CASA → the SOC 2 controls as evidence (readiness-doc Step 3) rather than generating new technical-control evidence.