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

8.5 KiB

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.