Skip to main content
This is a beta feature. Beta features provide early access to product functionality. These features may change between releases without warning, or can be removed in a future release. Please contact us to enable this feature for your organization.

Synopsis

Record an in-toto attestation, such as SLSA provenance or an SBOM, that a build already produced.
Build systems produce in-toto attestations as they build: actions/attest, cosign attest and docker buildx --provenance --sbom among them. This command records one in Kosli, verifying its signature first, rather than regenerating the same evidence with other kosli attest commands.
--predicate-type chooses what to record, one kind per command:
  • provenance (SLSA provenance v1 or v0.2) reports the artifact named by --name, as kosli attest artifact does. The commit, branch, repository and build URL come from the statement, never from the CI environment, so the build’s own commit and run are recorded even when this command runs in a different job or workflow.
  • sbom (SPDX or CycloneDX) reports an SBOM attestation named by --name, as kosli attest sbom does, with the attestation attached in place of the SBOM file.
Recording provenance and an SBOM takes two commands. The attestation is read from the file given with --bundle: a Sigstore bundle (.sigstore.json), a DSSE envelope, an in-toto statement, or an .intoto.jsonl file with one of these per line. Attestations of other kinds are ignored. When several qualify, a verified one is preferred, then the newest. The statement must list the artifact as its subject. A signed attestation is verified with Sigstore against a signer you pin: --certificate-identity (or --certificate-identity-regexp) with --certificate-oidc-issuer, or --key. There is no way to accept any valid certificate. An unsigned attestation is refused unless --allow-unsigned is given, and is then recorded as unverified. An attestation that fails verification, because another signer made it or it was changed after signing, fails the command and nothing is recorded, even when another attestation in the file would qualify. So does a signed attestation whose signature cannot be checked, such as when no signer is pinned, a trust root cannot be fetched or the signer flags do not fit how it was signed; the error then says it could not be verified, not that it failed. Verifying a certificate-signed attestation needs the trust root of the Sigstore instance that signed it: Sigstore’s public-good instance, or GitHub’s own, which signs attestations for private repositories. It is fetched over TUF on every run that verifies one, from https://tuf-repo-cdn.sigstore.dev or https://tuf-repo.github.com respectively, and cached under ~/.sigstore, so the runner needs outbound HTTPS to that host and a writable ~/.sigstore directory. A key-signed attestation needs neither, unless it carries a transparency log entry or a signed timestamp, which are checked against Sigstore’s public-good trust root. An unsigned attestation needs neither. The record is annotated with verified and, for a signed attestation, signer_identity, signer_issuer, log_index, integrated_time and signed_timestamp where they apply. Provenance adds builder_id, build_type and workflow, and an SBOM adds sbom_format and sbom_sha256. A transparency log entry is linked as the attestation external URL, pinned by the SHA-256 of the attestation’s bytes. For provenance, the commit’s message, author and time are looked up on GitHub with --github-token when the statement names a GitHub repository, or else read from the git checkout at --repo-root if it holds the commit. Failing both, only the commit’s SHA is recorded, without its details or branch. A repository on GitHub Enterprise Server needs --repo-provider github and --github-base-url to be looked up there: the token is only sent to the server you name, never to a host taken from the statement. A build URL or commit URL the statement does not carry can be given with --build-url and --commit-url. The artifact fingerprint can be provided directly with the --fingerprint flag, or calculated based on --artifact-type flag. Artifact type can be one of: “file” for files, “dir” for directories, “oci” for container images in registries or “docker” for local docker images. Note: --artifact-type=docker reads the image’s repo digest via the local Docker daemon. The image must have been pushed to or pulled from a registry for a repo digest to exist; a freshly built image (just docker build) will not have one. If the image is already in a registry, prefer --artifact-type=oci, which fetches the digest directly from the registry without needing a local Docker daemon. For --artifact-type=oci (and for --artifact-type=docker when --registry-username is set), registry credentials are resolved as follows:
  1. If --registry-username (and optionally --registry-password) is set, it is used directly.
  2. Otherwise, credentials are discovered automatically from:
    • the Docker config file (~/.docker/config.json, populated by docker login)
    • the Podman/containers auth file (~/.config/containers/auth.json, or $REGISTRY_AUTH_FILE)
    • any Docker credential helper configured in that config (e.g. docker-credential-ecr-login for AWS ECR, docker-credential-gcloud for GCR/Artifact Registry, an ACR helper for Azure, or a local keychain helper), invoked as an external binary on $PATH
    • if none of the above yield credentials, the registry is accessed anonymously, which works for public images --registry-provider is deprecated and no longer used.
To specify paths in a directory artifact that should always be excluded from the SHA256 calculation, you can add a .kosli_ignore file to the root of the artifact. Each line should specify a relative path or path glob to be ignored. You can include comments in this file, using #. The .kosli_ignore file is always treated as part of the artifact: its own entries cannot exclude it, so the exclusion list cannot be changed without changing the fingerprint. Paths the list already matches stay excluded whatever is later added there, so keep its entries as narrow as possible. Excluding the file with --exclude keeps it out of the fingerprint but still applies the paths it lists, which lets a writable directory change the list again. To drop the file from the fingerprint safely, move its entries to --exclude and delete it.

Flags

Flags inherited from parent commands

Examples Use Cases

These examples all assume that the flags --api-token, --org, --host, (and --flow, --trail when required), are set/provided.
Last modified on November 12, 2026