Skip to content

docs: document the CI signing subkey - #39

Merged
rocketraman merged 3 commits into
masterfrom
claude/releasing-ci-signing-subkey
Oct 20, 2026
Merged

rocketraman merged 3 commits into
masterfrom
claude/releasing-ci-signing-subkey

Conversation

@rocketraman

Copy link
Copy Markdown
Owner

What

Documents the new CI signing subkey in two docs:

  • docs/releasing.adoc: the intro no longer claims the signing key never leaves local hardware. A new Signing keys section covers:
    • the fingerprints of the YubiKey primary (1F3C…2C9D) and the ed25519 CI subkey (2B2E…A3BB);
    • why the primary stays [SC];
    • how the subkey was exported (--export-secret-subkeys '<fpr>!') and removed from the local keyring;
    • the SIGNING_KEY / SIGNING_KEY_PASSPHRASE secrets in the release environment;
    • the expiry, rotation, revocation and key-publishing procedures.
  • docs/kotlin-toolchain-evaluation.adoc: a new ci-subkey section records that Kotlin Toolchain 0.13.0's built-in signer can't use the subkey export, so CI must also sign through the signForCentral plugin. The verdict, gaps, upstream notes and next steps are updated, and the two docs link to each other.

Why

Releases still sign locally with the card. The subkey exists so a future release workflow can sign in CI without the YubiKey. Its secret is only in the GitHub release environment, and it can be revoked without touching the primary.

Notes for review

  • Primary stays [SC]. Tested with gpg 2.4.9: after change-usage to certify-only, gpg and gpgv reject the primary's existing signatures ("No public key"), with or without a signing subkey. GnuPG has checked sign usage at verify time since 2.2.9 (#4014).
  • Built-in signer fails. With an [SC] primary, BouncyCastle's addSigningKey picks the stub primary in the export and throws an NPE. gpg signs correctly with the same export. Hence the doc warns against exposing the key as KOTLIN_TOOLCHAIN_SIGNING_KEY.
  • No workflow yet. No release workflow uses the secrets yet. The documented release steps are unchanged.
  • Checks. Docs only. Both files render with asciidoctor without warnings.

Releases still sign locally with the YubiKey primary, but a dedicated
ed25519 signing subkey now exists for CI, stored as SIGNING_KEY and
SIGNING_KEY_PASSPHRASE in the release environment.

- Record both fingerprints, why the primary stays [SC], and why CI
  must sign with gpg rather than KOTLIN_TOOLCHAIN_SIGNING_KEY.
- Add the expiry, rotation, revocation and key publishing procedures.
The built-in signer can't use the new CI signing subkey either: with
an [SC] primary, BouncyCastle's addSigningKey picks the stub primary in
the export and fails, while gpg signs fine with the same export.

- Add a ci-subkey section with the failure, why the primary stays [SC],
  and that CI must sign through the signForCentral plugin too.
- Replace the stale releasing.adoc quote and update the verdict, the
  upstream note and the next steps; cross-link both docs.
@claude

claude Bot commented Oct 20, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

KTC-6065 (allow configuring a signing subkey) was filed from our
report. Once fixed, CI can sign with the built-in signer, so the
staged-publication workaround can go if releases move to CI.

- Mention it in the ci-subkey section, the upstream issue table and
  the next steps; agent-based signing remains untracked.
@rocketraman
rocketraman merged commit 33b9914 into master Oct 20, 2026
2 checks passed
@rocketraman
rocketraman deleted the claude/releasing-ci-signing-subkey branch October 20, 2026 03:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant