# Security model ForgeFlow bridges developer credentials, local source trees and production release controls. The design favors constrained operations over arbitrary flexibility. ## Desktop boundary - `nodeIntegration: false`; - `contextIsolation: true`; - renderer sandbox enabled; - Content Security Policy limited to packaged resources; - narrow frozen preload API; - IPC rejected unless it originates from the packaged file renderer; - external navigation restricted to HTTP(S); - renderer errors reported through sanitized diagnostic IPC; - support-bundle reveal restricted to the last archive created by the main process. ## Credentials and persistence - Gitea token encrypted through Electron `safeStorage` where available; - session-only fallback when OS encryption is unavailable; - token omitted from renderer-visible public state; - encrypted token blob excluded from diagnostic bundles; - blank settings token field preserves the existing token; - atomic config replacement and restrictive permissions where supported; - service URLs reject embedded user credentials; - no token is required by setup/build scripts or documentation. ## Git operations - Git executed through `execFile` argument arrays, never shell interpolation; - local repository and Git root verified; - file actions accept only repository-relative paths; - absolute paths, traversal and NUL characters rejected; - clone remotes restricted to supported Git protocols; embedded passwords rejected; - renderer supplies repository identity rather than a free-form remote URL; - automatic clone targets are calculated in the main process below a selected project root; - matching existing origins may be linked, while different repositories and non-empty ordinary folders are blocked; - branch names validated by Git; - fast-forward-only pull; - branch switching/creation require a clean tree; - selected-commit flow refuses hidden staged files outside the selection; - monitor pauses around mutating actions. ## Deployment - fixed workflow filenames, branch and environment; - full 40–64 character SHA required; - local state re-read immediately before dispatch; - clean, published and synchronized branch required; - deployment SHA must equal local `HEAD`; - deploy and rollback SHA must belong to the allowed remote branch; - no free-form server commands over IPC or workflow inputs; - mandatory deployment preflight in the normal UI flow; - backend validation repeated after preflight; - exact target displayed in confirmation; - independent health and live-SHA checks; - rollback uses a separate fixed workflow and previous full SHA; - UUID request ID correlates desktop, workflow and server state. ## Diagnostics and redaction - structured events are sanitized before writing; - IPC payloads and HTTP authorization headers are not logged; - sensitive object keys, including camelCase, are removed; - known active tokens, authorization strings, query tokens, URL passwords, private-key blocks and common token formats are redacted; - home/source paths are aliased; - strings and collections are bounded; - logs rotate by day/size and expire by retention policy; - support bundles offer deterministic strict-privacy aliases; - raw runner logs, diffs and source file contents are omitted from bundles; - bundle creation performs a final fail-closed scan for known secrets, private-key markers and URL credentials; - bundle SHA-256 is displayed for exact identification. No generic detector can identify a completely unknown arbitrary secret printed without context by third-party code. ForgeFlow minimizes that residual risk by not exporting raw runner output and by requiring user inspection before sharing. ## Runner boundary Use a production-capable runner only for repositories you trust. Give it a label unique to the intended environment and the narrowest repository or organization scope. Avoid exposing a host Docker socket to untrusted jobs. Treat a runner capable of host deployment as privileged infrastructure. ## Server entry point The runner account should not receive unrestricted sudo or SSH access. The included model uses: - root-owned `/usr/local/bin/forgeflow-deploy`; - root-owned `/etc/forgeflow/targets.conf` without group/other write access; - a sudoers rule for that exact executable only; - exact repository/environment matching; - absolute-path and branch validation; - full-SHA remote ancestry proof; - per-target `flock` lock; - fixed Compose and healthcheck configuration; - atomic non-secret status JSON; - previous-SHA recording and non-zero failure exits. ## Remaining release hardening - code-sign packages and signed updates; - validate private CA/TLS behavior in the target network; - dependency, secret and binary scans in CI; - package-level IPC/navigation regression tests; - OS-specific credential storage and installer acceptance; - rate/approval policies for team use; - threat-model every future deployment adapter separately. ## SSH and updater additions - SSH passwords and private-key passphrases use Electron `safeStorage`; - diagnostics receive those runtime secrets only for redaction and never export encrypted credential fields; - SSH deployment requires a pinned host-key fingerprint; - remote folders and Compose paths are validated against traversal; - tracked server-side changes block exact-SHA reset; - updater tokens are sent only to the configured Gitea origin; - update archives are checksummed and validated by the full local quality gate; - source backup is restored when an update fails.