133 lines
5.5 KiB
Markdown
133 lines
5.5 KiB
Markdown
# 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.
|
||
|
||
## 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 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.
|