From f3663a36217074e2814c47ec5a0b24bdcc9ae2fe Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Wed, 15 Feb 2023 16:05:00 -0500 Subject: [PATCH 1/4] selftest: skip alls-green if 3p PR (#48) Signed-off-by: William Woodruff --- .github/workflows/selftest.yml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/selftest.yml b/.github/workflows/selftest.yml index ae621f0..5c829b0 100644 --- a/.github/workflows/selftest.yml +++ b/.github/workflows/selftest.yml @@ -203,20 +203,21 @@ jobs: if: always() needs: - - selftest - - selftest-xfail-invalid-inputs - - selftest-staging - - selftest-glob - - selftest-upload-artifacts - - selftest-custom-paths - - selftest-verify - - selftest-xfail-verify-missing-options - - selftest-identity-token + - selftest + - selftest-xfail-invalid-inputs + - selftest-staging + - selftest-glob + - selftest-upload-artifacts + - selftest-custom-paths + - selftest-verify + - selftest-xfail-verify-missing-options + - selftest-identity-token runs-on: ubuntu-latest steps: - name: check test jobs + if: (github.event_name != 'pull_request') || !github.event.pull_request.head.repo.fork uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2 with: jobs: ${{ toJSON(needs) }} From 7643db00791d4176aab2926d2c7795366c58e1b0 Mon Sep 17 00:00:00 2001 From: Andrew Pan <3821575+tnytown@users.noreply.github.com> Date: Wed, 15 Feb 2023 15:06:54 -0600 Subject: [PATCH 2/4] action: download default release assets to sign (#46) * action: download default release assets to sign Signed-off-by: Andrew Pan * README.md: doc `release-signing-artifacts` change Signed-off-by: Andrew Pan * action.py: use requests library for download Signed-off-by: Andrew Pan * Apply suggestions from code review Signed-off-by: William Woodruff --------- Signed-off-by: Andrew Pan Signed-off-by: William Woodruff Co-authored-by: William Woodruff Co-authored-by: William Woodruff --- README.md | 3 +++ action.py | 25 +++++++++++++++++++++++++ action.yml | 1 + requirements.txt | 1 + 4 files changed, 30 insertions(+) diff --git a/README.md b/README.md index b91ce9d..f8c99ab 100644 --- a/README.md +++ b/README.md @@ -367,6 +367,9 @@ Example: The `release-signing-artifacts` setting controls whether or not `sigstore-python` uploads signing artifacts to the release publishing event that triggered this run. +If enabled, this setting also re-uploads and signs GitHub's default source code artifacts, +as they are not guaranteed to be stable. + By default, no release assets are uploaded. Requires the [`contents: write` permission](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token). diff --git a/action.py b/action.py index ed6b864..a42b088 100755 --- a/action.py +++ b/action.py @@ -26,6 +26,8 @@ from glob import glob from pathlib import Path +import requests + _HERE = Path(__file__).parent.resolve() _TEMPLATES = _HERE / "templates" @@ -53,6 +55,22 @@ def _log(msg): print(msg, file=sys.stderr) +def _download_ref_asset(ext): + repo = os.getenv('GITHUB_REPOSITORY') + ref = os.getenv("GITHUB_REF") + + artifact = Path(f"/tmp/{os.getenv('GITHUB_REF_NAME')}").with_suffix(ext) + + # GitHub supports /:org/:repo/archive/:ref<.tar.gz|.zip>. + r = requests.get(f"https://github.com/{repo}/archive/{ref}{ext}", stream=True) + r.raise_for_status() + with artifact.open("wb") as io: + for chunk in r.iter_content(chunk_size=None): + io.write(chunk) + + return str(artifact) + + def _sigstore_sign(global_args, sign_args): return ["python", "-m", "sigstore", *global_args, "sign", *sign_args] @@ -163,6 +181,13 @@ def _fatal_help(msg): else: sigstore_verify_args.extend(["--cert-oidc-issuer", verify_oidc_issuer]) +if os.getenv("GHA_SIGSTORE_PYTHON_RELEASE_SIGNING_ARTIFACTS") == "true": + for filetype in [".zip", ".tar.gz"]: + artifact = _download_ref_asset(filetype) + if artifact is not None: + signing_artifact_paths.append(artifact) + inputs.append(artifact) + for input_ in inputs: # Forbid things that look like flags. This isn't a security boundary; just # a way to prevent (less motivated) users from breaking the action on themselves. diff --git a/action.yml b/action.yml index 71d43fc..fb0f522 100644 --- a/action.yml +++ b/action.yml @@ -123,6 +123,7 @@ runs: GHA_SIGSTORE_PYTHON_VERIFY: "${{ inputs.verify }}" GHA_SIGSTORE_PYTHON_VERIFY_CERT_IDENTITY: "${{ inputs.verify-cert-identity }}" GHA_SIGSTORE_PYTHON_VERIFY_OIDC_ISSUER: "${{ inputs.verify-oidc-issuer }}" + GHA_SIGSTORE_PYTHON_RELEASE_SIGNING_ARTIFACTS: "${{ inputs.release-signing-artifacts }}" GHA_SIGSTORE_PYTHON_INTERNAL_BE_CAREFUL_DEBUG: "${{ inputs.internal-be-careful-debug }}" shell: bash diff --git a/requirements.txt b/requirements.txt index 60843c3..e99b40c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ sigstore ~= 1.1 +requests ~= 2.28 From 607296ab13094e9be761bc42b658476eca4b1ec2 Mon Sep 17 00:00:00 2001 From: Andrew Pan <3821575+tnytown@users.noreply.github.com> Date: Wed, 15 Feb 2023 15:25:50 -0600 Subject: [PATCH 3/4] action: implement and document `bundle-only` (#49) * action: implement and document `bundle-only` Signed-off-by: Andrew Pan * workflows/release: enable `bundle-only` Signed-off-by: Andrew Pan --------- Signed-off-by: Andrew Pan --- .github/workflows/release.yml | 1 + README.md | 23 +++++++++++++++++++++++ action.py | 5 +++-- action.yml | 8 ++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3183fc3..d57ce9f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,3 +24,4 @@ jobs: with: inputs: action.yml action.py release-signing-artifacts: true + bundle-only: true diff --git a/README.md b/README.md index f8c99ab..d9a1519 100644 --- a/README.md +++ b/README.md @@ -388,6 +388,29 @@ permissions: release-signing-artifacts: true ``` +### `bundle-only` + +**Default**: `false` + +The `bundle-only` setting controls whether or not `sigstore-python` uploads `.crt` +or `.sig` artifacts. + +This setting affects the behavior of the `upload-signing-artifacts` and `release-signing-artifacts` +settings. If neither of those settings are specified, this setting has no effect. + +By default, `.crt` and `.sig` artifacts are uploaded. If enabled, only the `.sigstore` +signing artifact is uploaded. + +Example: + +```yaml +- uses: sigstore/gh-action-sigstore-python@v1.1.0 + with: + inputs: file.txt + upload-signing-artifacts: true + bundle-only: true +``` + ### Internal options
⚠️ Internal options ⚠️ diff --git a/action.py b/action.py index a42b088..488f591 100755 --- a/action.py +++ b/action.py @@ -188,6 +188,7 @@ def _fatal_help(msg): signing_artifact_paths.append(artifact) inputs.append(artifact) +bundle_only = os.getenv("GHA_SIGSTORE_PYTHON_BUNDLE_ONLY") == "true" for input_ in inputs: # Forbid things that look like flags. This isn't a security boundary; just # a way to prevent (less motivated) users from breaking the action on themselves. @@ -199,9 +200,9 @@ def _fatal_help(msg): for file_ in files: if not file_.is_file(): _fatal_help(f"input {file_} does not look like a file") - if "--certificate" not in sigstore_sign_args: + if not bundle_only and "--certificate" not in sigstore_sign_args: signing_artifact_paths.append(f"{file_}.crt") - if "--signature" not in sigstore_sign_args: + if not bundle_only and "--signature" not in sigstore_sign_args: signing_artifact_paths.append(f"{file_}.sig") if "--bundle" not in sigstore_sign_args: signing_artifact_paths.append(f"{file_}.sigstore") diff --git a/action.yml b/action.yml index fb0f522..cdf1eec 100644 --- a/action.yml +++ b/action.yml @@ -90,6 +90,13 @@ inputs: description: "attach all signing artifacts as release assets" required: false default: false + bundle-only: + description: | + upload only the Sigstore bundle + + has no effect if `upload-signing-artifacts` or `release-signing-artifacts` is not enabled + required: false + default: false internal-be-careful-debug: description: "run with debug logs (default false)" required: false @@ -124,6 +131,7 @@ runs: GHA_SIGSTORE_PYTHON_VERIFY_CERT_IDENTITY: "${{ inputs.verify-cert-identity }}" GHA_SIGSTORE_PYTHON_VERIFY_OIDC_ISSUER: "${{ inputs.verify-oidc-issuer }}" GHA_SIGSTORE_PYTHON_RELEASE_SIGNING_ARTIFACTS: "${{ inputs.release-signing-artifacts }}" + GHA_SIGSTORE_PYTHON_BUNDLE_ONLY: "${{ inputs.bundle-only }}" GHA_SIGSTORE_PYTHON_INTERNAL_BE_CAREFUL_DEBUG: "${{ inputs.internal-be-careful-debug }}" shell: bash From 310f3cb441addf9e269304174612d9651118d038 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Wed, 15 Feb 2023 16:37:26 -0500 Subject: [PATCH 4/4] Prep 1.2.0 (#52) * action: mark env var as internal explicitly Signed-off-by: William Woodruff * README: prep 1.2.0 Signed-off-by: William Woodruff --------- Signed-off-by: William Woodruff --- README.md | 48 ++++++++++++++++++++++++------------------------ action.py | 8 ++++---- action.yml | 4 ++-- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index d9a1519..5baa130 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ jobs: - uses: actions/checkout@v3 - name: install run: python -m pip install . - - uses: sigstore/gh-action-sigstore-python@v1.1.0 + - uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt ``` @@ -53,7 +53,7 @@ provided. To sign one or more files: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file0.txt file1.txt file2.txt ``` @@ -61,7 +61,7 @@ To sign one or more files: The `inputs` argument also supports file globbing: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: ./path/to/inputs/*.txt ``` @@ -74,7 +74,7 @@ The `identity-token` setting controls the OpenID Connect token provided to Fulci workflow will use the credentials found in the GitHub Actions environment. ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt identity-token: ${{ IDENTITY_TOKEN }} # assigned elsewhere @@ -90,7 +90,7 @@ Server during OAuth2. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt oidc-client-id: alternative-sigstore-id @@ -106,7 +106,7 @@ Connect Server during OAuth2. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt oidc-client-secret: alternative-sigstore-secret @@ -122,7 +122,7 @@ when signing multiple input files. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt signature: custom-signature-filename.sig @@ -131,7 +131,7 @@ Example: However, this example is invalid: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file0.txt file1.txt file2.txt signature: custom-signature-filename.sig @@ -147,7 +147,7 @@ work when signing multiple input files. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt certificate: custom-certificate-filename.crt @@ -156,7 +156,7 @@ Example: However, this example is invalid: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file0.txt file1.txt file2.txt certificate: custom-certificate-filename.crt @@ -172,7 +172,7 @@ when signing multiple input files. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt bundle: custom-bundle.sigstore @@ -181,7 +181,7 @@ Example: However, this example is invalid: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file0.txt file1.txt file2.txt certificate: custom-bundle.sigstore @@ -197,7 +197,7 @@ from. This setting cannot be used in combination with the `staging` setting. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt fulcio-url: https://fulcio.sigstage.dev @@ -213,7 +213,7 @@ cannot be used in combination with the `staging` setting. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt rekor-url: https://rekor.sigstage.dev @@ -229,7 +229,7 @@ in combination with the `staging` setting. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt ctfe: ./path/to/ctfe.pub @@ -245,7 +245,7 @@ be used in combination with `staging` setting. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt ctfe: ./path/to/rekor.pub @@ -261,7 +261,7 @@ instead of the default production instances. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt staging: true @@ -284,7 +284,7 @@ and `verify-oidc-issuer` settings. Failing to pass these will produce an error. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt verify: true @@ -307,7 +307,7 @@ This setting may only be used in conjunction with `verify-oidc-issuer`. Supplying it without `verify-oidc-issuer` will produce an error. ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt verify: true @@ -332,7 +332,7 @@ Supplying it without `verify-cert-identity` will produce an error. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt verify: true @@ -354,7 +354,7 @@ workflow artifact retention period is used. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt upload-signing-artifacts: true @@ -382,7 +382,7 @@ permissions: # ... -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt release-signing-artifacts: true @@ -404,7 +404,7 @@ signing artifact is uploaded. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v1.1.0 +- uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt upload-signing-artifacts: true @@ -432,7 +432,7 @@ Example: Example: ```yaml - - uses: sigstore/gh-action-sigstore-python@v1.1.0 + - uses: sigstore/gh-action-sigstore-python@v1.2.0 with: inputs: file.txt internal-be-careful-debug: true diff --git a/action.py b/action.py index 488f591..6a2d3bf 100755 --- a/action.py +++ b/action.py @@ -56,7 +56,7 @@ def _log(msg): def _download_ref_asset(ext): - repo = os.getenv('GITHUB_REPOSITORY') + repo = os.getenv("GITHUB_REPOSITORY") ref = os.getenv("GITHUB_REF") artifact = Path(f"/tmp/{os.getenv('GITHUB_REF_NAME')}").with_suffix(ext) @@ -264,8 +264,8 @@ def _fatal_help(msg): assert verify_status is None sys.exit(sign_status.returncode) -# Now populate the `GHA_SIGSTORE_PYTHON_SIGNING_ARTIFACTS` environment variable -# so that later steps know which files to upload as workflow artifacts. +# Now populate the `GHA_SIGSTORE_PYTHON_INTERNAL_SIGNING_ARTIFACTS` environment +# variable so that later steps know which files to upload as workflow artifacts. # # In GitHub Actions, environment variables can be made to persist across # workflow steps by appending to the file at `GITHUB_ENV`. @@ -276,7 +276,7 @@ def _fatal_help(msg): # {value} # {delimiter} gh_env.write( - "GHA_SIGSTORE_PYTHON_SIGNING_ARTIFACTS<