checkId: check.attestation.cosign.keymaterial plugin: stellaops.doctor.attestor severity: fail tags: [attestation, cosign, signing, setup]

Cosign Key Material

This Stella Ops Doctor check confirms that the Attestor has usable signing key material before any signing operation is attempted. It is part of the attestation diagnostics surfaced by stella doctor; see the Doctor overview for how checks are run and reported.

What It Checks

Verifies that signing key material is available for container image attestation. The check reads the signing mode from configuration (Attestor:Signing:Mode or Signing:Mode, defaulting to keyless) and validates the appropriate key material for that mode:

Keyless mode

Checks that Fulcio URL is configured (defaults to https://fulcio.sigstore.dev). Uses OIDC identity for signing – no persistent key material required. Result: Pass if configured.

File mode

  1. If KeyPath is not configured: Fail with “KeyPath not configured”.
  2. If the key file does not exist at the configured path: Fail with “Signing key file not found”.
  3. If the key file cannot be read (permission error): Fail with the error message.
  4. If the key file exists and is readable: Pass with file size and last modification time.

KMS mode

  1. If KmsKeyRef is not configured: Fail with “KmsKeyRef not configured”.
  2. If configured, the check parses the KMS provider from the key reference URI prefix (awskms://, gcpkms://, azurekms://, hashivault://, pkcs11://) and reports it.

KMS connectivity is not verified in-process. The live in-process implementation (stellaops.doctor.attestation, configured via Sigstore:KMS:KeyRef) only parses the reference format — it does not contact the KMS or confirm the signing key is reachable, and most listed providers are cloud-managed, which the air-gap/on-prem invariant excludes from any in-process probe. Per ADR-026 D7 (no fabricated Pass), KMS mode now returns an honest Skip (“KMS key accessibility was not verified; requires the provider SDK”), with Verified=false evidence — not a Pass. Verify KMS access out-of-band with the provider CLI/SDK, or prefer a file-based key (Sigstore:KeyPath) / keyless mode for air-gapped, locally-verifiable deployments.

Unknown mode

Fail with “Unknown signing mode” and the list of supported modes.

Evidence collected varies by mode: SigningMode, FulcioUrl, KeyPath, FileExists, FileSize, LastModified, KmsKeyRef, Provider.

Why It Matters

Without valid signing key material, the Attestor cannot sign container images, SBOMs, or provenance attestations. Unsigned artifacts cannot pass policy gates that require signature verification, blocking the entire release pipeline. This check ensures the signing infrastructure is correctly configured before any signing operations are attempted.

Common Causes

How to Fix

Docker Compose

For file mode:

# Generate a new Cosign key pair
docker compose -f devops/compose/docker-compose.stella-ops.yml exec attestor \
  cosign generate-key-pair --output-key-prefix stellaops

# Set key path in environment
# ATTESTOR__SIGNING__MODE=file
# ATTESTOR__SIGNING__KEYPATH=/etc/stellaops/cosign.key

# Restart attestor
docker compose -f devops/compose/docker-compose.stella-ops.yml restart attestor

For keyless mode:

# Set signing mode to keyless (default)
# ATTESTOR__SIGNING__MODE=keyless
# ATTESTOR__FULCIO__URL=https://fulcio.sigstore.dev

For KMS mode:

# Set KMS key reference
# ATTESTOR__SIGNING__MODE=kms
# ATTESTOR__SIGNING__KMSKEYREF=awskms:///arn:aws:kms:us-east-1:123456789:key/abcd-1234

Bare Metal / systemd

# Configure signing mode
stella attestor signing configure --mode keyless

# For file mode, generate keys
cosign generate-key-pair --output-key-prefix stellaops
stella attestor signing configure --mode file --key-path /etc/stellaops/cosign.key

# For KMS mode (AWS example)
stella attestor signing configure --mode kms \
  --kms-key-ref 'awskms:///arn:aws:kms:us-east-1:123456789:key/abcd-1234'

# For KMS mode (GCP example)
stella attestor signing configure --mode kms \
  --kms-key-ref 'gcpkms://projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-key'

# Check if key exists at another location
find /etc/stellaops -name '*.key' -o -name 'cosign*'

Kubernetes / Helm

# For file mode, create secret with key material
kubectl create secret generic stellaops-cosign-key -n stellaops \
  --from-file=cosign.key=/path/to/cosign.key \
  --from-file=cosign.pub=/path/to/cosign.pub

# Set signing configuration in Helm values
# attestor:
#   signing:
#     mode: "kms"  # or "file" or "keyless"
#     kmsKeyRef: "awskms:///arn:aws:kms:..."
#     # For file mode:
#     # keyPath: "/etc/stellaops/cosign.key"
#     # keySecret: "stellaops-cosign-key"
helm upgrade stellaops stellaops/stellaops -f values.yaml

Verification

stella doctor run --check check.attestation.cosign.keymaterial