.gitbay/wiki/Architecture/09-Controls.org

32a5f76e5b270097b63a5bba9a43557cf50ad63d
gitbay/.gitbay/wiki/Architecture/09-Controls.org rendered · source · history · blame · raw

104 lines · 9918 bytes

Controls matrix

One row per control an auditor typically asks about. Status: in place (implemented and cited), partial (implemented with a stated limit), gap (not implemented; see 10). Categories follow the chapter names of OWASP ASVS 4.0 where one fits.

Architecture (V1)

Control Status Evidence
One authorization path for every surface partial all surfaces call control.Dispatch (internal/control/control.go); three web toggles write the store directly (#261)
No server-side signing key in place internal/sig verifies only
Least functionality by default in place API, web accounts, git://, push and registration default off (internal/config/config.go)
No git library; git runs as a subprocess with built argv in place internal/gitutil

Authentication (V2) and session management (V3)

Control Status Evidence
No passwords anywhere in place SSH keys, emailed single-use links, bearer tokens
Credentials stored as hashes in place SHA-256 of 256-bit random values (internal/store/sessions.go)
Brute-force limit on SSH auth in place 10 failures a minute per IP (internal/sshd/ratelimit.go)
Account enumeration resistance at login in place uniform response (internal/control/loginlink.go)
Session cookie flags in place HttpOnly, SameSite=Lax, Secure with TLS (internal/httpd/accounts.go)
Session lifetime partial 7 days absolute, no idle timeout (#276)
Credential expiry in place optional --ttl on API tokens, SSH and deploy keys; checked at auth and per exec
Revocation takes effect immediately in place removing a key or disabling an account closes its connections; every exec re-reads its key (internal/sshd/sshd.go)
Delegation bounded by the delegating credential partial expiring tokens refused on MintsCredential commands; credentials record their creating token (internal/control/control.go); a web session can still mint credentials that outlive it (#297)

Access control (V4)

Control Status Evidence
Deny by default on private data in place CanRead requires owner, public or grant (internal/policy/access.go)
Private resources indistinguishable from missing in place resolveRepo (internal/control/repo.go), runGit, smart HTTP
Credential scopes narrow account rights in place key and token scopes (control.go, policy/access.go)
Server-side write protections in place pre-receive CheckPush, signed commits (internal/hookd/hookd.go)
Merge gates partial MergeGates; any writer can post a ci/* status (#258)
Admin functions isolated in place admin noun gated in Dispatch; audit admin-only
CSRF protection in place SameSite=Lax plus checkOrigin (accounts.go)
Typed confirmation for destructive web actions in place internal/httpd/confirm.go

Input handling and output encoding (V5)

Control Status Evidence
User markup sanitised in place ugcHTML with bluemonday (internal/httpd/web.go)
No script execution in pages in place CSP script-src 'none' (internal/httpd/routes.go)
Control characters stripped at the terminal in place termSafe (internal/control/term.go)
No shell in command execution in place protocol.Tokenize for SSH argv; git and podman with argv slices
Parsers fuzzed partial five fuzz targets run briefly by deploy/audit.sh

Cryptography (V6) and data protection (V8)

Control Status Evidence
TLS for all authenticated HTTP in place ACME or certificate files; HSTS
Secrets encrypted at rest gap CI secrets, webhook secrets, mirror tokens stored in clear (#273)
Secrets kept out of argv, logs and output in place ReadsStdin, pruned audit argv, write-only secret commands
Local backups encrypted gap tar.gz in clear; offsite copy encrypted by restic (#274)
Data retention configurable in place [retention] (internal/config/config.go)
User data export in place account export

Logging (V7)

Control Status Evidence
Security-relevant writes audited in place every successful mutating command (control.go)
Authentication failures audited in place auth.failed, auth.throttled
Denied attempts audited gap refused commands are not recorded (#275)
Audit log tamper resistance gap same database, writable by the daemon user (#275)

Communications and integrations (V9, V10, V12)

Control Status Evidence
SSRF protection on user-supplied URLs partial webhooks at save and connect; mirrors at save only (#279)
Webhook payload integrity in place HMAC-SHA256 header
SMTP credentials protected in transit partial STARTTLS opportunistic (#280); Go refuses PLAIN auth without TLS to a remote host
Upload size limits in place per-owner storage quota at push (internal/sshd/sshd.go); API body 1 MiB

CI and build isolation

Control Status Evidence
Untrusted code runs isolated partial rootless podman, cgroup limits; shared build home per repository (#255)
No secrets for untrusted builds in place internal/control/build.go
Runner limited to attached repositories in place runnerMayBuild (build.go)
Build images fixed by the operator in place --pull=never
Build network egress restricted gap #260
Build results reused only across equal trust gap tree reuse ignores trust and image (#258)

Availability and operations

Control Status Evidence
Rate limits on API and writes in place 5. Rate limits
Concurrency limit on git pack generation gap #262
Service hardening in place systemd sandboxing (3)
Backups offsite and append-only in place restic with append-only credentials (documented)
Restore tested gap #259
Migrations validated before commit gap foreign-key check runs after commit (#261)
Signed, reviewed changes to production in place signed commits, require-mr, ff-only merges, clean-tree deploys