Skip to content
Merged
10 changes: 0 additions & 10 deletions .github/actions/publish/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ inputs:
dry_run:
description: 'Is this a dry run. If so no package will be published.'
required: true
outputs:
gem-hash:
description: "base64-encoded sha256 hashes of distribution files"
value: ${{ steps.gem-hash.outputs.gem-hash }}

runs:
using: composite
Expand All @@ -16,12 +12,6 @@ runs:
shell: bash
run: gem build launchdarkly-server-sdk-otel.gemspec

- name: Hash gem for provenance
id: gem-hash
shell: bash
run: |
echo "gem-hash=$(sha256sum launchdarkly-server-sdk-otel-*.gem | base64 -w0)" >> "$GITHUB_OUTPUT"

- name: Publish Library
shell: bash
if: ${{ inputs.dry_run == 'false' }}
Expand Down
18 changes: 6 additions & 12 deletions .github/workflows/manual-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ jobs:
permissions:
id-token: write
contents: read
outputs:
gem-hash: ${{ steps.publish.outputs.gem-hash}}
attestations: write # Needed for actions/attest
steps:
- uses: actions/checkout@v4

Expand All @@ -37,13 +36,8 @@ jobs:
with:
dry_run: ${{ inputs.dry_run }}

release-provenance:
needs: [ 'build-publish' ]
permissions:
actions: read
id-token: write
contents: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
with:
base64-subjects: "${{ needs.build-publish.outputs.gem-hash }}"
upload-assets: ${{ !inputs.dry_run }}
- name: Attest build provenance
if: ${{ format('{0}', inputs.dry_run) == 'false' }}
uses: actions/attest@v4
with:
subject-path: 'launchdarkly-server-sdk-otel-*.gem'
22 changes: 6 additions & 16 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ jobs:
id-token: write # Needed if using OIDC to get release secrets.
contents: write # Contents and pull-requests are for release-please to make releases.
pull-requests: write
outputs:
release-created: ${{ steps.release.outputs.release_created }}
upload-tag-name: ${{ steps.release.outputs.tag_name }}
gem-hash: ${{ steps.publish.outputs.gem-hash}}
attestations: write # Needed for actions/attest
steps:
- uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4
id: release
Expand Down Expand Up @@ -51,15 +48,8 @@ jobs:
with:
token: ${{secrets.GITHUB_TOKEN}}

release-provenance:
needs: [ 'release-package' ]
if: ${{ needs.release-package.outputs.release-created == 'true' }}
permissions:
actions: read
id-token: write
contents: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
with:
base64-subjects: "${{ needs.release-package.outputs.gem-hash }}"
upload-assets: true
upload-tag-name: ${{ needs.release-package.outputs.upload-tag-name }}
- name: Attest build provenance
if: ${{ steps.release.outputs.releases_created == 'true' }}
uses: actions/attest@v4
with:
subject-path: 'launchdarkly-server-sdk-otel-*.gem'
46 changes: 26 additions & 20 deletions PROVENANCE.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
## Verifying SDK build provenance with the SLSA framework
## Verifying SDK build provenance with GitHub artifact attestations

