Skip to main content
View Markdown ↗

Copy this page

Select and copy the Markdown below, then paste it into your LLM.

On this page

aflock-ai/cilock-action reference

Source of truth: cilock-action/action.yml.

The CI/lock GitHub Action wraps a command (or another GitHub Action) and produces signed attestations. It downloads its own variant of the cilock binary at runtime from the cilock-action releases.

- uses: aflock-ai/cilock-action@d39bb9b17e392520f9e7eef17cf355c027a5c283 # v1.0.4
  with:
    step: build
    command: "go build -o myapp ./cmd/myapp"
    platform-url: ${{ vars.CILOCK_PLATFORM_URL }}   # your administrator-approved origin

Name the destination. With enable-archivista at its default (true), the action signs through the Fulcio derived from platform-url and uploads the evidence to that platform's Archivista. If you omit platform-url, both default to the hosted platform, https://platform.testifysec.com. Set it explicitly to the origin your administrator approved for this repository: the hosted platform, or your private or self-hosted deployment, with the tenant and product already set up there. See the GitHub Actions tutorial for a preflight step that refuses to run without it.

Release pinned in these docs: v1.0.4, commit d39bb9b17e392520f9e7eef17cf355c027a5c283, the release every recipe on this site was checked against. It bundles a CI/lock built from rookery main with govulncheck, inclusion-proof, secretscan, slsa, and the PR #153 atomic-rename trace fix. It is not the newest release: GitHub lists v3.0.8 (2026-06-10, commit f3cf4e0487df980ee6aa3734229b4d2e9fd27a4d), whose platform-url and enable-archivista defaults are the ones described on this page. Read a release's notes before moving a pipeline to it, then pin its commit SHA with the tag in a comment — never a moving tag or major-version ref, which can be re-pointed after you reviewed the workflow.

What v1.0.4 evidence cannot do

v1.0.4 was built from an older rookery, and its evidence does not pass every verification these docs teach:

  • It records command-run/v0.1. The policies in these docs require https://aflock.ai/attestations/command-run/v0.2, and verification refuses a v1.0.4 envelope against them (missing required attestation .../command-run/v0.2). A policy for v1.0.4 evidence has to name command-run/v0.1.
  • Its products and materials carry no file list. They appear only as Merkle tree: subjects, so cilock verify -f <artifact> and an artifactsFrom chain cannot pass on its evidence.
  • cilock-args is mostly dropped. It applies only the --attestor-secretscan-* flags. --attestor-product-include-glob, --trace, --capture-mode, --require-zero-drops and --material-manifest are silently ignored, and so is the product-include-glob input.
  • An empty platform-url means the hosted platform. platform-url: ${{ vars.X }} with X unset signs and uploads to https://platform.testifysec.com.

For a step that needs artifact (-f) or cross-step (artifactsFrom) verification, run the plain CLI (cilock run) until a release built from current source is published. The action's current source records command-run/v0.2 and inline file lists. It applies the product globs, and it refuses cilock-args, an empty platform-url and the other inputs it would drop. That source is not released yet, so the pin above stays v1.0.4.

Multi-step chain via step names

CI/lock's policy language lets you declare relationships between attested steps. By giving each step a distinct name and declaring artifactsFrom in the verification policy, the verifier enforces that step N's materials match step N-1's products byte-for-byte. This is how CI/lock's own release pipeline chains vendor-cilock-deps → release-build — see Verify the cilock binary.

v1.0.4 evidence cannot pass that check (see above), so run chained steps with the plain CLI in the same workflow. Install cilock on PATH first, outside the checkout, as the release promotion gate does. --material-manifest keeps the file inventory the comparison reads, and the outfiles go under $RUNNER_TEMP so one step's evidence is not an input of the next:

# Step 1 — vendor
- name: vendor-deps
  run: |
    cilock run --step vendor-deps --material-manifest \
      -o "$RUNNER_TEMP/vendor.attestation.json" \
      -- go mod vendor

# Step 2 — build; the policy chains app-build to vendor-deps
- name: app-build
  run: |
    cilock run --step app-build --material-manifest --trace \
      -o "$RUNNER_TEMP/build.attestation.json" \
      -- go build -mod=vendor -o app ./cmd/app

--trace records network egress and file operations for the hermetic Rego gates.

Required permissions

For keyless Sigstore signing (the default), the workflow needs:

permissions:
  id-token: write   # for OIDC token to Fulcio
  contents: read    # standard checkout

Add packages: write if you push container images, etc.

Inputs

Core

One of command or action-ref is required.

