Files
ITWorx Pulse release export bd774932d5
Public source validation / validate (push) Failing after 3m8s
Publish ITWorx Pulse source
2026-09-03 02:09:19 +02:00

249 lines
8.5 KiB
Markdown

# Security threat model
## 1. Assets
- Unraid host and storage.
- Docker/container metadata and internal topology.
- Prometheus metrics and labels.
- Service URLs and availability data.
- OIDC identities/roles.
- Pulse configuration, alerts, incidents and audit.
- Notification/probe credentials.
- Database backups.
- Server access path used by Codex during deployment.
## 2. Trust boundaries
- Browser to Pulse.
- Pulse to Authentik.
- Pulse to PostgreSQL.
- Pulse to Prometheus.
- Pulse agent to host/Unraid/Docker.
- Probe worker to network targets.
- Notification worker to external channels.
- Codex workspace to production server.
## 3. Primary threats and controls
### M0 discovered deployment posture
The target host already runs Nginx Proxy Manager, Authentik, Grafana, and multiple Docker/Compose projects. Pulse treats all of them as external protected resources. Existing containers with broad privileges, including any Docker socket access, are not reused as a Pulse pattern. Pulse must be isolated on dedicated resources, integrate with the proxy and OIDC provider additively, and remain server-side for all Unraid/Prometheus access.
M0 did not identify a local Prometheus service; this is an explicit datasource uncertainty, not permission to substitute an unreviewed source. Missing or stale telemetry must map to `Unknown`. No hostname, port, network, volume, or path is trusted until the deployment task rechecks ownership and conflicts.
### Unrestricted Docker/host control
Threat: compromise of web/API leads to host root-equivalent access.
Controls:
- no unrestricted socket in web/API;
- separate agent/proxy;
- endpoint allowlist;
- read-only capability contract;
- non-root API;
- network separation;
- architecture test of compose/mounts;
- no mutation API in v1.
### SSRF from service probes
Threat: user config probes metadata, loopback, admin services or redirects.
Controls:
- role restriction;
- scheme/port allowlist;
- DNS resolution validation before and after redirect;
- block metadata/link-local/unspecified by default;
- configurable LAN allowlist;
- response size/time limits;
- no arbitrary methods/body;
- redacted logging;
- tests for DNS rebinding/redirect escape.
### Query abuse
Threat: expensive or injection-like Prometheus queries cause outage or expose labels.
Controls:
- semantic query templates;
- bounded scope/range/series/points;
- server-side parameterization/escaping;
- timeout/concurrency/rate limit;
- advanced raw query separate permission;
- audit and query cost metrics.
### Optional hardware capabilities
Hardware sensors and GPU telemetry are optional read-only capabilities. The adapter accepts only normalized bounded snapshots from an approved source; absent support is disabled and unsupported support remains inspectable without being treated as a host failure. API/web never gains device, mount, namespace or Docker-socket access for these values.
### Authentication/authorization bypass
Controls:
- standards-based OIDC validation;
- issuer/audience/nonce/state/PKCE;
- secure cookies;
- server-side RBAC;
- WebSocket auth/origin/subscription auth;
- CSRF protection where cookies are used;
- role matrix tests;
- break-glass disabled by default.
### XSS and dashboard import
Controls:
- no arbitrary HTML/JS widgets;
- sanitize Markdown;
- schema validation;
- safe chart labels/tooltips;
- CSP;
- escaped event/upstream text;
- import size and complexity limits.
### Secret leakage
Controls:
- external secret injection;
- encrypted-at-rest channel/probe references;
- redaction middleware;
- no env dumps;
- evidence policy;
- secret scan;
- diagnostic bundle allowlist;
- backups exclude plaintext or are encrypted/secured.
### Supply chain
Controls:
- lockfiles;
- minimal maintained dependencies;
- provenance/SBOM where feasible;
- vulnerability scanning;
- pinned base images;
- non-root runtime;
- update policy;
- build in CI/clean environment.
### Database compromise/data integrity
Controls:
- isolated network;
- dedicated credentials;
- TLS when remote;
- least privilege;
- migrations/transactions;
- backup/restore;
- input validation;
- audit;
- no exposed database port unless controlled testing override.
### Live/WebSocket abuse
Controls:
- authentication before upgrade;
- opaque HttpOnly sessions with an eight-hour sliding idle limit and a finite,
operator-bounded absolute limit; renewal never exposes OIDC tokens to the
browser, while a revocable session context propagates through HTTP upgrades
so logout, absolute expiry and request/server cancellation also close an
already established socket and release its subscriptions;
- origin policy;
- message/rate/size limits;
- max subscriptions/series;
- idle timeout/heartbeat;
- bounded send queue and slow-client eviction;
- no secret data in messages.
### Alert/notification abuse
Controls:
- RBAC and audit;
- versioned rules;
- safe templates;
- channel test rate limits;
- idempotency;
- recipient allowlist/policy;
- no secret values in notification body.
### Deployment mistakes
Controls:
- discovery and port/network/volume conflict checks;
- backup touched configs;
- isolated compose project;
- offline validation;
- health/smoke tests;
- rollback;
- no prune/delete/unrelated modifications;
- production evidence.
## 4. Security headers
At minimum:
- Content-Security-Policy;
- frame restrictions;
- nosniff;
- strict referrer policy;
- permissions policy;
- HSTS when HTTPS deployment is stable;
- secure/same-site/httpOnly cookies.
## 5. Container hardening
Where compatible:
- non-root;
- read-only root filesystem;
- tmpfs for temporary paths;
- drop all capabilities, add only required;
- no-new-privileges;
- seccomp/default profile;
- resource limits;
- explicit networks;
- no public database/collector ports;
- healthchecks;
- immutable image digest in production record.
The agent may need narrow exceptions; document and test each.
### Deployment hardening pass (2026-08-04)
- Resource limits are set on all six `deploy/compose.yaml` services via the
non-swarm `cpus`/`mem_limit`/`mem_reservation`/`memswap_limit` keys (the
project runs plain `docker compose up`, not swarm); sizing rationale is
inline in that file against `docs/architecture/SYSTEM_ARCHITECTURE.md` §7.
- `pulse-postgres` now runs `read_only: true` with tmpfs for `/tmp` and
`/var/run/postgresql`; all six services are now read-only-root. This
closes the previously undocumented exception; see
`docs/operations/DEPLOYMENT_UNRAID.md` §6/§8 for the required smoke test.
- Immutable image digests are enforced by `deploy/verify-image-digests.sh`
and CI. Every external registry image in `deploy/*.Dockerfile` is pinned to
a verified digest; only Docker's built-in `scratch` rootfs is exempt because
it has no registry manifest. See `deploy/IMAGE_DIGESTS.md` for the ledger.
- `pulse-worker`/`pulse-agent` healthchecks now verify a heartbeat file's
freshness instead of `kill -0 1`, and self-restart the container on
staleness (`docker compose up` does not restart on "unhealthy" status
alone). Contract for the Go runtime:
`docs/operations/WORKER_AGENT_HEALTHCHECK_CONTRACT.md`.
- `deploy/nginx.conf` now sends `Strict-Transport-Security` from
`pulse-web` as defence-in-depth (§4), verified not to conflict with
TLS terminating at Nginx Proxy Manager per ADR-0010.
## 6. Security acceptance
Required:
- threat model review at M0 and M9;
- SAST/dependency/image/secret scans;
- auth/RBAC matrix tests;
- SSRF suite;
- WebSocket security suite;
- dashboard import/XSS suite;
- query limit/validation suite;
- compose privilege/mount test;
- backup secret inspection;
- production exposure scan from permitted network.
### M7-02 implementation
The probe policy validates scheme, host and port before resolution, rejects loopback/link-local/metadata/multicast/unspecified addresses, and requires explicit CIDR permission for private LAN targets. The safe client repeats resolution at dial time and revalidates redirect destinations. Only bounded GET/HEAD requests with an allowlisted header set are accepted; responses are size/time limited. Policy changes are audit events containing no credentials or full request data.
### M8-08 notification controls
Notification channel persistence accepts only secret references and rejects sensitive configuration keys such as token, password, secret, and authorization. Delivery bodies and subjects are bounded. Sender errors are newline-normalized, length-bounded, and redacted before persistence; bearer credentials are removed as a complete value. Test sends are rate limited and never write delivery records.