burrow/infra/identity
Conrad Kramer 51f34c9a64
Some checks failed
Build Rust / Cargo Test (push) Successful in 4m0s
Build Site / Next.js Build (push) Failing after 4s
Infra: OpenTofu / OpenTofu (grafana) (push) Successful in 6s
Lint Governance / BEP Metadata (push) Successful in 1s
Use client-only WIF runner grants
2026-06-07 13:34:53 -07:00
..
.gitignore Wire Forge-native release infrastructure 2026-06-07 05:51:12 -07:00
.terraform.lock.hcl Wire Forge-native release infrastructure 2026-06-07 05:51:12 -07:00
backend.hcl.example Wire Forge-native release infrastructure 2026-06-07 05:51:12 -07:00
google.tf Wire Forge-native release infrastructure 2026-06-07 05:51:12 -07:00
outputs.tf Wire Forge-native release infrastructure 2026-06-07 05:51:12 -07:00
providers.tf Wire Forge-native release infrastructure 2026-06-07 05:51:12 -07:00
README.md Use client-only WIF runner grants 2026-06-07 13:34:53 -07:00
terraform.tfvars.example Use client-only WIF runner grants 2026-06-07 13:34:53 -07:00
variables.tf Use client-only WIF runner grants 2026-06-07 13:34:53 -07:00
versions.tf Wire Forge-native release infrastructure 2026-06-07 05:51:12 -07:00

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-identity Google 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 client ID 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 use sparkle-ed25519, a non-exportable Google KMS key with algorithm EC_SIGN_ED25519 and software protection level. Google KMS rejects Ed25519 at HSM protection level, so this key is intentionally separate from the HSM RSA keys used for Apple certificate CSRs and repository signing.

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.