Skip to main content

Standards guidance

A ceiling is the highest level this evidence could support. It is not a verified level: a SLSA Build level needs an assessment of the build platform, and an ALPS level needs an independent verifier.

cilock run and cilock verify print a standards block and, under --json / --format json, a typed standards object (schema cilock.standards-guidance/v1) with slsa_build.ceiling, alps.ceiling, verified_level: null and an ordered next_steps[]. When a coding agent drives cilock, the steps are phrased as imperative actions for the agent.

SLSA Build​

Specification: SLSA v1.2 Build track

LevelStatusRequiresHow cilock observes it
L1availableProvenance exists for the build.The run selected the slsa attestor (-a slsa) and signed the collection.
L2availableProvenance is generated and signed by a hosted build platform and timestamped.The signing leaf is a keyless CI workload identity (GitHub Actions, gitlab.com, Buildkite, CircleCI or a Kubernetes service account, recognized by its OIDC issuer) and its runner-environment names a provider-hosted runner, and the envelope carries an RFC 3161 timestamp. On a self-hosted runner, CircleCI or Kubernetes the level depends on whether you treat your runner operator as the build platform (formal/slsa-tracks interpretation I2), so cilock reports those as not provider-hosted.
L3plannedProvenance is unforgeable by the tenant's build steps: it is signed under a builder identity no build step can obtain, on an isolated, ephemeral runner.The signing leaf's Build Signer URI names the isolated provenance workflow (builder_identity on the slsa-provenance-workflow step), not the tenant workflow. GitHub Actions only: other CI signer identities are pipeline-wide.

Not reachable on some CI platforms​

  • L3 on gitlab, buildkite, circleci, kubernetes: not reachable on this CI today: its signer identity is pipeline-wide, so a build step can mint it. The only paths are the GitHub Actions provenance workflow (coming) and cilockd on a runner you operate (not yet available).

Next steps​

slsa-provenance-attestor (to L1, available)​

SLSA Build L1 needs provenance, and this run produced none.

Action: Add the slsa attestor to the cilock run invocation.

cilock run --step build -a slsa -- <your build command>

slsa-hosted-runner (to L2, available)​

SLSA Build L2 needs a hosted build platform. A laptop is never one. On a self-hosted runner, CircleCI or Kubernetes it depends on whether you treat your runner operator as the build platform; a provider-hosted runner (GitHub-hosted, gitlab.com SaaS, Buildkite hosted) removes that question.

Action: Run the build on a provider-hosted runner (GitHub-hosted, gitlab.com SaaS, or Buildkite hosted), or decide that your runner operator counts as the build platform and record why.

jobs:
build:
runs-on: ubuntu-latest

slsa-workflow-identity (to L2, available)​

SLSA Build L2 needs provenance signed by the platform's workload identity, not a key or a person's session.

Action: Sign keyless with your CI's workload OIDC identity. GitHub Actions works with the platform Fulcio or public Sigstore (grant id-token: write and use cilock-action). gitlab.com, Buildkite hosted and CircleCI cloud work with the platform Fulcio from the CI/lock release after 4.5.0, which fetches their job token itself (on gitlab.com declare an id_tokens entry with audience sigstore); with CI/lock 4.5.0 or earlier, and on Kubernetes, sign through public Sigstore Fulcio.

permissions:
id-token: write
contents: read
steps:
- uses: aflock-ai/cilock-[email protected] # pin to a 40-character commit SHA
with:
step: build
command: "<your build command>"
attestations: environment git github slsa

Docs: https://cilock.dev/getting-started/quickstart-ci

slsa-timestamp (to L2, available)​

The envelope carries no trusted timestamp, so a short-lived keyless leaf cannot be verified later.

Action: Sign with a timestamp authority.

cilock run --step build -a slsa --timestamp-servers <tsa-url> -- <your build command>

slsa-provenance-workflow (to L3, planned)​

Inline provenance is signed by the same workflow identity the build steps can mint, so a build step can forge it (issue #9822). L3 needs a separate builder identity, which only GitHub Actions' reusable-workflow identity provides.

Action: Coming: the isolated cilock provenance workflow. When it ships, add a provenance job that needs the build job and signs the build's subjects under its own identity.

Not yet published. Run and verify output withhold this snippet until it ships:

provenance:
needs: build
permissions:
id-token: write
uses: aflock-ai/cilock-action/.github/workflows/provenance.yml@{{pin}}
with:
subjects: ${{ needs.build.outputs.subjects }}

ALPS​

Specification: ALPS 0.1

LevelStatusRequiresHow cilock observes it
ALPS-0availableThe statement is signed and bound to the commit.The run signed the collection.
ALPS-1availableThe signing leaf chains to the platform root and names a non-human agent or workload principal, and the envelope is timestamped.Not reported by cilock yet. A leaf that names an agent or a CI workflow does not show the platform issued it (the same name appears under public Sigstore or a BYO CA), and authenticating the platform root is a separate design, so run and verify report ALPS-0 at most. A verifier policy that pins the platform root can still require it.
ALPS-2plannedThe run happened inside an enforced sandbox, and a non-agent observer signed the boundary it ran in.Nothing yet: the alps-evidence predicate has no boundary field. See docs/design/alps-2-boundary-attestation.md.
ALPS-3futurerequires cilockd (not yet available)Nothing yet.

Next steps​

alps-agent-identity (to ALPS-1, available)​

ALPS 1 needs a non-human principal the platform issued. This run signed with a local key or a human session, so the evidence cannot say an agent signed it.

Action: Enroll an agent identity for this machine and approve it in the browser.

cilock enroll agent

alps-workflow-identity (to ALPS-1, available)​

ALPS 1 needs a non-human principal the platform issued. In CI that is the job's workload OIDC identity, which this job did not sign with.

Action: Sign with the job's workload identity against the platform Fulcio. On GitHub Actions grant the job id-token: write. On gitlab.com, Buildkite or CircleCI use a CI/lock newer than 4.5.0, which fetches the job token itself (on gitlab.com declare an id_tokens entry with audience sigstore). Other CI has no platform-issued identity yet.

alps-timestamp (to ALPS-1, available)​

The envelope carries no trusted timestamp, so a short-lived identity cannot be verified later.

Action: Sign with a timestamp authority.

cilock run --step <step> --timestamp-servers <tsa-url> -- <command>

alps-boundary-attestation (to ALPS-2, planned)​

ALPS 2 needs an enforced sandbox and a non-agent observer that signs the boundary. cilock records no boundary today, so no run can present ALPS 2 evidence yet.

Action: Coming: boundary attestation in alps-evidence. Until it ships, run the agent inside the recommended sandbox so the run already has the boundary the attestation will record.

Docs: https://pushgate.dev/docs/agent-sandbox