Stratify
Legal and compliance

Logging & Monitoring Policy

docs/compliance/isms/policies/POL-08-logging-monitoring.md

Source updated 03. Aug. 2026

Logging & Monitoring Policy

Satisfies Annex A 8.15 (logging), 8.16 (monitoring activities), and 8.17 (clock synchronization). Grounded in `register/facts.md`; statuses match `register/controls.yaml`.

1. Policy statement

Stratify commits to capturing security-relevant events across the application and infrastructure it operates, and to having a real (not merely dashboard-configured-somewhere) process for noticing when something is wrong. Today that commitment is partially met: error telemetry and analytics events are captured on the server side, but a front-end visibility gap and an alerting gap both exist and are stated plainly below rather than assumed away.

This policy does not claim a mature logging/monitoring posture. It states what's real, what isn't, and what the minimum forward bar looks like.

2. What's captured today

  • Sentry (server-side only) captures errors from the Node runtime, at a

tracesSampleRate of 0.1, with PII sanitization enabled per dsgvo-data-flow.md:126 (facts.md, apps/web/instrumentation.ts:1-18).

  • PostHog (EU region, `eu.i.posthog.com`) captures analytics events with

autocapture: false — only explicit identify() calls and deliberately-instrumented events are recorded, not a raw clickstream (apps/web/lib/posthog/client.ts:9,15, facts.md).

Both of these are real, currently operating, and scoped in ways that reduce unnecessary personal-data capture (autocapture off, PII sanitization on) — this is a genuinely privacy-conscious default, not just a cost-saving one.

3. Logging (8.15) — status: partial — the real gap

No client-side/browser Sentry initialization exists. apps/web/instrumentation.ts only initializes Sentry for the Node runtime; there is no sentry.client.config.ts anywhere in the codebase (facts.md). This means front-end JavaScript errors — including security-relevant ones, such as a broken auth redirect, a failed client-side permission check, or an unexpected state in the sign-in/OTP flow — may occur in a subscriber's or partner's browser and never reach any system Stratify monitors. This is tracked as RISK-008 in register/risks.yaml (likelihood 3, impact 2, inherent score 6, treatment: mitigate, mapped to control 8.16).

This is scored partial, not not_started, because server-side logging is real and substantive — the gap is specifically the client side, not logging as a whole.

Commitment: client-side error capture is the concrete, achievable next step for this control — a sentry.client.config.ts alongside the existing server instrumentation, at the same conservative sample rate and PII-sanitization posture already applied server-side. No delivery date is committed here; see §6 and GOV-08 for how objectives with dates get set.

4. Monitoring activities (8.16) — status: not_started

No alerting rules, no on-call process, and no monitoring runbook are documented anywhere in this repository. facts.md states this plainly: "appears managed outside the repo (dashboard config), which is itself an ISMS evidence gap worth naming rather than assuming exists." This document repeats that framing deliberately — the honest position is not "no monitoring exists," it is "if monitoring exists, it isn't evidenced anywhere an auditor, partner, or future team member could find it." Those are different claims, and only the second one is defensible without direct verification of Sentry/PostHog dashboard configuration outside this repo.

What this means concretely: there is no confirmed mechanism today that would notice, in real time, if:

  • The verifyChain() audit-log integrity check ever reported { ok: false } in production

(the P0 scenario the entire incident runbook in docs/runbooks/db-recovery.md §3.3 is built around — see POL-09).

  • The nightly pg_dump backup cron job failed silently.
  • Error rates on the production host spiked outside the sampled 10% Sentry captures.

Commitment: the minimum forward bar for this control is at least one alerting rule tied to the one incident scenario Stratify already has a real runbook for — the audit-chain corruption case in db-recovery.md §3.3. Wiring an alert for verifyChain() failures is a smaller, more tractable first step than building general alerting infrastructure, and it directly closes the gap between "we have a P0 runbook" and "we'd actually find out P0 is happening." This is stated as a direction, not a committed date — see GOV-08 (Security Objectives & Metrics, pending) for where a dated target belongs.

5. Clock synchronization (8.17) — status: not_started

No explicit clock-synchronization control is documented for the Hetzner host. Standard NTP almost certainly applies by default on the underlying OS, but this has not been confirmed or stated as policy. This matters specifically for Stratify because the audit-log chain-hash mechanism and its verifyChain() replay (apps/web/lib/audit/chain.ts:34-39,60-67,101-137) depend on event ordering and timestamps being trustworthy — a host with drifted or unsynchronized clocks would undermine confidence in exactly the control (audit-log integrity) that Stratify relies on most heavily as evidence toward partners and, eventually, regulators.

Commitment: confirm and document that NTP (or an equivalent time-sync mechanism) is active on the Hetzner host, as a low-effort, high-signal-value close-out of this control.

6. Forward-looking minimum bar

Rather than commit to a fabricated rollout schedule, this policy states the minimum bar the next iteration of logging/monitoring should meet, and defers actual target dates to GOV-08 (Security Objectives & Metrics, pending):

  1. Client-side error capture (§3) — closes the front-end visibility gap tracked as RISK-008.
  2. At least one alerting rule tied to the audit-chain-corruption scenario (§4) — the

cheapest, highest-value monitoring investment given the P0 runbook already exists for it.

  1. Confirmed, documented clock synchronization on the production host (§5).

Achieving all three would move 8.15 and 8.16 from partial/not_started toward implemented in controls.yaml — this policy does not pre-emptively claim that status before the work is done.

7. Related documents

  • GOV-08 — Security Objectives & Metrics (pending) — where dated targets for the items in §6

belong

  • POL-07 — Operations & Change Management Policy (§8, capacity management, a related

monitoring gap)

  • POL-09 — Incident Management Policy (the audit-chain-corruption scenario referenced in §4)
  • docs/runbooks/db-recovery.md §3.3 — the P0 runbook this policy's alerting priority is

built around

  • register/risks.yaml — RISK-008 (front-end error visibility gap)
  • PRO-12 — Logging, Monitoring & Alerting (pending per PLAN.md §4) — the procedure-level

document this policy's commitments will be executed through