Install client tools for GPG keypair signing on GitHub
GPG signing with DigiCert® Software Trust Manager with GitHub Actions provides a secure, streamlined workflow that integrates with DevOps processes to sign binaries on Windows and Linux.
This action accelerates the installation and configuration of clients tools to help developers become signing-ready for GitHub action workflows.
GPG signing with Software Trust action can be used to set up client tool tasks.
Get the latest version of GPG signing with Software Trust from the GitHub Marketplace.
User authentication
Software Trust requires multi-factor authentication. Before you can access keypairs and certificates and sign code, you need to set up two credential types: an API key and an authentication certificate
Create an API key
The API key is an authentication method used to verify the user and their permissions as set in DigiCert ONE®. The client authentication provides the first factor authentication.
To create an API key:
In DigiCert ONE, select the profile (
) icon, and then select Admin Profile.
Under API keys, select Create API key.
For Name, enter a descriptive name for the key.
For End date (optional), enter the date when the key should expire.
Select Create. The API key appears this one time and can't be accessed again. Securely store the API key for future use.
Create an authentication certificate
The client authentication certificate is an authentication method used to verify the user and their permissions as set in DigiCert ONE. The client authentication certificate provides the second factor authentication.
To create a client authentication certificate:
In DigiCert ONE, select the profile (
) icon, and then select Admin Profile.
Under Client authentication certificates, select Create client authentication certificate.
For Nickname, enter a descriptive name for the key.
For End date, enter the date when the certificate should expire.
Select the desired Encryption and Signature hash algorithm.
Select Generate certificate. The password appears this one time and can't be accessed again. Download the certificate and securely store the password for future use.
Best practices for using secure GitHub
Use secrets and secure files to ensure security and accountability among your GitHub users when they use Software Trust to sign code. The code examples later assume that you're using secrets and secure files.
GitHub Secrets
Secrets are variables in GitHub encrypted so users can input information without knowing what the value of that information is. For example, with API keys, you may not want every GitHub collaborator to know your unique key, though they'll need it for signing through Software Trust. You can set up a variable where "(api_key)" is the name and the value is the API key itself.
Set your certificate file in the environment variables
To add a certificate to GitHub secrets, you need to encode the certificate to a base64 string.
For Linux, run the following command in a terminal:
base64 -i <file_name>
For Windows, run the following command in PowerShell:
$fileContentBytes = get-content 'YOURFILEPATH.pfx' -Encoding Byte [System.Convert]::ToBase64String($fileContentBytes)
Configure user credentials in GitHub Secrets
The client tools need these environment variables to connect with Software Trust.
To integrate environment variables as GitHub secrets:
Access GitHub repository.
Navigate to: Settings > Secrets > Actions.
Select New repository secret.
Enter the following environment variables:
Environment variables
Description
SM_CLIENT_CERT_PASSWORD
The password from client authentication certificate setup.
SM_CLIENT_CERT_FILE_B64
The base64 encoded text of certificate downloaded from client authentication certificate setup.
SM_HOST
The path to the Software Trust portal with client authorization.
Note
Usually this path stays as is unless you're connecting to a self-hosted instance of the Software Trust product.
SM_API_KEY
The API key generated during the API key setup.
SM_CODE_SIGNING_CERT_SHA1_HASH
The certificate fingerprint.
Note
The SM_HOST value used in the following commands depends on whether you're working in a demo or production environment.
Country | Host type | SM_HOST value |
---|---|---|
United States of America (USA) | Demo | https://clientauth.demo.one.digicert.com |
Production | https://clientauth.one.digicert.com | |
Switzerland (CH) | Demo | https://clientauth.demo.one.ch.digicert.com |
Production | https://clientauth.one.ch.digicert.com | |
Japan (JP) | Demo | https://clientauth.demo.one.digicert.co.jp |
Production | https://clientauth.one.digicert.co.jp | |
Netherlands (NL) | Demo | https://clientauth.demo.one.nl.digicert.com |
Production | https://clientauth.one.nl.digicert.com |
Commands to set environment variables
When you save the variable, it's fully encrypted. Even the creator (you) can't see the value. If you think you may need these variables in the future, securely and separately store them.
To set the API key as a new repository secret:
Name | SM_ SM_API_KEY |
Value | Insert the API key you created. |
To set the client authentication certificate as a new repository secret:
Name | SM_CLIENT_CERT_FILE_B64 |
Value | Insert the base64 encoded string you generated earlier. |
To set the client authentication certificate password as a new repository secret:
Name | SM_CLIENT_CERT_PASSWORD |
Value | Insert the password you were shown when creating the client certificate password. |
Set up environment variables
To set up the certificate file for signing:
- name: Setup Certificate run: | echo "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12 shell: bash
To set environment variables:
- name: Set variables id: variables run: | echo "::set-output name=version::${GITHUB_REF#refs/tags/v}" echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV" echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV" echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV" echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV" shell: bash
Usage example
Copy and paste the following snippet into your .yml file:
name: 'GPG Signing Template' on: workflow_dispatch: jobs: release: runs-on: ${{ matrix.os }} strategy: matrix: os: [windows-latest] steps: - name: Check out Git repository uses: actions/checkout@v4 - name: Set up certificate run: | echo "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12 shell: bash - name: Set variables id: variables run: | echo "::set-output name=version::${GITHUB_REF#refs/tags/v}" echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV" echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV" echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV" echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV" shell: bash
Note
When you save the variable, it's fully encrypted. Even the creator (you) can't see the value. If you think you may need these variables in the future, securely and separately store them.
Software Trust Manager client tools setup
The Software Trust client tools setup installs and configures all KeyLocker client tools, including the CTL client and the SCD client.
- name: GPG Signing with Secure Software Manager id: installer uses: digicert/ssm-gpg-signing@v0.0.2
To find the client tools installation path:
- run: echo “installation Path "${{ steps.installer.outputs.extractPath }}"”
Configure GPG signing
In C:\Users\RUNNER~1\.gnupg\gpg-agent.conf
, the gpg-agent.conf
file needs to be replaced with a custom gpg-agent.conf.
Review the following example of what gpg-agent.conf
should contain:
verbose debug-all scdaemon-program C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\DigiCert One Signing Manager Tools\\ssm-scd.exe
You can upload the configuration before this file to your repository, and then use the following command to replace the file:
- name: Configuration run: | del "C:\Users\RUNNER~1\.gnupg\gpg-agent.conf" copy path\togpg-agent.conf\inRepository "C:\Users\RUNNER~1\.gnupg\gpg-agent.conf"
To sign using a GPG keypair:
- name: Sign the artifact run: | gpgconf --kill all smctl gpg keyring download YOUR_GPG_KEYPAIR_ID --file-path C:\\Users\\RUNNER~1\\.gnupg\\pubring.gpg gpg --card-status gpg --list-keys gpg --list-secret-keys gpg --sign FileToSign
Sample GitHub Actions
name: 'GPG Signing Template' on: workflow_dispatch: jobs: release: runs-on: ${{ matrix.os }} strategy: matrix: os: [windows-latest] steps: - name: Check out Git repository uses: actions/checkout@v4 - name: Set up certificate run: | echo "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12 shell: bash - name: Set variables id: variables run: | echo "::set-output name=version::${GITHUB_REF#refs/tags/v}" echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV" echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV" echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV" echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV" shell: bash - name: GPG Signing with Secure Software Manager id: installer uses: digicert/ssm-gpg-signing@v0.0.2 - name: Configuration run: | del "C:\Users\RUNNER~1\.gnupg\gpg-agent.conf" copy path\togpg-agent.conf\inRepository "C:\Users\RUNNER~1\.gnupg\gpg-agent.conf" - name: Sign the artifact run: | gpgconf --kill all smctl gpg keyring download YOUR_GPG_KEYPAIR_ID --file-path C:\\Users\\RUNNER~1\\.gnupg\\pubring.gpg gpg --card-status gpg --list-keys gpg --list-secret-keys gpg --sign FileToSign