SignPath

Documentation  ❯  Trusted Build Systems   ❯   GitHub

Prerequisites

  • Use the predefined Trusted Build System GitHub.com (see configuration)
    • add it to the Organization
    • link it to each SignPath Project for GitHub
  • Specify <zip-file> as root element of your Artifact Configurations (GitHub packages all artifacts as ZIP archives)
  • Install the SignPath GitHub App and allow access to the code repositories.

GitHub Enterprise

SignPath hosts an instance of the GitHub connector which is linked to GitHub.com For integrating self-hosted GitHub Enterprise instances, contact our support team.

Checks performed by SignPath

The GitHub connector performs the following checks:

  • A build was actually performed by a GitHub workflow, not by some other entity in possession of the API token
  • Origin metadata is provided by GitHub, not the build script, and can therefore not be forged
  • The artifact is stored as a GitHub workflow artifact before it is submitted for signing
  • For OSS projects: All jobs of the GitHub worfklow leading up to the signing request were executed on GitHub-hosted agents

Usage

We provide a submit-signing-request action that can be integrated into a GitHub Actions workflow:

steps:
  # required for the artifact to be available on the GitHub server
- name: upload-unsigned-artifact
  id: upload-unsigned-artifact
  uses: actions/upload-artifact@v4
  with: 
    path: path/to/your/artifact

- id: optional_step_id
  uses: signpath/github-action-submit-signing-request@v1.1
  with:
    api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
    organization-id: '<SignPath organization id>'
    project-slug: '<SignPath project slug>'
    signing-policy-slug: '<SignPath signing policy slug>'
    github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
    wait-for-completion: true
    output-artifact-directory: '/path/to/signed/artifact/directory'

Action input parameters

Parameter Default Value Description
connector-url https://app.signpath.io/Api The URL of the SignPath connector. Required if self-hosted.
api-token (mandatory) The Api Token for a user with submitter permissions in the specified project/signing policy.
organization-id (mandatory) The SignPath organization ID.
project-slug (mandatory) The SignPath project slug.
signing-policy-slug (mandatory) The SignPath signing policy slug.
artifact-configuration-slug   The SignPath artifact configuration slug. If not specified, the default is used.
github-artifact-id (mandatory) ID of the Github Actions artifact. Must be uploaded using the actions/upload-artifact v4+ action before it can be signed. Use ${{ steps.<step-id>.outputs.artifact-id }} from the preceding actions/upload-artifact action step.
wait-for-completion (mandatory) If true, the action will wait for the signing request to complete. Defaults to true.
output-artifact-directory   Path to where the signed artifact will be extracted. If not specified, the task will not download the signed artifact from SignPath.
github-token   GitHub access token used to read job details and download the artifact. Defaults to the secrets.GITHUB_TOKEN. Requires the action:read and content:read permissions.
wait-for-completion-timeout-in-seconds 600 Maximum time in seconds that the action will wait for the signing request to complete.
service-unavailable-timeout-in-seconds 600 Total time in seconds that the action will wait for a single service call to succeed (across several retries).
download-signed-artifact-timeout-in-seconds 300 HTTP timeout when downloading the signed artifact. Defaults to 5 minutes.
parameters   Multiline-string of values that map to user-defined parameters in the Artifact Configuration. Use one line per parameter with the format <name>: "<value>" where <value> needs to be a valid JSON string.

Action output parameters

The action supports the following output parameters:

  • signing-request-id: The id of the newly created signing request
  • signing-request-web-url: The url of the signing request in SignPath
  • signpath-api-url: The base API url of the SignPath API
  • signed-artifact-download-url: The url of the signed artifact in SignPath

Define policies for source code and builds

Available for Advanced Code Signing, Code Signing Gateway.

You can define specific source code and build policies for your repository per signing policy:

  • runners: define which runners may be used by GitHub Actions
  • build: define conditions for GitHub Actions workflows and runs
  • branch_rulesets: define minimum requirements for branch rulesets including conditions for integrity, reviews, and code scanning

Steps to create a policy file:

  • create the policy file in the default branch of the source code repository
  • name it .signpath/policies/<project-slug>/<signing-policy-slug>.yml
  • restrict write permissions to the policy files using GitHub’s code owners feature

