.gitbay/wiki/Architecture/06-Data-and-Cryptography.org
120 lines · 9243 bytes
6 symbols in this file
1#+title: Data and cryptography
2
3* Data inventory
4
5Schema: =internal/store/migrations/=, 66 migrations. Classification:
6*C* credential or secret, *P* personal data, *R* private repository
7content (as confidential as the repository), *O* operational.
8
9| Domain | Tables | Class | Notes |
10|-----------------+---------------------------------------------------------------------------------------------+-------+-------------------------------------------------|
11| Identity | =users=, =emails=, =ssh_keys=, =pgp_keys=, =orgs=, =org_members=, =teams=, =team_members= | P | email addresses in clear; keys are public |
12| Credentials | =api_tokens=, =web_sessions=, =login_tokens=, =email_tokens=, =invites= | C | SHA-256 hashes only |
13| Repositories | =repos=, =repo_access=, =team_repos=, =repo_topics=, =repo_watchers=, =repo_pins=, =repo_bookmarks=, =page_domains= | O | |
14| Collaboration | =issues=, =issue_*=, =merge_requests=, =mr_*=, =labels=, =milestones=, =mentions= | R | bodies of issues, comments and reviews |
15| Releases, snippets | =releases=, =release_assets=, =snippets=, =snippet_files= | R | |
16| CI | =builds= (includes logs), =build_schedules=, =runner_repos=, =runner_seen= | R | build logs can echo anything a step prints |
17| CI secrets | =build_secrets= | C | sealed (AES-256-GCM) |
18| Integrations | =webhooks= (secret), =webhook_deliveries=, =mirrors= (username, token) | C | webhook secret and mirror token sealed |
19| Notifications | =notifications= (mail queue), =inbox=, =push_devices= (APNs token), =push_queue=, =mail_replies= (Message-IDs of posted replies) | P | device tokens sealed; looked up by SHA-256 |
20| Signatures | =commit_signatures=, =settings.key_epoch= | O | verification cache |
21| Audit and feed | =audit_log=, =events= | O, P | actor ids, pruned argv, fingerprints and IPs in some audit rows, a hash chain (=prev_hash=, =hash=) |
22| Dependencies | =dep_checks=, =dep_reports= | O | |
23
24Outside the database:
25
26| Data | Location | Class |
27|----------------------------+-----------------------------------+-------|
28| Repository contents | =<root>/repos= | R |
29| LFS objects | =<root>/lfs= | R |
30| SSH host key | =<root>/ssh/host_ed25519= | C |
31| TLS keys (ACME) | =<root>/acme= | C |
32| SMTP password | =/etc/gitbay/config.toml= | C |
33| APNs signing key (.p8) | path in =push.key_file= | C |
34| IMAP password | path in =mail.inbound.password_file= | C |
35| Secret key file | =server.secret_key_file= (=/etc/gitbay/secret.key=) | C |
36| Backups | =/var/backups/gitbay=, offsite | all of the above |
37
38No table stores client IP addresses as a column. The daemon writes a
39client IP into an audit row only for authentication failures and
40throttling (=internal/sshd/sshd.go=).
41
42* At rest
43
44| Item | Protection |
45|---------------------------------------+----------------------------------------------------------------|
46| API tokens, sessions, login links, email codes, invites | SHA-256 of a 256-bit random value; the value is shown once and never stored (=internal/store/sessions.go=) |
47| CI secrets, webhook secrets, mirror tokens, APNs device tokens | AES-256-GCM under a key file outside the database and outside =server.root=; additional data binds table, column and row (=internal/seal=, =internal/store/secrets.go=) |
48| SQLite file | mode 0640, directory 0750 |
49| Backups | local archives age-encrypted when =[backup] age_recipients= is set; restic encrypts the offsite copy; neither carries the secret key file, which is copied off the host by hand until a separate keys repository is set up |
50| Disk | no application-level encryption; any disk encryption is the host's |
51
52The database file or a backup read by anyone other than the =gitbay=
53user discloses no CI secret, webhook secret, mirror token or device
54token without the key file, which neither carries. Rotation:
55=gitbayd admin secrets rotate= (Admin wiki).
56
57* In transit
58
59| Channel | Protection |
60|--------------------------+--------------------------------------------------------------|
61| SSH | Go =x/crypto/ssh=; ed25519 host key generated on first start |
62| HTTPS | TLS 1.2 minimum (=cmd/gitbayd/tls.go=), ACME or operator certificates; HSTS one year |
63| HTTP port 80 | ACME challenges and redirect only |
64| git:// | none (public data only; off by default) |
65| Runner ↔ server | SSH |
66| SMTP | STARTTLS required unless the relay is local (=mail.require_tls=), or implicit TLS (=mail.tls=) |
67| APNs | TLS, HTTP/2 |
68| IMAP | implicit TLS or STARTTLS, TLS 1.2 minimum, certificate verified (=internal/imapc=) |
69| Webhooks | TLS when the URL is https; HMAC-SHA256 body signature in =X-Gitbay-Signature-256= (=internal/webhook/webhook.go=) |
70| Mirrors | per URL; token passed through =GIT_ASKPASS=, never argv (=internal/mirror/mirror.go=) |
71
72TLS 1.2 is the minimum, set in code (=serverTLS= in
73=cmd/gitbayd/tls.go=); cipher suites are Go's defaults.
74
75* Cryptographic primitives
76
77| Use | Primitive | Code |
78|---------------------------------+--------------------------------------------+------------------------------------|
79| Token generation | =crypto/rand=, 32 bytes | =internal/store/sessions.go= |
80| Token storage | SHA-256 | =sessions.go= |
81| LFS transfer tokens | HMAC-SHA256, secret in =settings= | =internal/lfs/lfs.go= |
82| Webhook signatures | HMAC-SHA256 | =internal/webhook/webhook.go= |
83| APNs provider token | ES256 JWT (ECDSA P-256) | =internal/push/token.go= |
84| SSH host key | ed25519 | =internal/sshd/sshd.go= |
85| Commit and tag signatures | verify OpenPGP (ProtonMail go-crypto) and SSHSIG | =internal/sig= |
86| LFS object ids | SHA-256 | =internal/lfs/lfs.go= |
87
88Signature verification results are cached in =commit_signatures= with
89the global =key_epoch= at the time of verification. Any change to a
90trust input (a key added or removed, an email verified) bumps the
91epoch, which invalidates every cached result (=internal/store/users.go=,
92=internal/control/sig.go=).
93
94The server holds no signing key and signs nothing. A "verified" badge
95means a user's own key signed the commit.
96
97* Secret handling rules
98
99- Secrets enter only on stdin. A command must set =ReadsStdin=
100 to receive stdin at all; =TestStdinCommandsReadStdin= enforces it.
101 Examples: =repo secret set=, =repo deploy-key add=, =repo import
102 --token-stdin= (=internal/control/build.go=, =import.go=).
103- Secrets are listed by name, never echoed back.
104- The audit log stores argv with flag values stripped
105 (=internal/control/control.go=).
106- Mail errors are logged with addresses redacted
107 (=internal/notify/notify.go=).
108- CI secrets travel in the runner's claim only for trusted builds and
109 reach the container as environment variables through a 0600 env file
110 or podman's =--env NAME= pass-through, never argv
111 (=cmd/gitbay-runner/isolate.go=).
112
113* Retention
114
115Configured under =[retention]= for =audit=, =events=,
116=webhook_deliveries=, =mail= and =push=; unset means keep forever.
117Expired sessions and tokens are swept hourly regardless
118(=internal/config/config.go=, =cmd/gitbayd/main.go=).
119Accounts that never verify are removed after
120=registration.pending_expiry=. =account export= gives a user their data.