Docs · Deploy

Security model

Watchpost sits where infrastructure visibility, credentials, human response, and AI meet. Its threat model begins before the first collector is accepted, and every control on this page states its safe failure mode.

Two security domains

Watchpost user authentication and Watchpost Agent local authentication are separate security domains. They share a password derivation but never share identities, sessions, or authority.

Watchpost users

Central server accounts with viewer, operator, and administrator roles. Sessions are server-side and cookie-based; every API path enforces role and CSRF.

Agent local accounts

Loopback-local admin, technician, and viewer roles that remain manageable while Watchpost is unreachable. Local administration has its own session, Origin, and CSRF controls.

Authentication and sessions

Keep these distinct: a user session, a pairing request, an agent credential, a bootstrap token, and an installation identity are different authorities and are never interchangeable.

First-administrator bootstrap token

Dangerous remote first-administrator setup requires explicit operator authorization. The gate is enforced automatically whenever the listener is not loopback or whenever a token is supplied through an environment variable or token file. Loopback-only first setup may proceed under its documented local trust model unless the operator supplies a token, which forces the requirement even on loopback. On the agent, WATCHPOST_AGENT_EXPOSE only permits a non-loopback bind; it does not by itself enable the token gate on a loopback listener, so a loopback-behind-proxy deployment must supply a token explicitly.

Explicit reverse-proxy trust

Forwarded headers are not authority. Central Watchpost does not implement a trusted-proxy resolver: it does not use forwarded client-IP or scheme headers for authorization, and there is no WATCHPOST_TRUSTED_PROXIES setting. Its proxy boundary is loopback binding, TLS termination at the proxy, original-Host preservation, --secure-cookies, and firewall or network policy.

Watchpost Agent remote administration implements the explicit forwarded-header resolver. Proxy trust is configured with explicit proxy IP/CIDR networks (WATCHPOST_AGENT_TRUSTED_PROXIES), and the direct peer must belong to a configured trusted-proxy network before forwarded host, protocol, or client-address headers are considered. Forwarded headers from any other peer are ignored or rejected according to the request.

Correct examples are on the dedicated proxy pages: Caddy HTTPS and nginx HTTPS, including the agent remote-administration configuration and the distinction between a same-machine and a remote-machine reverse proxy.

Audit guarantees and safe failure

Watchpost records security-sensitive state changes with two precise guarantees.

Persistent mutations - configuration, accounts, pairing, rotation, password changes, and audit-carrying changes - commit the state mutation and its attributed audit record atomically:

ValidateCheck the request and authority
Commit atomicallyState mutation + attributed audit record
ReportSuccess only after the save
If the audit record cannot be persisted, the protected state mutation is not committed.

Ephemeral in-memory sessions - login, logout, and administrative session revocation - cannot share a state save with their audit row, so the attributed audit event is durably persisted before the in-memory session mutation:

DecideChoose the session operation
Persist auditDurable attributed event first
Mutate sessionNon-failing in-memory change
ReportReturn the actual result
Sessions are in-memory; the durable audit must succeed before the session changes.

Safe failures:

If logout failure still clears the browser cookie, be precise about what that means: the client may lose its local cookie while the server-side session remains valid until it expires or is successfully revoked. That session is not destroyed. This ordering is safer than silently changing authority without a durable audit trail, but it is not a claim that every possible operational event is audit-covered.

Capabilities

Viewer, operator, and administrator roles are enforced by the server on every API path. Administrators manage accounts through the Users view: create users, change roles, reset passwords and revoke sessions. Any user can rotate their own password from the Account view, which revokes every other session for that account. The post owner field is metadata; evidence is not owner-isolated. Hiding a button is usability, not authorization. Permission-denied responses are rendered as deliberate UI states rather than unexplained empty panels.

Central checks and SNMP targets may deliberately monitor internal addresses, which is a core Watchpost feature. Operators can optionally restrict targets with CIDR allow/deny lists and denied ports; the policy is applied at schedule creation and again at run time against the resolved address, so a hostname that rebinds to a denied network is refused rather than probed. On-demand checks are rate-limited and audited.

Secrets

Collector, SNMP, notification, peer, and model credentials require narrow use, redaction, rotation, and exclusion from diagnostics and model context. Pairing and collector secrets are displayed once. Passwords are never returned by profile or status APIs.

Prompt injection

Monitored text is untrusted. A log line requesting shell access has no authority. Investigation tools accept server-defined typed inputs and return only citations that the server can verify.

Typed operations

Privileged operations require a registered type, validated parameters, actor capability, post scope, idempotency key, audit record, optional independent approval, atomic execution claim, and verification result. Arbitrary model-authored shell execution is outside the design. Every registered action executes a real operation and records its verification outcome - rerunning a check records the observed ok, failure and latency; silencing a route records disabled. No registered action is a no-op. Read capability never grants write authority, and no write operation travels through a generic untyped command path.

Industrial systems

Watchpost is not an industrial safety or control system. PLC writes and building-control commands remain future research requiring a separate threat model. They must not replace interlocks, certified safety systems, or deterministic control.

See Verification and hardening for what has been exercised, and Current limitations for what has not.

Reporting security issues

See the application repository's SECURITY.md. Do not include real credentials, sensitive telemetry, or exploitable production details in a public issue.