InputDefaultDescription
step(required)Step name for the attestation.
command(none)Shell command to run.
action-ref(none)GitHub Action to wrap (owner/repo@ref or docker://image).
action-inputs(none)JSON map of inputs to pass to the wrapped action.
action-env(none)Additional env vars for the wrapped action (KEY=VALUE per line).

Binary

InputDefaultDescription
versionmatches action tagcilock-action release version to download.
cilock-binary-url(none)Custom URL for a pre-built cilock binary.
cilock-args(none)v1.0.4 applies only the --attestor-secretscan-* flags and silently drops the rest. Current source refuses the input. Use the dedicated inputs instead.

Attestation

InputDefaultDescription
attestationsenvironment git githubSpace-separated attestor list (the shim translates to the comma-separated form the cilock CLI expects). v1.0.4 reads environment,git as one unknown attestor; current source also accepts commas.
outfile(none)Output file for signed envelope.
workingdir(none)Working directory.
tracefalseEnable command tracing.
hashessha256Hash algorithms.

TestifySec platform

InputDefaultDescription
platform-urlhttps://platform.testifysec.comAll service URLs are derived from this, including where evidence is uploaded. Set it explicitly to your administrator-approved origin; the default sends evidence to the hosted platform.

Archivista

Derived from platform-url if not explicitly set.

InputDefaultDescription
enable-archivistatrueStore attestations in Archivista.
archivista-serverderived from platform-urlArchivista server URL.

Sigstore / Fulcio

Derived from platform-url if not explicitly set.

InputDefaultDescription
enable-sigstoretrueEnable Sigstore/Fulcio signing.
fulcio-urlderived from platform-urlFulcio server URL.
fulcio-oidc-client-idsigstoreFulcio OIDC client ID.
fulcio-oidc-issuerhttps://token.actions.githubusercontent.comFulcio OIDC issuer URL.
fulcio-use-httptrueUse HTTP/REST API for Fulcio (works behind any reverse proxy).

File signer

InputDefaultDescription
key(none)Path to signing key.
certificate(none)Path to signing certificate.
intermediates(none)Comma-separated paths to intermediate certificates.

KMS

InputDefaultDescription
kms-aws-profile(none)AWS profile for KMS signing.
kms-gcp-credentials-file(none)GCP credentials file for KMS signing.
kms-ref(none)KMS key reference URI (awskms://..., gcpkms://..., azurekms://..., hashivault://...).

Vault

InputDefaultDescription
vault-url(none)HashiCorp Vault URL.
vault-token(none)HashiCorp Vault token.

Timestamps

InputDefaultDescription
timestamp-serversderived from platform-urlSpace-separated TSA URLs.

Environment filtering

InputDefaultDescription
env-add-sensitive-key(none)Comma-separated additional sensitive env var keys.
env-filter-sensitive-varsfalseFilter (remove) sensitive vars instead of obfuscating.

Material / Product

InputDefaultDescription
product-include-glob*Glob for product file inclusion.
product-exclude-glob(none)Glob for product file exclusion.

Attestor exports

InputDefaultDescription
attestor-sbom-exportfalseExport SBOM as a separate attestation.
attestor-slsa-exportfalseExport SLSA provenance as a separate attestation.

Builder

InputDefaultDescription
builder-manifest(none)Path to a rookery-builder manifest for a custom binary.
builder-preset(none)Builder preset: minimal, cicd, all.

Outputs

OutputDescription
git_oidGitOID of the stored attestation.
attestation_filePath to the attestation output.

Runtime

runs:
  using: "node20"
  main: "shim/index.js"

The shim/index.js Node entry point downloads the variant binary from https://github.com/aflock-ai/cilock-action/releases/{latest/download | download/<tag>} and invokes it with the constructed args.

SLSA Build L3: the provenance workflow

Availability — read before you run this

The verifier half ships: cilock verify --slsa-level is in cilock v4.6.0 and later. The builder half ships too: provenance.yml is in cilock-action release v4.6.2, byte for byte the file on main, so pin a commit that contains it. Even so, the standards guidance and the support matrix still list SLSA Build L3 as planned, because the matrix does not yet count this mode as available. Treat this section as early access, not a supported level.

When cilock runs inside your build job, the provenance it signs can reach SLSA Build L2 at most. The job's own steps could forge it. For L3, add a second job. It calls the reusable provenance.yml workflow, runs none of your code, and signs SLSA v1 provenance with its own Fulcio identity:

  provenance:
    needs: build
    permissions: { id-token: write }
    uses: aflock-ai/cilock-action/.github/workflows/provenance.yml@<40-hex commit>
    with: { subjects: "${{ needs.build.outputs.subjects }}" }
  • Pin by commit, never by tag. The verifier requires the certificate's Build Signer URI to name the pinned commit, so a tag pin is refused.
  • subjects is one <name>=sha256:<hex> per line. Your build job outputs it, for example with echo "subjects=app=sha256:$(sha256sum dist/app | cut -d' ' -f1)" >> "$GITHUB_OUTPUT". The build job must also run cilock in the same workflow run: a subject is accepted only if that run's build collection carries it.
  • Triggers: the workflow signs only for push, release and workflow_dispatch. Any other event, fork pull requests and pull_request_target included, fails the job.
  • Signer: the platform's Fulcio and timestamp authority by default (platform-url). Set public-sigstore: true to use public Sigstore instead.

Verify with the built-in L3 policy. There is no -p:

cilock verify ./dist/app --slsa-level 3 \
  --slsa-builder-digest <the same commit> --slsa-source-repo <owner>/<repo> \
  -a provenance.json -a build.json --vsa-outfile vsa.json

--slsa-level 3 exits 0 only if all of these hold:

  • the provenance's signing certificate names provenance.yml at that commit, a GitHub-hosted runner, a writer-only trigger, and your repository;
  • builder.id, repository, commit and run in the statement equal that certificate's extensions;
  • buildType and externalParameters are what provenance.yml writes;
  • the artifact is among the subjects, and a build collection from the same run, repository and commit carries it.

--format json lists each requirement that failed. The VSA states SLSA_BUILD_LEVEL_3 only on a pass. Add --slsa-roots public-sigstore with --slsa-public-sigstore-ca-roots and --slsa-public-sigstore-timestamp-servers to accept public Sigstore signatures.

Worked examples

The action ships example workflows in examples/github/:

  • Wrapping another GitHub Action (e.g. docker/build-push-action)
  • Wrapping a shell command
  • Multi-step pipeline with downstream verification

The full end-to-end walkthrough lives in the GitHub Actions tutorial.

Reference generated from the product documentation. Match commands and support details to your installed release.