5.6 KiB
Burrow Identity KMS and WIF
This OpenTofu stack owns Google Cloud KMS and Workload Identity Federation resources for Burrow identity and release automation.
It may manage:
- the
burrow-identityGoogle KMS key ring - non-exportable KMS signing keys for Authentik, the SAML CA, and release signing
- dedicated non-exportable KMS signing keys for APT, RPM, pacman, Flatpak, and AUR source release surfaces
- a non-exportable KMS signing key for the Apple Developer ID Application CSR
path (
apple-developer-id-application) - a non-exportable KMS signing key for the Apple iOS Distribution CSR path
(
apple-ios-distribution) - a non-exportable software KMS signing key for Sparkle Ed25519 appcast
signatures (
sparkle-ed25519) - an Authentik-backed WIF pool/provider for Forgejo runners
- the runner service account and its narrow IAM binding for the Authentik WIF
audience/client value
google-wif.burrow.net; human/group grants are opt-in
It must not manage:
- Authentik private signing key material
- OpenBao bootstrap tokens
- store credentials or service-account JSON keys
Forgejo CI should authenticate with Scripts/ci/google-wif-auth.sh. That helper
uses Authentik to obtain an OIDC token and lets Google WIF impersonate
burrow-forgejo-runner@project-88c23ce9-918a-470a-b33.iam.gserviceaccount.com
in project project-88c23ce9-918a-470a-b33.
Apple Developer ID CSR
Scripts/apple/google-kms-csr.py builds a standard PKCS#10 CSR using the public
key from projects/project-88c23ce9-918a-470a-b33/locations/global/keyRings/burrow-identity/cryptoKeys/apple-developer-id-application
and asks Google KMS to sign the CSR payload. The private key remains
non-exportable in KMS.
Forgejo can generate the Apple-uploadable CSR with:
Scripts/forgejo-dispatch.sh apple-developer-id-kms-csr.yml --ref main
Apple currently documents Developer ID certificate creation through the
Developer website or Xcode. After downloading the returned .cer, keep it with
release artifacts; do not convert this key path into an exportable .p12.
The active certificate created from this path is Apple certificate
9JKN6HXBHC, stored at
Apple/Certificates/developer-id-application-9JKN6HXBHC.cer. Its public key
matches KMS key version apple-developer-id-application/cryptoKeyVersions/1.
Apple iOS Distribution CSR
The iOS App Store distribution certificate uses the same CSR builder with the
apple-ios-distribution KMS key:
Scripts/apple/google-kms-csr.py \
--kms-key apple-ios-distribution \
--common-name "Burrow iOS Distribution" \
--output ios-distribution.certSigningRequest
The App Store Connect API can create the certificate from that CSR:
Scripts/apple/create-asc-certificate.mjs \
--certificate-type IOS_DISTRIBUTION \
--csr-file ios-distribution.certSigningRequest \
--out-dir Apple/Certificates
The active certificate created from this path is Apple certificate
3G42677598, stored at Apple/Certificates/ios-distribution-3G42677598.cer.
Its public key matches KMS key version
apple-ios-distribution/cryptoKeyVersions/1.
Sparkle Appcast Signing
Sparkle appcasts keep sparkle-ed25519, a Google KMS key with algorithm
EC_SIGN_ED25519 and software protection level, for small signing probes and
future signing-service work. Google KMS rejects Ed25519 at HSM protection level
and also rejects full-size macOS release archives as direct Ed25519 messages.
The tester pipeline therefore signs normal Sparkle archives with Sparkle's
sign_update and the decrypted SPARKLE_EDDSA_KEY_PATH release secret so the
appcast contains the standard full-archive EdDSA signature Sparkle verifies.
The public EdDSA key embedded in macOS release builds is:
Myv9ZNZT6YGKMtMezh52ra4WqaeEKc4VlvVU0evhJeI=
The appcast signer is:
Scripts/sparkle/sign-appcast-kms.py \
--appcast dist/builds/<build>/sparkle/<channel>/appcast.xml \
--artifact-dir dist/builds/<build>/sparkle/<channel>
Run
Scripts/identity-tofu.sh init -backend-config=backend.hcl
Scripts/identity-tofu.sh plan -var-file=terraform.tfvars
For local syntax work without remote state:
Scripts/identity-tofu.sh init -backend=false
Scripts/identity-tofu.sh validate
Start with manage_google = false. Import existing resources before enabling
management, then turn on one resource group at a time.
Bootstrap Imports
The first live Apple Developer ID pass may need these resources imported before
an identity apply can own them:
Scripts/identity-tofu.sh import 'google_kms_key_ring.identity[0]' \
projects/project-88c23ce9-918a-470a-b33/locations/global/keyRings/burrow-identity
Scripts/identity-tofu.sh import 'google_kms_crypto_key.signing["apple_developer_id_application"]' \
projects/project-88c23ce9-918a-470a-b33/locations/global/keyRings/burrow-identity/cryptoKeys/apple-developer-id-application
Scripts/identity-tofu.sh import 'google_kms_crypto_key.signing["apple_ios_distribution"]' \
projects/project-88c23ce9-918a-470a-b33/locations/global/keyRings/burrow-identity/cryptoKeys/apple-ios-distribution
Scripts/identity-tofu.sh import 'google_kms_crypto_key.signing["sparkle_ed25519"]' \
projects/project-88c23ce9-918a-470a-b33/locations/global/keyRings/burrow-identity/cryptoKeys/sparkle-ed25519
Scripts/identity-tofu.sh import 'google_service_account.runner[0]' \
projects/project-88c23ce9-918a-470a-b33/serviceAccounts/burrow-forgejo-runner@project-88c23ce9-918a-470a-b33.iam.gserviceaccount.com
Run imports with the same manage_google, key-ring, and service-account
variables that will be used for apply. Key-level IAM bindings should be imported
after the signing keys and service account exist.