Files
git.stella-ops.org/docs/modules/cli/guides/attest.md

222 lines
6.1 KiB
Markdown

# CLI Attest Guide (DOCS-ATTEST-74-004)
How to verify and inspect attestations via CLI.
## Verify DSSE
```bash
stella attest verify --envelope bundle.dsse.json --policy policy.json \
--root keys/root.pem --transparency-checkpoint checkpoints/rekor.json
```
- Offline verification uses bundled roots and checkpoints; transparency optional.
## List attestations
```bash
stella attest list --tenant default --issuer dev-kms --format table
```
## Show attestation
```bash
stella attest show --id a1b2c3 --output json
```
---
## Verify Offline (Air-Gapped Environments)
Verify attestation bundles completely offline without network access.
### Synopsis
```bash
stella attest verify-offline --bundle <path.tar.gz> [options]
```
### Options
| Option | Alias | Description |
|--------|-------|-------------|
| `--bundle <path>` | `-b` | **Required.** Path to attestation bundle (tar.gz). |
| `--checkpoint <path>` | `-c` | Path to Rekor checkpoint signature file. |
| `--trust-root <dir>` | `-r` | Path to trust root directory containing CA certificates. |
| `--artifact <digest>` | `-a` | Expected artifact digest (sha256:...) to verify against. |
| `--predicate-type <type>` | `-p` | Expected predicate type (e.g., https://slsa.dev/provenance/v1). |
| `--output <file>` | `-o` | Write verification report to file instead of stdout. |
| `--format <fmt>` | `-f` | Output format: `json`, `summary` (default), or `html`. |
| `--strict` | | Fail if any optional verification step fails. |
| `--verbose` | | Show detailed verification progress. |
### Verification Checks
The command performs the following verification checks:
1. **DSSE Envelope Signature**: Validates the DSSE envelope structure and signatures.
2. **Merkle Inclusion Proof**: Verifies Rekor transparency log inclusion proof.
3. **Checkpoint Signature**: Validates checkpoint signature against trusted keys.
4. **Content Hash**: Ensures all file hashes match the manifest.
### Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Verification passed |
| 1 | Verification failed (one or more checks failed) |
| 2 | Error (file not found, parse error, etc.) |
### Examples
```bash
# Basic offline verification
stella attest verify-offline --bundle evidence.tar.gz
# Full verification with all options
stella attest verify-offline \
--bundle evidence.tar.gz \
--checkpoint checkpoint.sig \
--trust-root /path/to/roots/ \
--artifact sha256:abc123def456 \
--predicate-type https://slsa.dev/provenance/v1
# Generate JSON verification report
stella attest verify-offline \
--bundle evidence.tar.gz \
--format json \
--output report.json
# Strict mode (fail on optional check failures)
stella attest verify-offline --bundle evidence.tar.gz --strict
```
### Sample Output
```
Attestation Verification Report
================================
Bundle: evidence.tar.gz
Status: VERIFIED
Checks:
[PASS] DSSE envelope signature valid
[PASS] Merkle inclusion proof verified (log index: 12345)
[PASS] Checkpoint signature valid (origin: rekor.sigstore.dev)
[PASS] Content hash matches manifest
Artifact: sha256:abc123...
Signed by: identity@example.com
Timestamp: 2026-01-14T10:30:00Z
```
### Bundle Format
The attestation bundle should be a tar.gz archive containing:
```
evidence.tar.gz
├── attestation.dsse.json # DSSE envelope with signature
├── manifest.json # File inventory with SHA-256 hashes
├── metadata.json # Generation timestamp, tool versions
├── certs/
│ ├── signing-cert.pem # Signing certificate
│ └── fulcio-root.pem # Fulcio root CA (optional)
└── rekor-proof/ # Transparency log proof (optional)
├── inclusion-proof.json
└── checkpoint.sig
```
### Air-Gap Workflow
1. **Export bundle** on connected system:
```bash
stella evidence export --scan-id <id> --output bundle.tar.gz
```
2. **Transfer bundle** to air-gapped system via secure media.
3. **Verify offline** on air-gapped system:
```bash
stella attest verify-offline --bundle bundle.tar.gz --trust-root /roots/
```
### Cross-Platform Determinism
The verification output is deterministic across platforms:
- Line endings normalized to LF
- Hex digests always lowercase
- Timestamps in ISO 8601 UTC format
- Paths use forward slashes
## CI/CD Integration
### GitHub Actions
```yaml
# .github/workflows/verify-attestation.yml
name: Verify Attestation
on:
workflow_dispatch:
inputs:
artifact_path:
description: 'Path to artifact with attestation'
required: true
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: signed-artifact
path: ./artifacts
- name: Install StellaOps CLI
run: |
dotnet tool install --global StellaOps.Cli
- name: Verify attestation
run: |
stella attest verify \
--envelope ./artifacts/attestation.dsse.json \
--policy ./policy/verify-policy.json \
--root ./keys/trusted-root.pem \
--output ./verification-report.json
- name: Upload verification report
uses: actions/upload-artifact@v4
with:
name: verification-report
path: ./verification-report.json
```
### GitLab CI
```yaml
# .gitlab-ci.yml
verify-attestation:
stage: verify
image: mcr.microsoft.com/dotnet/sdk:10.0
before_script:
- dotnet tool install --global StellaOps.Cli
- export PATH="$PATH:$HOME/.dotnet/tools"
script:
- |
stella attest verify \
--envelope ./artifacts/attestation.dsse.json \
--policy ./policy/verify-policy.json \
--root ./keys/trusted-root.pem \
--output ./verification-report.json
artifacts:
paths:
- verification-report.json
expire_in: 1 week
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
```
## Notes
- No network access required in sealed mode.
- All commands emit deterministic JSON; timestamps in UTC.
- Exit codes: 0 success, 2 verification failed, 4 input error.