Policy sections

runners section

Use the runners section to define which runners may be used in the workflow run.

Policy Description

allowed_groups

Provide a list of GitHub runner group names. Ensures that all jobs of the workflow are executed on runners from one of the listed groups. Note that the GitHub Actions group is predefined and represents GitHub-hosted runners.

build section

Use the build section to configure rules for the build run.

Policy Description

disallow_reruns

Set to true to prevent signing builds from re-runs. By enforcing this policy, old, temporarily failed builds cannot be re-run and signed under the false impression that they include recent changes, such as vulnerability fixes. These builds would still be identified by their branch name, e.g. main.

branch_rulesets section

Use the branch_rulests section to configure conditions for GitHub branch rulesets.

  • You can configure branch rulesets in GitHub on an organization or repository level. SignPath verifies that there is at least one branch ruleset for each specified condition.
  • Rules define minimum requirements that may be exceeded by the actual branch ruleset.
How branch_rulesets conditions are evaluated

You can group your policy requirements into multiple conditions, each containing a combination of rules, bypassers, and enforcement date:

Section Values Description
rules See below Rules that must be implemented by one ore more active branch rulesets
allow_bypass_actors boolean If true, the branche ruleset is allowed to define bypassers
enforced_from None, timestamp, or EARLIEST By default, the rules are only evaluated at the time of signing. When provided, defines that these rules must have been in place from the specified date (YAML ISO timestamp) or earliest availability of audit log entries (EARLIEST).

About enforced_from evaluation

Depending on your GitHub subscription, the continuous enforcement of policies is either based on:

  • Audit log events for GitHub Enterprise subscriptions. Audit log events are only available for the last 180 days, any prior policy violations will not be detected.
  • The last modified date of the branch rulesets for all other subscriptions. At least one branch ruleset that has not been modified since the specified timestap must implement the rule.
Available branch_rulesets rules
Rule Description

restrict_creations

Set to true to allow only users with bypass permission to create matching refs.

restrict_updates

Set to true to allow only users with bypass permission to update matching refs.

restrict_deletions

Set to true to allow only users with bypass permissions to delete matching refs.

require_linear_history

Set to true to prevent merge commits from being pushed to matching refs.

require_pull_request

Require all commits be made to a non-target branch and submitted via a pull request before they can be merged. Can be set to true or defined as a block with the following parameters:

  • min_required_approvals: The minimum number of required approvals.
  • dismiss_stale_reviews_on_push: Set to true to dismiss stale pull request approvals when new commits are pushed.
  • require_code_owner_review: Set to true to require review from Code Owners.
  • require_last_push_approval: Set to true to require approval of the most recent reviewable push.
  • require_review_thread_resolution: Set to true to require conversation resolution before merging.

block_force_pushes

Set to true to prevent users with push access from force pushing to refs.

require_code_scanning

Configure a list of code scanning tools which must provide scan results with the following entries:

  • tool: The name of the code scanning tool, e.g. CodeQL
  • min_alerts_threshold: one of none, errors or warnings
  • min_security_alerts_threshold: one of none, critical, high, medium or all

Example

# .signpath/policies/my-project-slug/release-signing.yml

github-policies:
  runners:
    allowed_groups:
      - 'GitHub Actions'                         # all jobs need to run on GitHub-hosted runners
  build:
    disallow_reruns: true
  branch_rulesets:
    - condition:
        rules:
        - block_force_pushes:                    # force pushes are prevented
        - pull_request:                          # code reviews are required
            min_required_approvals: 1
            require_code_owner_review: true
      allow_bypass_actors: false                 # no-one is allowed to bypass this rule
      enforced_from: EARLIEST                    # rule enforcement history is checked
    - condition:
        rules:
        - require_code_scanning:                 # code scanning must not reveal problems
            tools:
              - tool: CodeQL
                min_alerts_threshold: errors
                min_security_alerts_threshold: medium
        allow_bypass_actors: true                # some people may bypass these rules
        enforced_from: '2025-01-01 00:00'        # had to be reset at some point

Sign up for news and special offers