tenseleyflow/shithub / d203df2

Browse files

docs/runbooks: S51 GPG-keys deploy procedure

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
d203df229d814fc363e563c748a1dd293b52e29d
Parents
6a48039
Tree
d90115d

1 changed file

StatusFile+-
A docs/internal/runbooks/gpg-keys-deploy.md 144 0
docs/internal/runbooks/gpg-keys-deploy.mdadded
@@ -0,0 +1,144 @@
1
+# Deploy: GPG keys + commit signature verification (S51)
2
+
3
+S51 ships the GPG-keys storage + the verification orchestrator
4
++ the Verified-badge rendering + a bulk-backfill admin command,
5
+all in one feature-branch merge to trunk. The migrations are
6
+additive and the rendering paths fall back to "unsigned"
7
+(no badge) on cache miss, so the rollout is safe to do
8
+in-band — no maintenance window required.
9
+
10
+## Pre-deploy
11
+
12
+1. Note the currently-deployed `ldd /opt/shithub/bin/shithubd`
13
+   output. shithub uses pure-Go OpenPGP via
14
+   `github.com/ProtonMail/go-crypto`; no new dynamic deps are
15
+   expected. Diffing post-deploy confirms.
16
+
17
+   ```sh
18
+   ssh root@shithub.sh "ldd /opt/shithub/bin/shithubd" > /tmp/ldd-pre.txt
19
+   ```
20
+
21
+2. Capture migration status as a baseline:
22
+
23
+   ```sh
24
+   ssh root@shithub.sh "sudo -u shithub /opt/shithub/bin/shithubd migrate status" \
25
+     > /tmp/migrate-pre.txt
26
+   ```
27
+
28
+## Deploy
29
+
30
+3. Apply migrations. Three new versions land:
31
+   - `0066_user_gpg_keys.sql` — primary keys table
32
+   - `0067_user_gpg_subkeys.sql` — subkey fingerprint reverse-lookup
33
+   - `0068_commit_verification_cache.sql` — verification result cache
34
+
35
+   ```sh
36
+   ssh root@shithub.sh "sudo -u shithub /opt/shithub/bin/shithubd migrate up"
37
+   ssh root@shithub.sh "sudo -u shithub /opt/shithub/bin/shithubd migrate status"
38
+   ```
39
+
40
+   `migrate status` should report all three at version applied.
41
+
42
+4. Quick sanity-check the three new tables exist and are empty:
43
+
44
+   ```sh
45
+   ssh root@shithub.sh "sudo -u shithub psql -d shithub -c '
46
+     SELECT count(*) FROM user_gpg_keys;
47
+     SELECT count(*) FROM user_gpg_subkeys;
48
+     SELECT count(*) FROM commit_verification_cache;'"
49
+   ```
50
+
51
+   Expect `0 / 0 / 0`.
52
+
53
+5. Rolling-restart shithubd. The deploy unit drops one replica
54
+   at a time; the health endpoint reports 200 once a replica
55
+   has finished its startup migration check.
56
+
57
+   ```sh
58
+   ssh root@shithub.sh "sudo systemctl restart shithubd@*"
59
+   ```
60
+
61
+6. Confirm the `gpg-keys` capability landed:
62
+
63
+   ```sh
64
+   curl -fsS https://shithub.sh/api/v1/meta | jq '.capabilities | index("gpg-keys")'
65
+   ```
66
+
67
+   Non-null output confirms.
68
+
69
+## Bulk backfill
70
+
71
+7. **Once-off after deploy.** Walk every repo's default branch
72
+   and stamp the verification cache for commits whose signing
73
+   subkey matches an already-uploaded GPG key. This is what
74
+   lights up existing signed commits for users whose keys we
75
+   already had (mostly admins / early testers; the long tail
76
+   gets covered on next key upload).
77
+
78
+   ```sh
79
+   ssh root@shithub.sh "sudo -u shithub /opt/shithub/bin/shithubd gpg-backfill-all"
80
+   ```
81
+
82
+   The command is idempotent and resumable — re-running picks
83
+   up where it left off (cache rows are upserted; existing rows
84
+   short-circuit the walk for that commit). Progress is logged
85
+   per repo. On a fresh deploy with no pre-existing GPG keys
86
+   the command is a no-op and exits in a few seconds.
87
+
88
+   To limit to a single repo (e.g. for spot-checking after the
89
+   bulk run):
90
+
91
+   ```sh
92
+   ssh root@shithub.sh "sudo -u shithub /opt/shithub/bin/shithubd \
93
+     gpg-backfill-all --repo=<owner>/<name>"
94
+   ```
95
+
96
+## Smoke-test
97
+
98
+8. Log in as a test account and exercise the user-visible flow:
99
+
100
+   - Navigate to `/settings/keys`. Confirm the page renders with
101
+     the combined SSH + GPG sections.
102
+   - Upload a test GPG key whose UID email matches a verified
103
+     email on the test account.
104
+   - Navigate to a repo that has signed commits authored by
105
+     that account on its default branch. The commit list should
106
+     show green **Verified** pills within a few seconds of the
107
+     upload (the backfill worker picks up the eager dispatch).
108
+   - Open `/{owner}/{repo}/commits/{sha}` for one of those
109
+     commits. The header should show the larger Verified badge
110
+     with a click-popover.
111
+
112
+9. Hit the REST surface with a `repo:read` PAT:
113
+
114
+   ```sh
115
+   curl -fsS -H "Authorization: Bearer $PAT" \
116
+     https://shithub.sh/api/v1/repos/<owner>/<name>/commits | \
117
+     jq '.[0].verification'
118
+   ```
119
+
120
+   Expect `{verified, reason, signature, payload, verified_at}`
121
+   on every entry.
122
+
123
+## Rollback
124
+
125
+The migrations are additive; rollback is `migrate down 3` to
126
+reverse them. Re-running with a server build that includes
127
+0066–0068 will re-apply on the next deploy with no data loss
128
+(the tables get rebuilt empty; the next eager dispatch repopulates).
129
+
130
+If a bad server build forces a rollback to a pre-S51 binary:
131
+
132
+```sh
133
+ssh root@shithub.sh "sudo -u shithub /opt/shithub/bin/shithubd migrate down 3"
134
+```
135
+
136
+This drops the three new tables. Any verification cache rows
137
+are lost; the bulk backfill on the subsequent re-deploy
138
+regenerates them.
139
+
140
+## See also
141
+
142
+- User docs: [GPG keys & commit signing](/docs/public/user/gpg-keys.md)
143
+- API reference: [GPG keys](/docs/public/api/gpg-keys.md),
144
+  [Signature verification on commits](/docs/public/api/commits.md#signature-verification)