Classification: CONFIDENTIAL — Internal Use Only
Document version
v1.0 — 2026-04-18 — derived from forms-backend/compliance/cis-pci-nist-mitre.md at Phase 1 cut.
This document is the authoritative mapping of the Forms Portal (forms.greenpeace.us) implementation against CIS Controls v8, PCI-DSS v4.0, NIST 800-53 Rev 5, and MITRE ATT&CK mitigations. It is reviewed quarterly by the Director of Cyber Security and requires owner sign-off before production cutover (tracked in Cowork Task 6 of the Phase 1 runbook).
The operational/architecture description of the portal lives at Forms Portal — forms.greenpeace.us. This page covers controls and evidence only.
Data classification
| Data element |
Classification |
Handling |
| Submission field values (default) |
CONFIDENTIAL |
AES-256-GCM envelope encryption, per-submission DEK wrapped by KMS |
Searchable field mirrors (searchable: true) |
INTERNAL |
Plaintext JSONB column, indexed for admin search |
| Attachments |
CONFIDENTIAL |
GCS with CMEK, signed URLs, ClamAV scanned, 7-year retention lock |
| Submitter identity (email, username) |
INTERNAL |
Plaintext columns (operational necessity for audit) |
| Audit log |
CONFIDENTIAL |
Append-only (REVOKE UPDATE/DELETE), 7-year retention |
| DEK wrapping key |
RESTRICTED |
Cloud KMS, CMEK, software-protected, automatic 90-day rotation |
Encryption — data in transit
| Channel |
Protocol |
Enforcement |
| Browser → Cloud Run |
TLS 1.3, HSTS 2yr + preload |
Cloud Run managed cert; HSTS header set in app.py |
| Cloud Run → Cloud SQL |
TLS 1.3 + mTLS via Cloud SQL Connector |
IAM auth; enable_iam_auth=True in db.py |
| Cloud Run → KMS / GCS / Secret Manager |
TLS 1.3 (Google private endpoints) |
Service account OAuth2 via ADC |
| Cloud Run → HappyFox |
HTTPS (TLS 1.2+) |
Validated in requests call |
| Cloud Run → VPC (private IP) |
TLS via Cloud SQL Connector |
vpc-egress=private-ranges-only |
Encryption — data at rest
| Asset |
Cipher |
Key |
| Cloud SQL storage |
AES-256 (Google-managed layer) + CMEK (customer-managed) |
gpus-forms-cmek |
| Cloud SQL automated backups |
Same as instance |
Inherited |
| Submission field values |
AES-256-GCM |
Per-submission DEK, wrapped by KMS key gpus-forms-dek-wrapper |
| GCS attachments bucket |
AES-256 + CMEK |
gpus-forms-cmek |
| GCS backup bucket |
AES-256 + CMEK |
gpus-forms-cmek |
| Secret Manager |
AES-256 (Google-managed) |
Managed |
CIS Controls v8
| Control |
Title |
Implementation |
| 3.11 |
Encrypt Sensitive Data at Rest |
CMEK on Cloud SQL + GCS; AES-256-GCM envelope on submission fields |
| 3.12 |
Segment Data Processing |
Dedicated service account gpus-forms-backend@; private IP; VPC connector |
| 4.4 |
Firewall |
Cloud SQL private IP only; Cloud Armor WAF at edge; Cloud Run no-allow-unauthenticated |
| 5.1 |
Account Management |
Okta SSO via OIDC; users table mirrors Okta identity; roles admin/viewer only |
| 6.3 |
Multi-factor Authentication |
MFA enforced by Okta policy at tenant level |
| 6.8 |
Privileged Account Access |
Admin role granted in users table; audited via user_granted/user_revoked events |
| 8.2 |
Audit Log Collection |
Append-only audit_log table; structured JSON to Cloud Logging → CEDAR |
| 8.3 |
Log Storage |
7-year retention; Cloud Logging sink to GCS with bucket lock |
| 8.5 |
Centralized Log Management |
Cloud Logging → CEDAR Elasticsearch (existing pipeline) |
| 8.11 |
Audit Log Review |
Wazuh rules 100020–100025 on MAPLE; SOC dashboard Tickets tab |
| 10.6 |
Vulnerability Scanning |
Cloud Build step runs bandit + pip-audit; OAK OpenVAS weekly; Artifact Registry vuln scanning |
| 13.1 |
Threat Detection |
Wazuh rules trigger SOC auto-ticketing at level ≥ 10 |
| 16.1 |
Secure Application Development |
Pydantic input validation; parameterized SQL via SQLAlchemy; CSRF tokens; security headers |
PCI-DSS v4.0
Forms portal does not process cardholder data. PCI-DSS mapping documented for defense-in-depth alignment only.
| Req |
Implementation |
| 1.2.1 |
Inbound traffic restricted — Cloud Run auth required, Cloud Armor WAF filters |
| 2.2.1 |
Secure configuration — CIS-hardened base image, distroless python, non-root container user |
| 3.5 |
Key management — KMS-wrapped DEK; rule 100024 fires on decrypt failure |
| 3.6 |
Key rotation — KMS automatic 90-day rotation; re-encrypt job runs on key version change |
| 4.1 |
Strong cryptography for transmission — TLS 1.3, HSTS preload |
| 6.5.9 |
Protect against CSRF — Flask-WTF CSRF tokens; rule 100022 logs rejects |
| 7.1 |
Access to data limited to need — forms_viewer RLS role; admin actions audited |
| 8.3.6 |
Password complexity — N/A (Okta SSO, no passwords in forms portal) |
| 10.2.1–10.2.7 |
Audit trails — audit_log captures auth, admin, decrypt, export events |
| 10.3 |
Audit trail protection — REVOKE UPDATE/DELETE on audit_log; central forwarding to CEDAR |
| 10.7 |
Log retention — 7 years |
| 11.3 |
Vulnerability scans — OpenVAS weekly (OAK); image scan on every build |
NIST 800-53 Rev 5
| Control |
Implementation |
| AC-2 |
Account Management — Okta + users table sync |
| AC-3 |
Access Enforcement — @require_role decorators; Postgres RLS |
| AC-6 |
Least Privilege — 2 roles only; service account scoped to Cloud SQL client + KMS encrypter/decrypter + GCS object creator/viewer |
| AU-2 |
Event Logging — audit_log table + Cloud Logging |
| AU-6 |
Audit Record Review — Wazuh rules + SOC dashboard |
| AU-9 |
Protection of Audit Information — append-only, REVOKE UPDATE/DELETE |
| AU-11 |
Audit Record Retention — 7 years |
| CM-7 |
Least Functionality — minimal container, no shell, distroless-style |
| IA-2 |
Identification & Authentication — Okta OIDC, JWT verification |
| IA-5 |
Authenticator Management — handled by Okta |
| SC-8 |
Transmission Confidentiality — TLS 1.3 everywhere |
| SC-12 |
Cryptographic Key Establishment — KMS-managed CMEK + DEK |
| SC-13 |
Cryptographic Protection — AES-256-GCM, FIPS-validated via BoringCrypto in GCP |
| SC-28 |
Protection of Info at Rest — envelope encryption + CMEK |
| SI-4 |
System Monitoring — Prometheus + Wazuh |
| SI-10 |
Information Input Validation — pydantic |
MITRE ATT&CK mitigations
| Technique |
Mitigation |
| T1078 (Valid Accounts) |
Okta MFA; role-based access; account lifecycle via Okta lifecycle management |
| T1190 (Exploit Public-Facing Application) |
Cloud Armor OWASP rules; pydantic input validation; bandit + pip-audit on build |
| T1213 (Data from Information Repositories) |
RLS on submissions; decrypt events audited; bulk export rule 100025 |
| T1537 (Transfer Data to Cloud Account) |
Egress restricted to private ranges; signed URLs for attachments; bulk export alerts |
| T1552 (Unsecured Credentials) |
All secrets in Secret Manager; no passwords in code or env vars; IAM auth for DB |
| T1562 (Impair Defenses) |
Audit log append-only at DB role level; separate forms_readonly role for reports |
Control ownership
| Area |
Owner |
Review cadence |
| Cryptographic controls |
Director of Cyber Security |
Quarterly |
| Access controls (Okta + RLS) |
Director of Cyber Security |
Quarterly |
| Audit log review |
SOC |
Weekly (via SOC dashboard) |
| Vulnerability scanning |
SOC (OAK) |
Weekly |
| Key rotation verification |
Director of Cyber Security |
Quarterly |
| Retention policy enforcement |
Director of Cyber Security |
Monthly (purge job audit) |
Sign-off before production
- [ ] Director of Cyber Security reviews this document
- [ ] Wazuh rules deployed and verified firing on test events
- [ ] Prometheus alerts routed to correct email/Slack channels
- [ ] OAK OpenVAS target added, baseline scan complete with zero criticals
- [ ] Penetration test scope includes forms portal (update
pentest-schedule.md)
- [ ] Disaster recovery test completed (restore from GCS backup, verify decrypt works)
- [ ] IRP (
irp.md) updated with forms-portal-specific playbook entries
Forms Portal Compliance Controls · v1.0 · 2026-04-18 · GPUS-IT · Classification: CONFIDENTIAL — Internal Use Only