From 9e48702b3a41fcd11ad03194af219449d08cc5bd Mon Sep 17 00:00:00 2001 From: tarunoai Date: Fri, 13 Nov 2026 18:16:09 +0000 Subject: [PATCH] Add opt-in signer-service support for macOS releases (#61371) ## What changed Wire signer-service settings from repository variables into the PKCS11 setup action for macOS binary, DMG, and provisioned bundle releases. Keep the feature disabled by default; Azure continues to supply tools, certificates, and notarization. Require signing mode, a pinned certificate, GitHub OIDC, and valid endpoint, purpose, and key ID inputs when enabled. Reject pre-supplied OIDC tokens and providers missing signer-service support markers, then export the signer-service backend configuration. GitOrigin-RevId: d6c9f2f65512892b286e4bbeb271633e23a96a24 --- .../setup-akv-pkcs11-codesigning/action.yaml | 75 +++++++++++++++++++ .../rust-release-provisioned-macos.yml | 4 + .github/workflows/rust-release.yml | 8 ++ 3 files changed, 87 insertions(+) diff --git a/.github/actions/setup-akv-pkcs11-codesigning/action.yaml b/.github/actions/setup-akv-pkcs11-codesigning/action.yaml index 4d79cab42e..4a3ade4e10 100644 --- a/.github/actions/setup-akv-pkcs11-codesigning/action.yaml +++ b/.github/actions/setup-akv-pkcs11-codesigning/action.yaml @@ -42,6 +42,23 @@ inputs: required: false default: "" + signer-service-enabled: + description: Opt in to signer-service for signing only; Azure still supplies tools, certificates, and notarization. + required: false + default: "false" + signer-service-endpoint: + description: Approved signer-service HTTPS origin and GitHub OIDC audience. + required: false + default: "" + signer-service-purpose: + description: Approved signer-service purpose for this release caller. + required: false + default: "" + signer-service-key-id: + description: Exact signer-service key ID matching the pinned signing certificate. + required: false + default: "" + outputs: pkcs11-library: description: Path to the downloaded AKV PKCS11 provider library. @@ -60,6 +77,7 @@ runs: shell: bash env: SETUP_MODE: ${{ inputs.setup-mode }} + SIGNER_SERVICE_ENABLED: ${{ inputs.signer-service-enabled }} RCODESIGN_BLOB_URI: ${{ inputs.rcodesign-blob-uri }} RCODESIGN_SHA256: ${{ inputs.rcodesign-sha256 }} AKV_PKCS11_LIBRARY_BLOB_URI: ${{ inputs.akv-pkcs11-library-blob-uri }} @@ -69,6 +87,18 @@ runs: run: | set -euo pipefail + case "$SIGNER_SERVICE_ENABLED" in + true|false) ;; + *) + echo "signer-service-enabled must be 'true' or 'false'." >&2 + exit 1 + ;; + esac + if [[ "$SIGNER_SERVICE_ENABLED" == true && "$SETUP_MODE" != signing ]]; then + echo "signer-service requires setup-mode=signing." >&2 + exit 1 + fi + case "$SETUP_MODE" in signing|tools-only) ;; @@ -347,3 +377,48 @@ runs: echo "AZURE_KEYVAULT_KEY_VERSION=$KEY_VERSION" fi } >> "$GITHUB_ENV" + + - name: Select signer-service for PKCS11 signing + if: ${{ inputs.signer-service-enabled == 'true' }} + shell: bash + env: + SIGNER_SERVICE_ENDPOINT: ${{ inputs.signer-service-endpoint }} + SIGNER_SERVICE_PURPOSE: ${{ inputs.signer-service-purpose }} + SIGNER_SERVICE_KEY_ID: ${{ inputs.signer-service-key-id }} + CERTIFICATE_SHA256: ${{ inputs.certificate-sha256 }} + run: | + set -euo pipefail + + : "${CERTIFICATE_SHA256:?A pinned signing certificate is required}" + : "${ACTIONS_ID_TOKEN_REQUEST_URL:?GitHub OIDC is required}" + : "${ACTIONS_ID_TOKEN_REQUEST_TOKEN:?GitHub OIDC is required}" + if [[ -v SIGNER_SERVICE_OIDC_TOKEN ]]; then + echo "The provider must obtain its own fresh GitHub OIDC token." >&2 + exit 1 + fi + if [[ ! "$SIGNER_SERVICE_ENDPOINT" =~ ^https://[A-Za-z0-9.-]+(:[0-9]+)?$ || + ! "$SIGNER_SERVICE_PURPOSE" =~ ^[A-Z][A-Z0-9_]+$ || + ! "$SIGNER_SERVICE_KEY_ID" =~ ^[A-Za-z0-9_-]{43}$ ]]; then + echo "An approved HTTPS origin, purpose, and exact key ID are required." >&2 + exit 1 + fi + + # An older Azure-only provider ignores signer-service configuration. + # Keep artifact SHA-256 verification above and reject that silent fallback. + for marker in AKV_PKCS11_BACKEND SIGNER_SERVICE_ENDPOINT SIGNER_SERVICE_KEY_ID SIGNER_SERVICE_OIDC_TOKEN; do + if ! grep -aFq "$marker" "$OAI_AKV_PKCS11_LIBRARY"; then + echo "The pinned PKCS11 provider does not support signer-service." >&2 + exit 1 + fi + done + + # The provider checks GetPublicKeys against the certificate and exact key + # ID, and verifies every returned signature. Authorization errors fail closed. + { + echo "AKV_PKCS11_BACKEND=signer-service" + echo "SIGNER_SERVICE_ENDPOINT=$SIGNER_SERVICE_ENDPOINT" + echo "SIGNER_SERVICE_PURPOSE=$SIGNER_SERVICE_PURPOSE" + echo "SIGNER_SERVICE_KEY_ID=$SIGNER_SERVICE_KEY_ID" + echo "SIGNER_SERVICE_KEY_LABEL=$OAI_AKV_KEY_LABEL" + echo "SIGNER_SERVICE_CERTIFICATE_FILE=$OAI_AKV_SIGNING_CERTIFICATE_PEM" + } >> "$GITHUB_ENV" diff --git a/.github/workflows/rust-release-provisioned-macos.yml b/.github/workflows/rust-release-provisioned-macos.yml index 2ce30c8fef..8f71009c1c 100644 --- a/.github/workflows/rust-release-provisioned-macos.yml +++ b/.github/workflows/rust-release-provisioned-macos.yml @@ -98,6 +98,10 @@ jobs: key-name: ${{ secrets.AKV_CODESIGN_KEY_NAME }} key-version: ${{ secrets.AKV_CODESIGN_KEY_VERSION || '' }} certificate-sha256: ${{ secrets.AKV_CODESIGN_CERTIFICATE_SHA256 }} + signer-service-enabled: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_ENABLED || 'false' }} + signer-service-endpoint: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_ENDPOINT }} + signer-service-purpose: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_PURPOSE }} + signer-service-key-id: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_KEY_ID }} - name: Sign and notarize the provisioned bundle env: APPLE_NOTARIZATION_AKV_KEY_NAME: ${{ secrets.AKV_NOTARIZATION_KEY_NAME }} diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index 47580c36b2..1702654ae9 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -711,6 +711,10 @@ jobs: key-name: ${{ secrets.AKV_CODESIGN_KEY_NAME }} key-version: ${{ secrets.AKV_CODESIGN_KEY_VERSION || '' }} certificate-sha256: ${{ secrets.AKV_CODESIGN_CERTIFICATE_SHA256 || '' }} + signer-service-enabled: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_ENABLED || 'false' }} + signer-service-endpoint: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_ENDPOINT }} + signer-service-purpose: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_PURPOSE }} + signer-service-key-id: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_KEY_ID }} - name: Sign and notarize macOS binaries shell: bash @@ -1223,6 +1227,10 @@ jobs: key-name: ${{ secrets.AKV_CODESIGN_KEY_NAME }} key-version: ${{ secrets.AKV_CODESIGN_KEY_VERSION || '' }} certificate-sha256: ${{ secrets.AKV_CODESIGN_CERTIFICATE_SHA256 || '' }} + signer-service-enabled: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_ENABLED || 'false' }} + signer-service-endpoint: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_ENDPOINT }} + signer-service-purpose: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_PURPOSE }} + signer-service-key-id: ${{ vars.CODEX_PUBLIC_MACOS_SIGNER_SERVICE_KEY_ID }} - name: Sign, notarize, and staple macOS DMG shell: bash