5.9 KiB
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
safeStoragewhere available; - session-only fallback when OS encryption is unavailable;
- token omitted from renderer-visible public state;
- encrypted token blob excluded from diagnostic bundles;
- a blank settings token field preserves the existing token only when the normalized Gitea origin is unchanged;
- 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
execFileargument 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.confwithout 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
flocklock; - fixed Compose and healthcheck configuration;
- atomic non-secret status JSON;
- previous-SHA recording and non-zero failure exits.
Optional and future release hardening
- optional code signing if ForgeFlow is ever distributed publicly;
- 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 host identity is previewed without credentials and authenticated sessions require the exact user-confirmed pinned 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, and changing that origin requires a newly entered token;
- non-loopback Gitea connections require HTTPS;
- packaged updates require a publisher-signed Ed25519 manifest that binds the source commit, artifact identity, byte length and SHA-256 digest;
- packaged update bytes are rehashed immediately before apply;
- integrated source replacement is disabled until source archives carry the same independent publisher signature.