RK · Recipient + Portal Key
A Portal holds the keys and lends one to the runner for a single build. GitHub triggers on push.
Every developer has their own keypair. The CI runner has one too — but its private key lives in the Portal, not on GitHub. The runner fetches it for one build, unwraps it locally, and deletes it before compiling.
Builds still start on push, as in RS. The difference is that GitHub never holds a key that outlives a single build.
1 · Create the token
Do this first. sgit init uploads the secrets your workflow reads, and without
a token it sets up everything except the half that makes builds run.
GitHub → Settings → Developer settings → Fine-grained tokens → Generate new
| Repository access | Only select repositories → this one |
| Contents | Read and write — so you can push |
| Secrets | Read and write — so init can upload them |
Metadata: read is added for you.
export GITHUB_PAT=github_pat_…GH_TOKEN and GITHUB_TOKEN work too. If none is set and you are at a
terminal, init offers to take it and stores it per project.
2 · Seal the repository
sgit rkrk is the shorthand for this pair, and takes every flag init takes.
Spelled out, it is:
sgit init --mode recipient --ci-mode portal-keyOn your disk:
admin.key # adds and removes recipients
identity.age # yoursEvery key is outside the repository, at 0600. A key in the working tree is
one git add -A from being published.
3 · Check GitHub is ready
sgit init uploaded CODESEAL_BOOTSTRAP_SECRET and GITHUB_WRAPPER_PRIVATE_KEY as it went — that is what the token in step 1
was for. Confirm it landed:
sgit ci verifymylife-inc/demo is ready to build.
Neither decrypts anything alone: the first buys a sixty-second single-use token, the second unwraps what that token fetches.
4 · Protect something
sgit add-sensitive src/private
sgit encrypt5 · The everyday loop
sgit add -s src/private/payment.rs
sgit commit -- -m "protect payments"
sgit push origin mainPush, and GitHub starts the workflow. The runner trades the bootstrap secret
for a token, redeems it for a wrapped key, unwraps it with the wrapper key, and
deletes both before build.sh runs.
What you end up with
| On GitHub | ciphertext, and two secrets that are useless apart |
| In the Portal | the runner key, stored encrypted to a key it does not have |
| Adding a teammate | a rewrap |
| To start a build | nothing — GitHub does it |