LaunchDarkly uses the [SLSA framework](https://slsa.dev/spec/v1.0/about) (Supply-chain Levels for Software Artifacts) to help developers make their supply chain more secure by ensuring the authenticity and build integrity of our published SDK packages.
LaunchDarkly uses [GitHub artifact attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds) to help developers make their supply chain more secure by ensuring the authenticity and build integrity of our published SDK packages.

As part of [SLSA requirements for level 3 compliance](https://slsa.dev/spec/v1.0/requirements), LaunchDarkly publishes provenance about our SDK package builds using [GitHub's generic SLSA3 provenance generator](https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/generic/README.md#generation-of-slsa3-provenance-for-arbitrary-projects) for distribution alongside our packages. These attestations are available for download from the GitHub release page for the release version under Assets > `multiple-provenance.intoto.jsonl`.
LaunchDarkly publishes provenance about our SDK package builds using [GitHub's `actions/attest` action](https://github.com/actions/attest). These attestations are stored in GitHub's attestation API and can be verified using the [GitHub CLI](https://cli.github.com/).

To verify SLSA provenance attestations, we recommend using [slsa-verifier](https://github.com/slsa-framework/slsa-verifier). Example usage for verifying SDK packages is included below:
To verify build provenance attestations, we recommend using the [GitHub CLI `attestation verify` command](https://cli.github.com/manual/gh_attestation_verify). Example usage for verifying SDK packages is included below:

<!-- x-release-please-start-version -->
```
# Set the version of the SDK to verify
# Set the version of the library to verify
VERSION=1.1.1
```
<!-- x-release-please-end -->
Expand All @@ -17,27 +17,33 @@ VERSION=1.1.1
# Download gem
$ gem fetch launchdarkly-server-sdk-otel -v $VERSION

# Download provenance from Github release
$ curl --location -O \
https://github.com/launchdarkly/ruby-server-sdk-otel/releases/download/${VERSION}/launchdarkly-server-sdk-otel-${VERSION}.gem.intoto.jsonl

# Run slsa-verifier to verify provenance against package artifacts
$ slsa-verifier verify-artifact \
--provenance-path launchdarkly-server-sdk-otel-${VERSION}.gem.intoto.jsonl \
--source-uri github.com/launchdarkly/ruby-server-sdk-otel \
launchdarkly-server-sdk-otel-${VERSION}.gem
# Verify provenance using the GitHub CLI
$ gh attestation verify launchdarkly-server-sdk-otel-${VERSION}.gem --owner launchdarkly
```

Below is a sample of expected output.

```
Verified signature against tlog entry index 83653185 at URL: https://rekor.sigstore.dev/api/v1/log/entries/24296fb24b8ad77a7df0bbf87a7d5fcaafa551a2101d9f993d251a56a918bb113e81d2c575dc7e25
Verified build using builder "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v1.10.0" at commit 14c48a68c45871c27409591969e7f4c0ebdcdf62
Verifying artifact launchdarkly-server-sdk-otel-1.0.0.gem: PASSED
Loaded digest sha256:... for file://launchdarkly-server-sdk-otel-1.1.1.gem
Loaded 1 attestation from GitHub API

The following policy criteria will be enforced:
- Predicate type must match:................ https://slsa.dev/provenance/v1
- Source Repository Owner URI must match:... https://github.com/launchdarkly
- Subject Alternative Name must match regex: (?i)^https://github.com/launchdarkly/
- OIDC Issuer must match:................... https://token.actions.githubusercontent.com

✓ Verification succeeded!

The following 1 attestation matched the policy criteria

PASSED: Verified SLSA provenance
- Attestation #1
- Build repo:..... launchdarkly/ruby-server-sdk-otel
- Build workflow:. .github/workflows/release-please.yml
- Signer repo:.... launchdarkly/ruby-server-sdk-otel
- Signer workflow: .github/workflows/release-please.yml
```

Alternatively, to verify the provenance manually, the SLSA framework specifies [recommendations for verifying build artifacts](https://slsa.dev/spec/v1.0/verifying-artifacts) in their documentation.
For more information, see [GitHub's documentation on verifying artifact attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds#verifying-artifact-attestations-with-the-github-cli).

**Note:** These instructions do not apply when building our libraries from source.
**Note:** These instructions do not apply when building our libraries from source.
5 changes: 4 additions & 1 deletion release-please-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
"versioning": "default",
"include-component-in-tag": false,
"include-v-in-tag": false,
"extra-files": ["PROVENANCE.md", "lib/ldclient-otel/version.rb"]
"extra-files": [
"PROVENANCE.md",
"lib/ldclient-otel/version.rb"
]
}
}
}
Loading