# Threat model ## Protected properties - A release is identified by an operator-approved SHA-256 digest. - Only regular, bounded, allowlisted archive entries are extracted. - Release roots, state, pointers, and Caddy files reject symlink substitution at their checked boundaries. - Configuration is strict JSON and is never interpolated into a shell command. - Candidate health is established before traffic or any current release pointer changes. New deployments also satisfy configured content smoke checks; rollback uses health and readiness because future-release content markers are not valid requirements for an older retained release. - Caddy configuration validates before reload. - Canonical routed origins and the previous blue/green slot or singleton handoff candidate remain under probe for the configured activation window; a failure restores the old handler and release pointer. - Desired, candidate, active, previous, and failed-attempt identities remain distinct in state. Bounded deployment events contain no arbitrary command output or environment values and cannot block deployment. - An activation failure restores the previously observed state. - Active and previous releases survive pruning. - The restricted receiver accepts one versioned bounded stream, one allowlisted service name, and one explicitly approved digest. It accepts no remote path, URL, environment value, or shell expression. - OpenSSH host keys are pinned; forwarding, PTYs, proxy commands, local commands, and user SSH configuration are disabled by the client invocation. - Production secret values are absent from configuration, process arguments, artifacts, manifests, reports, deployment state, and Tend logs. - One host-wide lock serializes shared Caddy activation without stopping or reconfiguring unrelated services. ## Trusted inputs Reviewed source, the pinned Go toolchain, root-owned server policy and service configuration, systemd unit files, the Caddy handler template, the operator, and the target host's root account are trusted. Packaging a hostile repository can execute hostile Go compiler hooks or consume resources; Tend is not a source-code sandbox. ## Adversarial inputs Artifact paths and bytes, protocol frames, requested service names, archive metadata, stale or malformed state, HTTP responses, subprocess failures, and filesystem objects at managed paths are validated and fail closed. Process output and receive fields are bounded. ## Non-goals and preview limits Tend does not defend against a concurrently malicious root user, a compromised kernel/toolchain/systemd/Caddy/OpenSSH installation, denial of service by the trusted application, or secrets an application itself exposes. It does not manage data migrations, databases, containers, Kubernetes, or application-specific activation. EQL therefore remains outside the generic deployment adapter until its SQLite/catalog publication checkpoints can be modeled explicitly.