Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 0 additions & 61 deletions .github/workflows/ci-repo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ name: CI Repo

on:
workflow_call:
secrets:
TAURI_SIGNING_PRIVATE_KEY:
required: false
TAURI_SIGNING_PRIVATE_KEY_PASSWORD:
required: false

permissions: {}

Expand Down Expand Up @@ -69,62 +64,6 @@ jobs:
- name: No source comment names a tracking issue
run: node scripts/check-tracker-refs.mjs

# The updater refuses any release that its configured key did not sign. A
# pubkey that drifts from the CI signing secret thus ships an app that can
# never update again. This check answers to no path filter, because a key
# rotation touches none, and the signing key stays out of every job that runs
# the desktop crate build scripts. Dependabot runs receive no repository
# secrets, so the job skips there.
updater-key:
name: Updater Key
if: github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
# No git operation follows the checkout, and this job holds the signing
# secret, so the job token stays out of the workspace .git/config.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: 'package.json'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Install minisign
run: |
sudo apt-get update
sudo apt-get install -y minisign

- name: Assert the updater pubkey matches the signing key
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: |
set -euo pipefail
if [ -z "${TAURI_SIGNING_PRIVATE_KEY}" ]; then
echo "::error::TAURI_SIGNING_PRIVATE_KEY is unavailable to this run, so the updater key is unverifiable"
exit 1
fi
WORK=$(mktemp -d)
# Tauri wraps both the public key and the signature file in base64;
# minisign wants the unwrapped bytes.
jq -er '.plugins.updater.pubkey' apps/desktop/src-tauri/tauri.conf.json \
| base64 -d > "${WORK}/updater.pub"
echo 'cipherbox updater key check' > "${WORK}/payload"
# `exec`, not the package's `tauri` script: that wrapper appends a
# `--config` the `signer` subcommand rejects.
pnpm --filter @cipherbox/desktop exec tauri signer sign "${WORK}/payload"
base64 -d < "${WORK}/payload.sig" > "${WORK}/payload.minisig"
minisign -V -p "${WORK}/updater.pub" -m "${WORK}/payload" -x "${WORK}/payload.minisig"

# The mock /routing/v1 record store holds the monotonic-sequence rule that a
# real routing endpoint holds, so a rollback cannot reach a client. The suite
# runs here, under no path filter, because the Repo area is the only gate that
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ jobs:
permissions:
contents: read
uses: ./.github/workflows/ci-repo.yml
secrets:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}

repo-result:
name: Repo Result
Expand Down
68 changes: 68 additions & 0 deletions .github/workflows/updater-key.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# The updater refuses any release that its configured key did not sign. A
# pubkey that drifts from the CI signing secret thus ships an app that can
# never update again. The check has to compare the two, and the comparison
# needs the private key, so it runs on the main gate: a push to main carries
# reviewed code, while a pull-request job would hand the release signing key
# to a tree the author still controls. The cost is that drift is reported
# after the merge. The check answers to no path filter, because a key rotation
# touches none.
name: Updater Key

on:
push:
branches: [main]
workflow_dispatch:

permissions: {}

jobs:
updater-key:
name: Updater Key
# The secret stays on reviewed code: a dispatch cannot aim this job at a branch.
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
# No git operation follows the checkout, and this job holds the signing
# secret, so the job token stays out of the workspace .git/config.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: 'package.json'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Install minisign
run: |
sudo apt-get update
sudo apt-get install -y minisign

- name: Assert the updater pubkey matches the signing key
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: |
set -euo pipefail
if [ -z "${TAURI_SIGNING_PRIVATE_KEY}" ]; then
echo "::error::TAURI_SIGNING_PRIVATE_KEY is unavailable to this run, so the updater key is unverifiable"
exit 1
fi
WORK=$(mktemp -d)
# Tauri wraps both the public key and the signature file in base64;
# minisign wants the unwrapped bytes.
jq -er '.plugins.updater.pubkey' apps/desktop/src-tauri/tauri.conf.json \
| base64 -d > "${WORK}/updater.pub"
echo 'cipherbox updater key check' > "${WORK}/payload"
# `exec`, not the package's `tauri` script: that wrapper appends a
# `--config` the `signer` subcommand rejects.
pnpm --filter @cipherbox/desktop exec tauri signer sign "${WORK}/payload"
base64 -d < "${WORK}/payload.sig" > "${WORK}/payload.minisig"
minisign -V -p "${WORK}/updater.pub" -m "${WORK}/payload" -x "${WORK}/payload.minisig"
Loading