cilock-action

module
v1.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 23, 2026 License: Apache-2.0

README

cilock-action

GitHub Action that wraps a command (or another action) with cilock attestation. Records what ran, what files it touched, what containers it pulled, and what credentials it leaked — all into a signed in-toto statement.

- uses: aflock-ai/cilock-action@v1
  with:
    step: build
    attestations: "environment git github sbom secretscan"
    outfile: ${{ github.workspace }}/attestation.json
    command: make build

See action.yml for every input.

The outfile is a DSSE envelope, not a raw attestation

This trips up everyone the first time, including the people writing this README. The file at outfile: is a DSSE envelope:

{
  "payloadType": "application/vnd.in-toto+json",
  "payload": "<base64-encoded in-toto Statement>",
  "signatures": [{ "keyid": "…", "sig": "…", "cert": "…" }]
}

The actual attestation content — predicateType, subject, predicate.attestations[] — lives inside .payload, base64-encoded. Treating the envelope as the statement leads to OPA policies that silently match nothing because input.predicate doesn't exist at the envelope level.

Decode it before consuming
# Inspect the inner Statement
jq -r '.payload' attestation.json | base64 -d | jq .

# Predicate type
jq -r '.payload' attestation.json | base64 -d | jq -r '.predicateType'
# → https://aflock.ai/attestation-collection/v0.1

# Per-attestor entries (this is where secretscan findings, trace data, etc. live)
jq -r '.payload' attestation.json | base64 -d \
  | jq '.predicate.attestations[] | {type, attestation_keys: (.attestation | keys)}'
Feed it to OPA

OPA Rego policies that match on input.predicate.attestations[] need the decoded statement, not the envelope. The right shape:

jq -r '.payload' attestation.json | base64 -d > /tmp/statement.json

opa eval -d policy.rego -i /tmp/statement.json 'data.cilock.verify.deny' -f json

If your policy expects a specific attestor's data at the top level (e.g. trace data from command-run), drill in one more layer:

jq '.predicate.attestations[] | .attestation | select(has("processes"))' /tmp/statement.json \
  > /tmp/trace-input.json

opa eval -d policy-trace.rego -i /tmp/trace-input.json 'data.cilock.verify.deny' -f json
Why DSSE?

DSSE is what makes the signature meaningful — it covers the exact bytes of the payload (including payloadType), so downstream verifiers can prove what was signed without re-canonicalizing JSON. The base64 wrapping prevents whitespace and key-ordering changes from invalidating signatures.

The downside is the extra unwrap step. If you build CI checks against cilock attestations, write a small helper:

# decode_attestation.sh
jq -r '.payload' "$1" | base64 -d

…and use it everywhere.

Inputs

See action.yml. The most-used ones:

Input Purpose
step Step name embedded in the attestation (required)
command / action-ref What to wrap (exactly one required)
attestations Space-separated attestor list
outfile Path for the DSSE envelope. Format above.
trace Enable command tracing (ptrace on Linux)
enable-sigstore Sign with Fulcio (default true)
enable-archivista Upload to Archivista (default true)
cilock-args Pass-through args to attestors (see supported flags)
cilock-args passthrough

cilock-action runs the rookery library in-process — it does not shell out to the cilock binary — so only flags that the action explicitly translates take effect. Currently supported:

  • --attestor-secretscan-fail-on-detection [bool] — exit non-zero when secretscan records findings
  • --attestor-secretscan-max-decode-layers <int> — how many encoding layers to recursively decode (default 3)
  • --attestor-secretscan-max-file-size <int-mb> — skip files larger than this
  • --attestor-secretscan-config-path <path> — custom Gitleaks config

Unknown flags are silently ignored. File an issue or PR if you need another attestor option wired through.

Examples

Wrap a command and assert on secretscan findings
- uses: aflock-ai/cilock-action@v1
  with:
    step: build
    attestations: "environment git github secretscan"
    outfile: ${{ github.workspace }}/attestation.json
    cilock-args: "--attestor-secretscan-fail-on-detection"
    command: make build
Wrap an upstream action (e.g. supply-chain hygiene)
- uses: aflock-ai/cilock-action@v1
  with:
    step: trivy-scan
    attestations: "environment git github sbom"
    outfile: ${{ github.workspace }}/scan.attestation.json
    action-ref: aquasecurity/trivy-action@76071ef0d7ec1c61c8c2dc1a37a91019797d3c1b
    action-inputs: |
      {"scan-type": "fs", "scan-ref": "."}
Verify in CI with OPA
- uses: aflock-ai/cilock-action@v1
  with:
    step: build
    outfile: ${{ github.workspace }}/attestation.json
    command: make build

- name: Decode and verify
  run: |
    jq -r '.payload' attestation.json | base64 -d > /tmp/statement.json
    opa eval -d policy.rego -i /tmp/statement.json \
      'data.cilock.verify.deny' -f json | tee /tmp/opa-result.json
    DENY=$(jq -r '.result[0].expressions[0].value | length // 0' /tmp/opa-result.json)
    if [ "$DENY" -gt 0 ]; then
      echo "::error::policy denied $DENY rules"
      exit 1
    fi

Versioning

  • @v1 — major-version tag, auto-updated on each v1.x.y release
  • @v1.0.1 — exact-tag pin
  • @<40-hex-SHA> — SHA pin against the published-tag commit (recommended for supply-chain hygiene; the shim resolves the SHA to its release tag)

License

Apache 2.0. Built and sponsored by TestifySec.

Directories

Path Synopsis
cmd
cilock-action command
cilock-action is the Go binary for the cilock GitHub Action / GitLab CI template.
cilock-action is the Go binary for the cilock GitHub Action / GitLab CI template.
internal
actions
Package actions implements downloading, parsing, and executing GitHub Actions.
Package actions implements downloading, parsing, and executing GitHub Actions.
attestation
Package attestation wraps rookery's workflow API to run attestation from cilock-action's config.
Package attestation wraps rookery's workflow API to run attestation from cilock-action's config.
bypass
Package bypass implements CILOCK_BYPASS mode, which skips attestation and runs the command directly.
Package bypass implements CILOCK_BYPASS mode, which skips attestation and runs the command directly.
config
Package config defines the platform-agnostic configuration for cilock-action.
Package config defines the platform-agnostic configuration for cilock-action.
platform
Package platform provides CI platform detection and input parsing.
Package platform provides CI platform detection and input parsing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL