Hardening¶
Statement¶
ClaimGuard's production VM (claim-guard-app-1) is a Google Cloud
Deep Learning VM (DLVM) image with a documented incremental-hardening
plan against it. The host runs with up-to-date OS packages, on the
least-privilege claim-guard-vm service account (swapped 2026-05-02),
with Shielded VM Secure Boot enabled (also 2026-05-02), and is
operated through IAP-SSH rather than direct sshd. The remaining
host-level hardening step — OS Login — is queued for plan step
A1.6, deferred because it requires dev-team coordination
(re-keying laptops + osLogin grant management).
This control sits at partial specifically because OS Login is not yet enforced. Secure Boot and the SA swap, previously listed here as known gaps, landed 2026-05-02.
Implementation¶
Host configuration today¶
- Image: Google Cloud Deep Learning VM image (Linux). Standard
GCP-managed kernel; package updates land via the standard
unattended-upgrades /
aptflow. - Shielded VM:
- vTPM: on.
- Integrity monitoring: on.
- Secure Boot: on (enabled 2026-05-02 in the A1.5 maintenance window combined with A1.1).
- OS Login: off at the project metadata level (queued for A1.6); SSH today uses metadata-keyed access on top of IAP.
- Service account: the VM runs under
claim-guard-vm@train-cvit2.iam.gserviceaccount.com(least-privilege), swapped from the default Compute SA on 2026-05-02 (plan step A1.1 combined with A1.5). Per-secretsecretAccessorbindings only; no project-levelroles/editor. See Privileged access.
Process posture¶
- pm2 as the process supervisor. Crash-restart, log rotation, and
pm2 resurrecton boot via thepm2-roee.servicesystemd unit (wired 2026-05-02 — until then the dump existed but no boot-time trigger fired it, which surfaced when Tier D rebooted the VM). - Application boot depends on
JWT_SECRETand other secrets; server refuses to start if they're unset. The values are sourced from local.envtoday (the Secret Manager fallback exists but theUSE_SECRET_MANAGERgate is not flipped on in prod — see Secrets management). - No server-side admin daemons beyond what the application requires. No RabbitMQ, no Redis, no Elasticsearch on this VM.
Firewall and SSH¶
- No public SSH endpoint. SSH is gated through GCP's IAP. See Privileged access for the IAM side, Network security for the firewall side.
- No legacy world-open SSH rules. The duplicated
allow-ssh/default-allow-sshrules were deleted on 2026-04-28 (plan step A0.2).
Logging and monitoring¶
- Cloud audit logs for every privileged action. 400-day immutable retention. See Audit logging (cloud).
- Application logs via pm2 stdout / stderr capture, rotated locally. Not yet shipped to Cloud Logging — cross-listed on Application audit logging.
- Integrity monitoring signals are visible in the GCP console but not yet wired into a paging channel — queued.
What hardening looks like in practice today¶
- A1.1 + A1.5 ran together in a maintenance window 2026-05-02.
Total observed downtime: ~6 minutes. Pre-window boot-disk
snapshot (
claim-guard-pre-secboot-2026-05-01) was taken as failsafe and remains in place during the soak period. - A1.6 (OS Login) is the remaining bundle item, deferred because it disables the existing metadata-keyed SSH path used by the dev team — needs each operator's laptop re-keyed + osLogin grants managed. Will be scheduled once the team is ready to absorb the change.
What's deliberately not in scope for this page¶
- VM-level antivirus / EDR. Out of scope for a Linux GCP VM at this stage.
- CIS-benchmark scanning. Not running today; revisit at SOC 2 Type II.
- Container hardening. The application does not run in containers on this VM; tools/services are pm2-managed processes. Container hardening becomes a relevant control if a future architecture introduces them.
Status¶
partial — verified 2026-05-02.
What's in place:
- DLVM image with current OS package state.
- Shielded VM features (vTPM, integrity monitoring, Secure Boot) enabled. Secure Boot landed 2026-05-02 in the A1.5 window.
- VM runs under least-privilege
claim-guard-vmSA (swapped 2026-05-02 in the A1.1 window). - IAP-only SSH; no world-open SSH or RDP.
- pm2 startup wired to systemd (
pm2-roee.service) 2026-05-02 — future reboots auto-resurrect the 8 pm2 processes. - Documented, reproducible boot path; Secret Manager bootstrap in code (gate not yet flipped — see secrets-management page).
- Cloud audit logging on every privileged action.
Known gaps¶
- OS Login is off — plan step A1.6. Until enabled, SSH
metadata-keyed access lives on top of IAP, and stale home
directories for removed users persist on the VM. (The
corresponding metadata
ssh-keysentries for those removed users were cleaned up 2026-05-02; on-disk dirs remain.) USE_SECRET_MANAGERgate is not flipped on in prod. Theclaim-guard-vmSA holds the per-secret accessor grants but the bootstrap's gate is unset, so secrets actually come from on-disk.envfiles. Cross-listed on Secrets management.- Integrity-monitoring signals are not wired into alerting.
- No CIS-benchmark scan or routine OS-level vulnerability scan beyond the GCP-managed package update flow.
Roadmap¶
- A1.6 (OS Login enable) — needs dev-team re-keying coordination. Closes the metadata-keyed SSH path + enables cleanup of stale home dirs.
- Activate
USE_SECRET_MANAGER=1+ remove secret values from.envfiles so the runtime data path actually exercises the pre-provisioned SA grants. - CIS-benchmark scan at SOC 2 Type II preparation time.
- Integrity-monitoring alert pipeline wired into the eventual audit-log alerting infrastructure (cross-listed on Incident response).
- Container hardening framework if and when the architecture introduces containers.