Doctor plugin checks: implement health check classes and documentation

Implement remediation-aware health checks across all Doctor plugin modules
(Agent, Attestor, Auth, BinaryAnalysis, Compliance, Crypto, Environment,
EvidenceLocker, Notify, Observability, Operations, Policy, Postgres, Release,
Scanner, Storage, Vex) and their backing library counterparts (AI, Attestation,
Authority, Core, Cryptography, Database, Docker, Integration, Notify,
Observability, Security, ServiceGraph, Sources, Verification).

Each check now emits structured remediation metadata (severity, category,
runbook links, and fix suggestions) consumed by the Doctor dashboard
remediation panel.

Also adds:
- docs/doctor/articles/ knowledge base for check explanations
- Advisory AI search seed and allowlist updates for doctor content
- Sprint plan for doctor checks documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-27 12:28:00 +02:00
parent fbd24e71de
commit c58a236d70
326 changed files with 18500 additions and 463 deletions

View File

@@ -0,0 +1,128 @@
---
checkId: check.attestation.cosign.keymaterial
plugin: stellaops.doctor.attestor
severity: fail
tags: [attestation, cosign, signing, setup]
---
# Cosign Key Material
## 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://`) and reports it. Result: **Pass** with provider name and key reference.
### 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
- KeyPath not set in configuration (file mode, incomplete setup)
- Configuration file not loaded (missing appsettings, environment variable not set)
- Key file was moved or deleted from the configured path
- Wrong path configured (typo, path changed during migration)
- Key file not yet generated (first-run setup incomplete)
- KmsKeyRef not configured (KMS mode, missing configuration)
- Unknown or misspelled signing mode in configuration
## How to Fix
### Docker Compose
For **file** mode:
```bash
# 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:
```bash
# Set signing mode to keyless (default)
# ATTESTOR__SIGNING__MODE=keyless
# ATTESTOR__FULCIO__URL=https://fulcio.sigstore.dev
```
For **KMS** mode:
```bash
# 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
```bash
# 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
```bash
# 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
```
## Related Checks
- `check.attestation.keymaterial` -- signing key expiration monitoring
- `check.attestation.rekor.connectivity` -- Rekor required for keyless signing verification
- `check.attestation.clock.skew` -- clock accuracy required for keyless OIDC tokens