Skip to content

Commit 2f7142c

Browse files
Migrate Code Signing from DigiCert to Azure Trusted Signer (#5809)
Refactor Windows signing workflow; improve OIDC auth, input handling, and artifact validation - Switched Azure authentication to OIDC - Refactored workflows to sign Windows binaries using Azure Trusted Signing - Added snapshot and artifact upload options to support validation without publishing Signed-off-by: Gary Bright <gary@mondoo.com>
1 parent b1c254a commit 2f7142c

File tree

3 files changed

+86
-48
lines changed

3 files changed

+86
-48
lines changed

.github/.goreleaser-unstable.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ builds:
6464
- -s -w -X go.mondoo.com/cnquery/v9.Version={{.Version}} -X go.mondoo.com/cnquery/v9.Build={{.ShortCommit}} -X go.mondoo.com/cnquery/v9.Date={{.Date}}
6565
hooks:
6666
post:
67-
- cmd: jsign --storetype DIGICERTONE --alias "{{ .Env.SM_CERT_ALIAS }}" --storepass "{{ .Env.SM_API_KEY }}|{{ .Env.SM_CLIENT_CERT_FILE}}|{{ .Env.SM_CLIENT_CERT_PASSWORD }}" --tsaurl "http://timestamp.digicert.com" '{{ .Path }}'
67+
- cmd: jsign --storetype TRUSTEDSIGNING --keystore {{ .Env.TSIGN_AZURE_ENDPOINT }} --storepass {{ .Env.TSIGN_ACCESS_TOKEN }} --alias {{ .Env.TSIGN_ACCOUNT_NAME }}/{{ .Env.TSIGN_CERT_PROFILE_NAME }} '{{ .Path }}'
6868
nfpms:
6969
-
7070
maintainer: Mondoo <hello@mondoo.com>
@@ -89,7 +89,7 @@ checksum:
8989
name_template: '{{ .ProjectName }}_v{{ .Version }}_SHA256SUMS'
9090
algorithm: sha256
9191
snapshot:
92-
name_template: "{{ .Tag }}-snapshot"
92+
version_template: "{{ .Tag }}-snapshot"
9393
changelog:
9494
use: github-native
9595
dockers: # https://goreleaser.com/customization/docker/

.github/workflows/goreleaser.yml

Lines changed: 83 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,21 @@ on:
1111
type: boolean
1212
required: false
1313
default: false
14-
14+
use-test-cert:
15+
description: "Use test certificate profile (not publicly trusted)"
16+
required: false
17+
default: false
18+
type: boolean
19+
goreleaser-snapshot:
20+
description: 'Run goreleaser in snapshot mode, which will not publish and bypass tag checks.'
21+
required: false
22+
default: false
23+
type: boolean
24+
upload-artifacts:
25+
description: "Uploading artifacts to workflow"
26+
required: false
27+
default: false
28+
type: boolean
1529

1630
env:
1731
REGISTRY: docker.io
@@ -25,16 +39,20 @@ jobs:
2539
id-token: 'write'
2640

2741
runs-on: self-hosted
42+
environment: prod
2843
timeout-minutes: 120
2944
steps:
3045
- name: Checkout
3146
uses: actions/checkout@v4
3247
with:
3348
fetch-depth: 0
3449

50+
- name: Dump all inputs
51+
run: echo "${{ toJSON(inputs) }}"
52+
3553
- name: Skip Publish for Alpha and Beta Tags
3654
id: skip-publish
37-
if: contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') || inputs.skip-publish == 'true'
55+
if: contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') || inputs.skip-publish == true
3856
run: |
3957
echo "Skipping publish for alpha and beta tags"
4058
echo "skip-publish=true" >> $GITHUB_OUTPUT
@@ -61,13 +79,6 @@ jobs:
6179
workload_identity_provider: ${{ secrets.GCP_WIP }}
6280
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
6381

64-
- id: 'gcp_secrets'
65-
uses: 'google-github-actions/get-secretmanager-secrets@v2'
66-
with:
67-
secrets: |-
68-
code_sign_cert_b64:mondoo-base-infra/mondoo_code_sign_certificate_pfx_b64
69-
code_sign_cert_challenge:mondoo-base-infra/mondoo_code_sign_challenge
70-
7182
- name: "Write RPM Signing Cert"
7283
run: |
7384
gpgkey="$(mktemp -t gpgkey.XXX)"
@@ -76,33 +87,30 @@ jobs:
7687
env:
7788
GPG_KEY: '${{ secrets.GPG_KEY}}'
7889

79-
- name: "Write Windows Signing Cert"
80-
run: |
81-
cert="$(mktemp -t cert.XXX)"
82-
base64 -d <<<"$CERT_CONTENTS" > "$cert"
83-
echo "CERT_FILE=$cert" >> $GITHUB_ENV
84-
env:
85-
CERT_CONTENTS: '${{ steps.gcp_secrets.outputs.code_sign_cert_b64 }}'
90+
# jsign and azure-cli are both requirements for Azure Trusted Signing and these actions to authenticate
91+
# These packages have been installed on the self-hosted runner using ansible from the private repo
92+
93+
- name: Azure login
94+
uses: azure/login@v2
95+
with:
96+
client-id: ${{ secrets.TSIGN_AZURE_CLIENT_ID }}
97+
tenant-id: ${{ vars.TSIGN_AZURE_TENANT_ID}}
98+
subscription-id: ${{ vars.TSIGN_AZURE_SUBSCRIPTION_ID }}
8699

87-
- name: Configure DigiCert Signing Variables
88-
shell: bash
100+
- name: Get Azure AD Access Token to trusted signing
101+
id: get_token
89102
run: |
90-
# CertLocker Authentication Certifiate
91-
CERT_PATH="$(mktemp -t cert.XXX)"
92-
echo "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > ${CERT_PATH}
93-
echo "SM_CLIENT_CERT_FILE=${CERT_PATH}" >> "$GITHUB_ENV"
94-
echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV"
95-
# CertLocker API Key & Host
96-
echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV"
97-
echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV"
98-
# DigiCert CertLocker Code Signing Certificate
99-
echo "SM_CODE_SIGNING_CERT_SHA1_HASH=${{ secrets.SM_CODE_SIGNING_CERT_SHA1_HASH }}" >> "$GITHUB_ENV"
100-
echo "SM_CERT_ALIAS=${{ secrets.SM_CERT_ALIAS }}" >> "$GITHUB_ENV"
101-
102-
# - name: Install jSign (Windows Signing Tool) -- Required for public runners
103-
# run: |
104-
# curl -LO https://github.com/ebourg/jsign/releases/download/5.0/jsign_5.0_all.deb
105-
# sudo dpkg -i ./jsign_5.0_all.deb
103+
set -e # Stop on first error
104+
TSIGN_ACCESS_TOKEN=$(az account get-access-token --resource https://codesigning.azure.net --query accessToken -o tsv)
105+
106+
if [ -z "$TSIGN_ACCESS_TOKEN" ]; then
107+
echo "Error: Access token is empty"
108+
exit 1
109+
fi
110+
PREFIX="${TSIGN_ACCESS_TOKEN:0:8}"
111+
echo "Access token prefix: ${PREFIX}..."
112+
echo "TSIGN_ACCESS_TOKEN=$TSIGN_ACCESS_TOKEN" >> $GITHUB_OUTPUT
113+
106114
107115
- name: Install Quill for Mac Signing and Notarization
108116
run: |
@@ -116,13 +124,26 @@ jobs:
116124
username: ${{ secrets.DOCKER_USERNAME }}
117125
password: ${{ secrets.DOCKER_PASSWORD }}
118126

127+
# Run GoReleaser
128+
# This will build the binaries, create the docker images, and publish the release to Git
129+
# we are currently pinned to v2.5.1 because of a bug in v2.6.0 that causes the release to fail
130+
# specifically with the signing of the RPM packages
131+
# if you upgrade then when validating the signatures 'rpm -qpi dist/*.rpm' it will error with
132+
# Header RSA signature: BAD (package tag 268: invalid OpenPGP signature)
133+
# This is because a goreleaser dep was changed to https://github.com/goreleaser/nfpm/releases/tag/v2.41.2
134+
# created a discussion on the issue here https://github.com/orgs/goreleaser/discussions/5943
135+
119136
- name: Run GoReleaser (w/ Docker Release)
120-
if: ${{ ! steps.skip-publish.outputs.skip-publish }}
137+
if: ${{ inputs.skip-publish != true }}
121138
uses: goreleaser/goreleaser-action@v6
122139
with:
123140
distribution: goreleaser
124141
version: v2.5.1
125-
args: release --clean --timeout 120m
142+
args: >
143+
release
144+
--config .goreleaser.yml
145+
--clean
146+
--timeout 120m
126147
env:
127148
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
128149
CERT_PASSWORD: ${{ steps.gcp_secrets.outputs.code_sign_cert_challenge }}
@@ -132,14 +153,23 @@ jobs:
132153
QUILL_NOTARY_KEY: ${{ secrets.APPLE_NOTARY_KEY }}
133154
QUILL_NOTARY_KEY_ID: ${{ secrets.APPLE_NOTARY_KEY_ID }}
134155
QUILL_NOTARY_ISSUER: ${{ secrets.APPLE_NOTARY_ISSUER }}
156+
TSIGN_AZURE_ENDPOINT: ${{ vars.TSIGN_AZURE_ENDPOINT }}
157+
TSIGN_ACCOUNT_NAME: ${{ vars.TSIGN_ACCOUNT_NAME }}
158+
TSIGN_CERT_PROFILE_NAME: ${{ github.event.inputs.use-test-cert == 'true' && vars.TSIGN_TEST_CERT_PROFILE_NAME || vars.TSIGN_CERT_PROFILE_NAME }}
159+
TSIGN_ACCESS_TOKEN: ${{ steps.get_token.outputs.TSIGN_ACCESS_TOKEN }}
135160

136161
- name: Run GoReleaser (w/o Docker Release)
137-
if: ${{ steps.skip-publish.outputs.skip-publish == 'true' }}
162+
if: ${{ inputs.skip-publish == true }}
138163
uses: goreleaser/goreleaser-action@v6
139164
with:
140165
distribution: goreleaser
141-
version: latest
142-
args: release -f .github/.goreleaser-unstable.yml --clean --timeout 120m
166+
version: v2.5.1
167+
args: >
168+
release
169+
${{ inputs.goreleaser-snapshot == true && '--snapshot' || '' }}
170+
--config .github/.goreleaser-unstable.yml
171+
--clean
172+
--timeout 120m
143173
env:
144174
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
145175
CERT_PASSWORD: ${{ steps.gcp_secrets.outputs.code_sign_cert_challenge }}
@@ -149,10 +179,15 @@ jobs:
149179
QUILL_NOTARY_KEY: ${{ secrets.APPLE_NOTARY_KEY }}
150180
QUILL_NOTARY_KEY_ID: ${{ secrets.APPLE_NOTARY_KEY_ID }}
151181
QUILL_NOTARY_ISSUER: ${{ secrets.APPLE_NOTARY_ISSUER }}
182+
TSIGN_AZURE_ENDPOINT: ${{ vars.TSIGN_AZURE_ENDPOINT }}
183+
TSIGN_ACCOUNT_NAME: ${{ vars.TSIGN_ACCOUNT_NAME }}
184+
TSIGN_CERT_PROFILE_NAME: ${{ github.event.inputs.use-test-cert == 'true' && vars.TSIGN_TEST_CERT_PROFILE_NAME || vars.TSIGN_CERT_PROFILE_NAME }}
185+
TSIGN_ACCESS_TOKEN: ${{ steps.get_token.outputs.TSIGN_ACCESS_TOKEN }}
152186

153187
- name: Check RPMs
154188
run: |
155189
rpm -qpi dist/*.rpm
190+
156191
- name: Output Quill Logs
157192
if: ${{ failure() }}
158193
run: |
@@ -162,11 +197,19 @@ jobs:
162197
cat $f
163198
done
164199
200+
- name: Upload artifacts
201+
if: ${{ inputs.upload-artifacts == true }}
202+
uses: actions/upload-artifact@v4
203+
with:
204+
name: windows-artifacts
205+
path: dist/*.zip
206+
retention-days: 7
207+
165208
# At this point we know the docker container is published.
166209
# We can now trigger the cnquery bump in cnspec, which will also trigger the release of cnspec.
167210
# The docker container is a pre-requisite for cnspec release.
168211
- name: Trigger cnquery bump in cnspec
169-
if: ${{ ! steps.skip-publish.outputs.skip-publish }}
212+
if: ${{ inputs.skip-publish != true }}
170213
uses: peter-evans/repository-dispatch@v3
171214
with:
172215
token: ${{ secrets.RELEASR_ACTION_TOKEN }}
@@ -175,8 +218,3 @@ jobs:
175218
client-payload: '{
176219
"version": "${{ github.ref_name }}"
177220
}'
178-
179-
- name: Cleanup
180-
if: always()
181-
run:
182-
rm -f ${CERT_PATH}

.goreleaser.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ builds:
6464
- -s -w -X go.mondoo.com/cnquery/v11.Version={{.Version}} -X go.mondoo.com/cnquery/v11.Build={{.ShortCommit}} -X go.mondoo.com/cnquery/v11.Date={{.Date}}
6565
hooks:
6666
post:
67-
- cmd: jsign --storetype DIGICERTONE --alias "{{ .Env.SM_CERT_ALIAS }}" --storepass "{{ .Env.SM_API_KEY }}|{{ .Env.SM_CLIENT_CERT_FILE}}|{{ .Env.SM_CLIENT_CERT_PASSWORD }}" --tsaurl "http://timestamp.digicert.com" '{{ .Path }}'
67+
- cmd: jsign --storetype TRUSTEDSIGNING --keystore {{ .Env.TSIGN_AZURE_ENDPOINT }} --storepass {{ .Env.TSIGN_ACCESS_TOKEN }} --alias {{ .Env.TSIGN_ACCOUNT_NAME }}/{{ .Env.TSIGN_CERT_PROFILE_NAME }} '{{ .Path }}'
6868
nfpms:
6969
-
7070
maintainer: Mondoo <hello@mondoo.com>

0 commit comments

Comments
 (0)