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

3bcdce33fb9a2309312854331359d376171c7368
gitbay/.gitbay/wiki/Architecture/09-Controls.org rendered · source · history · blame · raw

104 lines · 10359 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 in place 12 hours idle, 7 days absolute (internal/store/sessions.go)
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 in place MergeGates; ci/* statuses written only by the build subsystem; required contexts
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 in place refused mutating commands and pushes, ten a minute per actor, 600 in all (internal/control/auditrefusal.go)
Audit log tamper resistance partial hash chain checked by gitbayd admin audit verify; every row the daemon writes copied to its journal; the table is writable by the daemon user, and removing the newest rows (or reusing their ids) shows only by comparing verify's last id and hash with the journal

Communications and integrations (V9, V10, V12)

Control Status Evidence
SSRF protection on user-supplied URLs partial webhooks at save and connect; mirrors at save and sync, git pinned to the checked address (internal/mirror/mirror.go); repo import --from has no address check (#298)
Webhook payload integrity in place HMAC-SHA256 header
SMTP credentials protected in transit in place STARTTLS required for non-local relays, implicit TLS optional (internal/mail/mail.go)
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 in place rootless podman, cgroup limits; untrusted builds get a disposable home (cmd/gitbay-runner/main.go)
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 partial host: loopback closed, public 22/80/443 only (gitbay-runner-egress.nft); internet outbound open by decision (#260)
Build results reused only across equal trust in place SuccessBuildForTree, SuccessBuildFor (internal/store/builds.go)

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