Skip to main content

Signing & identity

A signer is the cryptographic identity used to sign an attestation. In policy, the signer is what gets evaluated against a functionary: the policy's declaration of who is allowed to sign for a given step.

The verifier's question is always:

Does the signer of this evidence match a trusted functionary for this step?

Signers in the cilock binary

The cilock binary registers the following signer providers:

SignerTypeWhen to pick it
fulcioKeyless (Sigstore)CI runs in a hosted system with an OIDC token (GitHub Actions, GitLab CI). Default for most teams.
spiffeKeyless (SPIFFE/SPIRE)Workloads in a SPIFFE-enabled mesh that already have SVID identities.
kms/awsCloud KMSLong-lived AWS-managed identity, HSM-backed keys.
kms/gcpCloud KMSLong-lived GCP-managed identity.
kms/azureCloud KMS (Azure Key Vault)Long-lived Azure-managed identity.
vaultHashiCorp VaultVault-issued signing keys.
vault-transitHashiCorp Vault Transit engineCentralized signing-as-a-service via Vault Transit.
fileLocal key fileLocal development, CI without OIDC. Not recommended for production releases.
debug-signerDebugDevelopment and integration testing.

For the full decision tree, see Choose a signer.

Keyless signing: Fulcio and SPIFFE

Fulcio is the Sigstore certificate authority. It issues short-lived signing certificates tied to CI identity by exchanging a CI runtime's OIDC token (e.g. the id-token GitHub Actions provides) for a certificate valid for a few minutes, long enough to sign, short enough that there's nothing meaningful to steal. No long-lived private key to manage.

SPIFFE/SPIRE is the alternative for workloads inside a service mesh. Identity is encoded as a SPIFFE ID URI on the certificate (e.g. spiffe://example.com/step1). Witness/cilock policies can require functionaries by SPIFFE URI directly, see the policy SPIFFE example.

KMS signers (URI scheme)

KMS signers use a URI-based reference scheme borrowed from Sigstore Cosign:

  • AWS: awskms:///arn:aws:kms:us-east-2:111122223333:key/1234abcd-... (note the triple slash) Also supports key ID, alias name, alias ARN, and custom endpoints (e.g. localstack) via awskms://[endpoint]/[ID/ALIAS/ARN].
  • GCP: gcpkms://projects/$PROJECT/locations/$LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY/cryptoKeyVersions/$KEY_VERSION. The cryptoKeyVersions/$VERSION suffix (and its versions/$VERSION shorthand) is optional and resolves to the key's primary version when omitted.
  • Azure Key Vault: azurekms://<vault-name>.vault.azure.net/<key>[/<key-version>]. The host segment is specifically the vault's DNS name, not an arbitrary URI.

Authentication uses each cloud provider's standard credential resolution. A KMS reference URI can also be used as a publickeyid in a policy, so the verifier knows to fetch the public key from the KMS service. For air-gapped verification, a base64-encoded PEM public key can be embedded in the policy directly.

What the verifier checks

When cilock verify runs against a policy, it checks identity by asking:

  • Is the signature valid for the envelope?
  • Does the signer's certificate or public key match a trusted functionary for this step?
  • For X.509 functionaries: do the certificate constraints (commonname, dnsnames, emails, organizations, SPIFFE URIs, trusted roots) match?

For long-term integrity, verifying a years-old signature whose certificate has long since expired, see Timestamping.