-
Notifications
You must be signed in to change notification settings - Fork 0
feat: migration to OpenSSF #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
c289b9e
migration to OpenSSF
eddie-knight b193170
Address Kusari review: workflow env indirection, dependency bumps
eddie-knight 3acdf99
Point every reference at gemaraproj/grcli; drop revanite-io remnants
eddie-knight 4ec2c39
Restart versioning at v0.1.0; drop prior-lineage history
eddie-knight df692dc
remove old ADR comments
eddie-knight f71cede
Address Kusari review: pin actions to commit SHAs, disable credential…
eddie-knight cf73b65
internal: scrub userinfo from provenance remote URL, reuse digest.Byt…
eddie-knight c816821
chore: repo hygiene from panel review
eddie-knight d1cc1a0
ci: disable setup-go cache in the privileged release job
eddie-knight File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| name: Install grcli | ||
| description: >- | ||
| Install the grcli binary from the public GHCR OCI artifact onto the | ||
| runner PATH. No token required (the package is public). | ||
|
|
||
| inputs: | ||
| version: | ||
| description: >- | ||
| Version tag to install from ghcr.io/gemaraproj/grcli, e.g. v0.1.0, | ||
| or "latest". | ||
| required: false | ||
| default: latest | ||
| verify: | ||
| description: >- | ||
| Verify the cosign signature before installing. Requires cosign on | ||
| PATH (e.g. a prior sigstore/cosign-installer step). Default false. | ||
| required: false | ||
| default: "false" | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| # v2: https://github.com/oras-project/setup-oras/releases/tag/v2.0.0 | ||
| - uses: oras-project/setup-oras@38de303aac69abb66f3e6255b7198bff35f323e3 | ||
| with: | ||
| version: 1.3.0 | ||
|
|
||
| - shell: bash | ||
| env: | ||
| GRCLI_VERSION: ${{ inputs.version }} | ||
| GRCLI_VERIFY: ${{ inputs.verify }} | ||
| run: | | ||
| set -euo pipefail | ||
| image="ghcr.io/gemaraproj/grcli" | ||
|
|
||
| case "${RUNNER_OS}" in | ||
| Linux) os=linux ;; | ||
| macOS) os=darwin ;; | ||
| Windows) os=windows ;; | ||
| *) echo "grcli install: unsupported RUNNER_OS=${RUNNER_OS}" >&2; exit 1 ;; | ||
| esac | ||
| case "${RUNNER_ARCH}" in | ||
| X64) arch=amd64 ;; | ||
| ARM64) arch=arm64 ;; | ||
| *) echo "grcli install: unsupported RUNNER_ARCH=${RUNNER_ARCH}" >&2; exit 1 ;; | ||
| esac | ||
| bin=grcli; [ "$os" = "windows" ] && bin=grcli.exe | ||
|
|
||
| # Resolve the tag once and use the digest for both verify and pull, so a | ||
| # retag between the two steps cannot install a binary that was never | ||
| # verified. | ||
| ref="${image}@$(oras resolve "${image}:${GRCLI_VERSION}")" | ||
|
|
||
| if [ "${GRCLI_VERIFY}" = "true" ]; then | ||
| if ! command -v cosign >/dev/null 2>&1; then | ||
| echo "grcli install: verify=true but cosign not on PATH; add a sigstore/cosign-installer step first" >&2 | ||
| exit 1 | ||
| fi | ||
| cosign verify "$ref" \ | ||
| --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ | ||
| --certificate-identity-regexp "^https://github.com/gemaraproj/grcli/.github/workflows/release.yml@" \ | ||
| >/dev/null | ||
| fi | ||
|
|
||
| dest="${RUNNER_TEMP}/grcli-bin" | ||
| mkdir -p "$dest" | ||
| oras pull "$ref" --platform "${os}/${arch}" -o "$dest" | ||
| chmod +x "${dest}/${bin}" 2>/dev/null || true | ||
|
|
||
| echo "$dest" >> "$GITHUB_PATH" | ||
| "${dest}/${bin}" --version | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| name: ci | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | ||
| with: | ||
| persist-credentials: false | ||
| - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 | ||
| with: | ||
| go-version-file: go.mod | ||
| cache: true | ||
| - run: make fmtcheck | ||
| - run: make vet | ||
| - run: make tidycheck | ||
| - run: make testcov | ||
| - uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0 | ||
| with: | ||
| version: v2.12.2 | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | ||
| with: | ||
| persist-credentials: false | ||
| - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 | ||
| with: | ||
| go-version-file: go.mod | ||
| cache: true | ||
| - run: make build |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| # Reusable workflow: publish Gemara artifact(s) to grc.store with grcli. | ||
| # | ||
| # The artifact TYPE (catalog, threat model, evaluation log, …) is NOT a | ||
| # parameter — grcli reads it from each file's Gemara `metadata`, so this one | ||
| # workflow publishes any Gemara type. You supply the file(s), the license, and | ||
| # optionally the hub URL. | ||
| # | ||
| # === AUTH: NO SECRET REQUIRED (trusted publishing) === | ||
| # grcli uses the workflow's GitHub Actions OIDC token as its hub credential and | ||
| # for cosign keyless signing. `id-token: write` is the entire auth setup — do | ||
| # NOT add GRCLI_TOKEN, a PAT, or any `secrets.*` reference. | ||
| # | ||
| # Prerequisite (one-time, by a hub/org admin — NOT in the caller's repo): | ||
| # register the calling repository (owner/repo, optionally ref-pinned) as a | ||
| # Trusted CI publisher for the target namespace. Without that binding the hub | ||
| # returns 403; adding a GitHub secret will not fix it. | ||
| # | ||
| # --- Call it from a catalog repo --- | ||
| # name: Publish catalog | ||
| # on: | ||
| # push: | ||
| # branches: [main] | ||
| # paths: ['controls.yaml'] | ||
| # workflow_dispatch: {} | ||
| # jobs: | ||
| # publish: | ||
| # permissions: | ||
| # contents: read | ||
| # id-token: write # caller MUST grant this — it's what auth uses | ||
| # uses: gemaraproj/grcli/.github/workflows/publish-gemara.yml@v0.1.0 | ||
| # with: | ||
| # files: controls.yaml | ||
| # license: Apache-2.0 | ||
|
|
||
| name: Publish Gemara artifact | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| files: | ||
| description: 'Artifact file(s), whitespace/newline-separated. Each entry is published as one artifact; grcli reads its type + version from the YAML.' | ||
| required: true | ||
| type: string | ||
| license: | ||
| description: 'REQUIRED publication license as an SPDX expression (e.g. Apache-2.0, MIT OR Apache-2.0, or a LicenseRef-… token). Applied to every file.' | ||
| required: true | ||
| type: string | ||
| hub-url: | ||
| description: 'grc.store hub base URL — discovers the registry and is the sync target.' | ||
| required: false | ||
| type: string | ||
| default: https://hub.grc.store | ||
| grcli-version: | ||
| description: 'grcli release tag to install from ghcr.io/gemaraproj/grcli.' | ||
| required: false | ||
| type: string | ||
| default: v0.1.0 | ||
|
|
||
| jobs: | ||
| publish: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| id-token: write # hub auth + cosign keyless signing (no secret) | ||
| steps: | ||
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| # grcli ships as a public, signed, multi-platform OCI artifact; pulling | ||
| # needs no token. v2: https://github.com/oras-project/setup-oras/releases/tag/v2.0.0 | ||
| - uses: oras-project/setup-oras@38de303aac69abb66f3e6255b7198bff35f323e3 | ||
| - name: Install grcli ${{ inputs.grcli-version }} | ||
| env: | ||
| GRCLI_VERSION: ${{ inputs.grcli-version }} | ||
| run: | | ||
|
eddie-knight marked this conversation as resolved.
|
||
| oras pull "ghcr.io/gemaraproj/grcli:$GRCLI_VERSION" --platform linux/amd64 | ||
| sudo install grcli /usr/local/bin/grcli | ||
|
|
||
| - name: Publish | ||
| env: | ||
| FILES: ${{ inputs.files }} | ||
| LICENSE: ${{ inputs.license }} | ||
| HUB_URL: ${{ inputs.hub-url }} | ||
| run: | | ||
| set -euo pipefail | ||
| # Word-split FILES on whitespace/newlines: one grcli publish per artifact. | ||
| for f in $FILES; do | ||
| echo "::group::grcli publish $f" | ||
| grcli publish -f "$f" --license "$LICENSE" --url "$HUB_URL" | ||
| echo "::endgroup::" | ||
| done | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| name: release | ||
|
|
||
| # Publish grcli as a public, multi-platform OCI artifact on GHCR, signed | ||
| # keyless with cosign. Triggered by pushing a semver tag (e.g. v0.1.0). | ||
| # | ||
| # The published *package* is public, so anyone can `oras pull` the binary | ||
| # with no token. See README "Install or Upgrade". | ||
| # | ||
| # Native macOS binaries ride along because these are raw OCI artifacts, | ||
| # not container images (images can't carry darwin binaries). | ||
|
|
||
| on: | ||
| push: | ||
| tags: ['v*'] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| packages: write # push the OCI artifact to GHCR | ||
| id-token: write # cosign keyless signing (Sigstore via GitHub OIDC) | ||
|
|
||
| env: | ||
| REGISTRY: ghcr.io | ||
| IMAGE: ghcr.io/${{ github.repository }} # ghcr.io/gemaraproj/grcli | ||
|
|
||
| jobs: | ||
| release: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 | ||
| with: | ||
| go-version-file: go.mod | ||
| cache: false # release job holds packages:write + id-token:write; no cache poisoning surface (Kusari) | ||
|
|
||
| # oras >= 1.3 is required for --artifact-platform and | ||
| # `oras manifest index create`. | ||
| # v2: https://github.com/oras-project/setup-oras/releases/tag/v2.0.0 | ||
| - uses: oras-project/setup-oras@38de303aac69abb66f3e6255b7198bff35f323e3 | ||
| with: | ||
| version: 1.3.0 | ||
|
|
||
| - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 | ||
|
|
||
| - name: Log in to GHCR | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| ACTOR: ${{ github.actor }} | ||
| run: echo "$GH_TOKEN" | oras login "$REGISTRY" -u "$ACTOR" --password-stdin | ||
|
|
||
| - name: Build binaries, push per-platform artifacts, assemble index | ||
| id: build | ||
| env: | ||
| VERSION: ${{ github.ref_name }} | ||
| CGO_ENABLED: "0" | ||
| run: | | ||
| set -euo pipefail | ||
| ldflags="-s -w -X github.com/gemaraproj/grcli/cmd.version=${VERSION}" | ||
| artifact_type="application/vnd.gemaraproj.grcli.binary" | ||
| platforms="linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64" | ||
|
|
||
| children=() | ||
| for p in $platforms; do | ||
| os="${p%/*}"; arch="${p#*/}" | ||
| bin="grcli"; [ "$os" = "windows" ] && bin="grcli.exe" | ||
| echo "::group::build & push $p" | ||
| GOOS="$os" GOARCH="$arch" go build -trimpath -ldflags "$ldflags" -o "$bin" . | ||
| tag="${VERSION}-${os}-${arch}" | ||
| # Push the raw binary as a platform-tagged OCI artifact. The file | ||
| # is stored under its own name, so `oras pull` restores `grcli`. | ||
| oras push --artifact-type "$artifact_type" \ | ||
| --artifact-platform "$os/$arch" \ | ||
| "${IMAGE}:${tag}" \ | ||
| "${bin}:application/octet-stream" | ||
| rm -f "$bin" | ||
| children+=( "${IMAGE}:${tag}" ) | ||
| echo "::endgroup::" | ||
| done | ||
|
|
||
| # Combine the per-platform artifacts into one multi-arch index. | ||
| # Platform metadata is carried from each child (set above), so a | ||
| # later `oras pull --platform os/arch` selects the right binary. | ||
| oras manifest index create "${IMAGE}:${VERSION}" "${children[@]}" | ||
| oras tag "${IMAGE}:${VERSION}" latest | ||
|
|
||
| digest="$(oras resolve "${IMAGE}:${VERSION}")" | ||
| echo "digest=${digest}" >> "$GITHUB_OUTPUT" | ||
| echo "Published ${IMAGE}:${VERSION} (${digest})" | ||
|
|
||
| # Sign by digest. The signature covers the index, hence every tag | ||
| # (version and latest) that points at it. | ||
| - name: Sign the index (keyless) | ||
| run: cosign sign --yes "${IMAGE}@${{ steps.build.outputs.digest }}" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,32 +1,11 @@ | ||
| # If you prefer the allow list template instead of the deny list, see community template: | ||
| # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore | ||
| # | ||
| # Binaries for programs and plugins | ||
| *.exe | ||
| *.exe~ | ||
| *.dll | ||
| *.so | ||
| *.dylib | ||
|
|
||
| # Test binary, built with `go test -c` | ||
| bin/ | ||
| coverage.out | ||
| *.test | ||
|
|
||
| # Code coverage profiles and other test artifacts | ||
| *.out | ||
| coverage.* | ||
| *.coverprofile | ||
| profile.cov | ||
|
|
||
| # Dependency directories (remove the comment below to include it) | ||
| # vendor/ | ||
|
|
||
| # Go workspace file | ||
| grcli-out/ | ||
| .grcli.yaml | ||
| .env | ||
| go.work | ||
| go.work.sum | ||
|
|
||
| # env file | ||
| .env | ||
|
|
||
| # Editor/IDE | ||
| # .idea/ | ||
| # .vscode/ | ||
| .claude/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| version: "2" | ||
|
|
||
| # golangci-lint v2. The default linter set (standard) is kept; we only | ||
| # re-enable the "std-error-handling" exclusion preset, which v1 applied by | ||
| # default but v2 makes opt-in. It excludes errcheck on fire-and-forget | ||
| # writes to stdout/stderr (fmt.Fprint*, etc.). | ||
| linters: | ||
| exclusions: | ||
| presets: | ||
| - std-error-handling |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Changelog | ||
|
|
||
| Notable changes to `grcli`. This project is pre-1.0; while on `v0.x`, a breaking | ||
| change bumps the minor version. | ||
|
|
||
| ## [0.1.0] - Unreleased | ||
|
|
||
| First release of `grcli` under `github.com/gemaraproj/grcli`, published as a | ||
| signed multi-platform OCI artifact at `ghcr.io/gemaraproj/grcli`. | ||
|
|
||
| ### Added | ||
|
|
||
| - `login` / `logout` — OIDC device-flow sign-in to a hub, credentials stored | ||
| at `$XDG_DATA_HOME/grcli/credentials.json`. | ||
| - `validate` — check Gemara YAML against the spec via `cue vet`. | ||
| - `publish` — pack an artifact plus SLSA-shaped provenance into an OCI bundle, | ||
| sign it, push it, and notify the hub. `--license` (an SPDX expression) is | ||
| required. Keyless signing runs in-process via `sigstore-go` using the | ||
| GitHub Actions OIDC token; `cosign` is needed only for `--cosign-key`. | ||
| - `verify` — verify a bundle's Sigstore signature in-process; with no trust | ||
| flags, against the signer identity the hub recorded at ingest. | ||
| - `unpack` — verify (fail-closed; `--no-verify` to skip) then extract a bundle | ||
| to a directory from a registry or OCI layout. | ||
| - `cat` — stream an artifact's Gemara content to stdout without writing files. | ||
| - `versions <ns>/<id>` — list published versions. | ||
| - On-disk cache for remote fetches at `$GRCLI_CACHE`; `--no-cache` per run, | ||
| `cache-enabled: false` to disable. | ||
| - Single user-global config at `$XDG_CONFIG_HOME/grcli/config.yaml`, with | ||
| `GRCLI_*` env overrides and `--config <file>` to bypass. | ||
| - Reusable GitHub Actions workflow (`.github/workflows/publish-gemara.yml`) | ||
| and install action (`.github/actions/install`). |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.