docs: WS-7 closure — RFC status + SECURITY_AUDIT + BACKLOG + sync config
PR-4 commit 3 — closure-bookkeeping nu de implementation-PRs en de twee runbooks gemerged zijn. - RFC-WS-7-OBSERVABILITY.md: nieuwe §9 Implementation status (mei 2026) vat samen welke acceptance criteria via PR-1..PR-4 zijn voldaan en welke (1, 2, 7, 9, 10) op Bert's deploy-checklist resteren. Pointer naar ARCH-OBSERVABILITY.md als levende reference; de RFC blijft historisch document. - SECURITY_AUDIT.md: nieuwe sectie 'WS-7 Observability — finale audit (mei 2026)' tussen A13-10 en Positive Findings. Bevat (1) acceptance criteria checklist met status per criterium, (2) processing register entry voor GlitchTip (controller-not-processor, retention 90 dagen, TLS+full-disk-encryption+2FA), (3) zeven security controls die WS-7 introduceert (PII scrubbing, CSP whitelist, sourcemap upload-only, listener registration discipline, runtime portal-context-split, multi-tenant tag invariant, impersonation.active binary signal), (4) pointer naar runbooks/observability-erasure.md voor Art. 17. - BACKLOG.md: status-overzicht-tabel boven de OBS-entries. Toegevoegd als entry: OBS-2 (early-pipeline log context, ✅ Resolved), OBS-3 (sentry-context middleware coverage, ✅ Resolved — opgevouwen in AuthScopeContextListener), OBS-5 (Crewli render handlers report() invariant, ✅ Resolved via48f2a00+ ExceptionReportingTest), en OBS-9 (Active — staging environment GlitchTip CSP whitelist follow-up bij staging-introductie). Bestaande OBS-1, 4, 6, 7 ongewijzigd (Active); OBS-8 staat al op Resolved sindsdee1401. - .claude-sync.conf: drie nieuwe doc-paths toegevoegd (ARCH-OBSERVABILITY.md, runbooks/observability-triage.md, runbooks/observability-erasure.md). Post-commit sync-claude-docs hook regenereert SYNC_MANIFEST.md met deze entries. Closes WS-7 documentation acceptance criteria 8 (ARCH) en 14 (SECURITY_AUDIT). Resterende criteria (1, 2, 7, 9, 10) zijn deploy-checklist door Bert. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -618,6 +618,113 @@ Audit scope: all files under `api/` and `apps/` (app, portal).
|
||||
|
||||
---
|
||||
|
||||
## WS-7 Observability — finale audit (mei 2026)
|
||||
|
||||
### Acceptance criteria
|
||||
|
||||
Alle 14 criteria uit `RFC-WS-7-OBSERVABILITY.md §6` zijn geadresseerd:
|
||||
|
||||
| # | Criterium | Status |
|
||||
|---|---|---|
|
||||
| 1 | GlitchTip op `monitoring.hausdesign.nl` met TLS + 2FA | Bert-handmatig (deploy-checklist) |
|
||||
| 2 | Twee projecten + DSNs in 1Password vault | Bert-handmatig (deploy-checklist) |
|
||||
| 3 | Laravel SDK geïntegreerd; errors uit prod-API verschijnen <60s | ✅ PR-2 |
|
||||
| 4 | apps/app SDK geïntegreerd; errors met org/user/release context; portal-routes strict scrub | ✅ PR-3 |
|
||||
| 5 | Sourcemaps upload werkt; leesbare stack traces; `.map` afwezig in publieke bundle | ✅ PR-3 (`deploy.sh`) |
|
||||
| 6 | PII scrubbing-tests groen (backend + frontend) | ✅ PR-2 + PR-3 |
|
||||
| 7 | Smoke test induced 500 in staging | Bert-handmatig (deploy-checklist) |
|
||||
| 8 | `ARCH-OBSERVABILITY.md` geschreven (WS-8b) | ✅ PR-4 |
|
||||
| 9 | Email-alerting geconfigureerd + getest | Bert-handmatig (GlitchTip UI configuratie) |
|
||||
| 10 | Retention-policy 90 dagen toegepast | Bert-handmatig (GlitchTip admin) |
|
||||
| 11 | Daily postgres-backup-script in place | ✅ PR-1 |
|
||||
| 12 | Activity_log indexes (D-06) gemigreerd | ✅ Pre-existing (Spatie default `nullableMorphs`); regression-guard `tests/Feature/Database/ActivityLogIndexesTest.php` |
|
||||
| 13 | Structured logging conventie geïmplementeerd; `X-Request-Id` round-trip getest | ✅ PR-2 |
|
||||
| 14 | `SECURITY_AUDIT.md` bijgewerkt | ✅ This entry |
|
||||
|
||||
### Processing register
|
||||
|
||||
GlitchTip is opgenomen in Crewli's processing register als zelfstandig
|
||||
verwerkingsproces:
|
||||
|
||||
- **Doel:** defectdetectie en service-availability monitoring.
|
||||
- **Categorieën persoonsgegevens:** pseudonieme identifiers (ULIDs voor
|
||||
user/organisation/event), technische metadata (route names, HTTP
|
||||
methods, stack traces zonder locals).
|
||||
- **Bron:** geautomatiseerd captured uit Laravel API en apps/app SPA
|
||||
bij programmer/infra errors.
|
||||
- **Ontvanger:** alleen Bert (single super_admin met 2FA op GlitchTip
|
||||
web-UI).
|
||||
- **Bewaartermijn:** 90 dagen, daarna automatisch gepurged door
|
||||
GlitchTip's eigen partition-maintenance loop.
|
||||
- **Beveiligingsmaatregelen:** TLS in transit, full-disk encryption at
|
||||
rest, SSH-key + 2FA op web-UI.
|
||||
- **Controller / processor:** Crewli is **controller**. Self-hosted op
|
||||
Crewli-infra; geen processor-relatie of DPA-uitbreiding nodig.
|
||||
- **Procedure right to erasure (Art. 17):** zie
|
||||
[`runbooks/observability-erasure.md`](./runbooks/observability-erasure.md).
|
||||
|
||||
### Security controls die WS-7 introduceert
|
||||
|
||||
1. **PII scrubbing op events (back + front).** `SentryEventScrubber`
|
||||
(PHP) en `scrubEvent` (TypeScript) strippen sensitive body-keys,
|
||||
headers, query-params, cookies, en form_values voordat events naar
|
||||
GlitchTip gestuurd worden. Regression-guards:
|
||||
`tests/Feature/Observability/PiiScrubbingTest.php` (20 cases) en
|
||||
`apps/app/src/observability/__tests__/scrubber.spec.ts` (18 cases).
|
||||
|
||||
2. **CSP `connect-src` whitelist voor named ingest host.** Outgoing
|
||||
Sentry-events zijn beperkt tot `localhost:8200` (dev) en
|
||||
`monitoring.hausdesign.nl` (prod). Geen exfiltration mogelijk naar
|
||||
arbitrary hosts. Regression-guard:
|
||||
`tests/Feature/Security/CspConnectsToObservabilityTest.php`. Zie
|
||||
ook A13-9 hierboven.
|
||||
|
||||
3. **Sourcemap upload-only, never public-mapped.** `deploy.sh` upload
|
||||
sourcemaps naar GlitchTip vóór `find apps/app/dist -name '*.map'
|
||||
-delete`. Stack-traces leesbaar in GlitchTip UI; geen `.map`
|
||||
bestanden bereikbaar via productie-bundle. Default soft-fail op
|
||||
upload faalt zodat deploy doorgaat (unmapped frames in GlitchTip
|
||||
is acceptabel; geblokkeerde deploy niet).
|
||||
|
||||
4. **Listener registration discipline.** Auto-discovery
|
||||
uitgeschakeld; alle observability listeners expliciet geregistreerd
|
||||
in `AppServiceProvider::boot()` met array-callable form.
|
||||
Regression-guard:
|
||||
`tests/Feature/Observability/EventListenerRegistrationTest.php`
|
||||
(BACKLOG OBS-8). Voorkomt silent double-emission die op een
|
||||
toekomstig moment additive operations zou breken.
|
||||
|
||||
5. **Runtime context-split portal/organizer.** Frontend portal-zone
|
||||
(`route.meta.public === true && route.meta.context === 'portal'`)
|
||||
krijgt geen `user_id` of `username` op events. RFC §3.7 frontend-
|
||||
block punt 5 — ULID-tokens voor token-based access (artist
|
||||
advance, public form fill) blijven uit GlitchTip-events.
|
||||
Regression-guard:
|
||||
`apps/app/src/observability/__tests__/contextBinding.spec.ts`
|
||||
(cross-zone leak test).
|
||||
|
||||
6. **Multi-tenant invariant op tag-niveau.**
|
||||
`actor_scope=organisation` impliceert valide ULID `organisation_id`;
|
||||
`actor_scope=platform` impliceert geen `organisation_id` (forced
|
||||
fallback zou misleidend zijn). Regression-guard:
|
||||
`AuthScopeContextListenerTest::test_organisation_id_present_when_actor_scope_is_organisation`.
|
||||
|
||||
7. **`impersonation.active` always-present binary signal.** Default-
|
||||
in-listener (`'false'`) + override-in-middleware (`'true'`) pattern
|
||||
garandeert dat élke authenticated event een binary signal voor
|
||||
filtering heeft. Regression-guard:
|
||||
`AuthScopeContextListenerTest::test_impersonation_active_default_false_across_every_actor_scope_branch`.
|
||||
|
||||
### Pointer naar Art. 17 procedure
|
||||
|
||||
GDPR right-to-erasure verzoeken voor GlitchTip-data: zie
|
||||
[`runbooks/observability-erasure.md`](./runbooks/observability-erasure.md)
|
||||
voor stap-voor-stap procedure. Geautomatiseerd erasure-script staat
|
||||
op BACKLOG; tot dan handmatige psql-procedure met audit-trail
|
||||
verplichting.
|
||||
|
||||
---
|
||||
|
||||
## Positive Findings
|
||||
|
||||
The following security measures ARE correctly implemented:
|
||||
|
||||
Reference in New Issue
Block a user