Files
ForgeFlow/docs/SECURITY.md
T
2026-07-24 20:29:23 +02:00

133 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 4064 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.