Skip to content

PK · Passphrase + Portal Key

A Portal holds the shared passphrase and hands it to the runner for one build.

One shared passphrase, held by the Portal rather than by GitHub. The runner fetches it for a single build and deletes it before compiling.

The same delivery mechanism as RK, with the simpler encryption mode.

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 accessOnly select repositories → this one
ContentsRead and write — so you can push
SecretsRead and write — so init can upload them

Metadata: read is added for you.

terminal
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

Passphrase mode does not invent your secret — you pick it:

terminal
export SGIT_KEY="$(openssl rand -base64 32)"
terminal
sgit pk

pk is the shorthand for this pair, and takes every flag init takes. Spelled out, it is:

the same thing, in full
sgit init --mode passphrase --ci-mode portal-key

On your disk:

$CODESEAL/<project>/
passphrase      # a copy of $SGIT_KEY, so it outlives the shell

Every 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:

terminal
sgit ci verify
mylife-inc/demo is ready to build.

The passphrase itself is never a GitHub secret.

4 · Protect something

terminal
sgit add-sensitive src/private
sgit encrypt

5 · The everyday loop

terminal
sgit add -s src/private/payment.rs
sgit commit -- -m "protect payments"
sgit push origin main

Push, and GitHub starts the workflow. The runner exchanges its bootstrap secret for a short-lived token, redeems that for the wrapped passphrase, and unwraps it locally.

What you end up with

On GitHubciphertext, and two secrets that are useless apart
In the Portalthe passphrase, stored encrypted
Adding a teammatetell them the passphrase
Removing onerotate everything, and re-provision the Portal
To start a buildnothing — GitHub does it

See also

  • RK — the same delivery, per-developer keys
  • PS — the same passphrase, given to GitHub instead