audit work, fixed StellaOps.sln warnings/errors, fixed tests, sprints work, new advisories
This commit is contained in:
267
docs/modules/cli/guides/commands/facet-drift.md
Normal file
267
docs/modules/cli/guides/commands/facet-drift.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# stella drift (Facet Analysis) - Command Guide
|
||||
|
||||
**Sprint:** SPRINT_20260105_002_004_CLI
|
||||
**Task:** CLI-016 - Facet drift command documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The `stella drift` command analyzes facet drift between a baseline seal and the current state of a container image. Unlike reachability drift (which tracks call paths to vulnerable code), facet drift tracks file-level changes within categorized image layers.
|
||||
|
||||
## Commands
|
||||
|
||||
### stella drift
|
||||
|
||||
Analyze facet drift for an image against a baseline seal.
|
||||
|
||||
```bash
|
||||
stella drift <IMAGE> [OPTIONS]
|
||||
```
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Argument | Description |
|
||||
|----------|-------------|
|
||||
| `IMAGE` | Image reference or digest to analyze (required) |
|
||||
|
||||
#### Options
|
||||
|
||||
| Option | Alias | Description | Default |
|
||||
|--------|-------|-------------|---------|
|
||||
| `--baseline <ID>` | `-b` | Baseline seal ID for comparison | latest seal |
|
||||
| `--format <FMT>` | `-f` | Output format: `table`, `json`, `yaml` | `table` |
|
||||
| `--verbose` | `-v` | Show detailed file changes | `false` |
|
||||
| `--fail-on-breach` | | Exit with error code if quota breached | `false` |
|
||||
|
||||
#### Examples
|
||||
|
||||
##### Basic drift analysis
|
||||
|
||||
```bash
|
||||
stella drift sha256:abc123def456...
|
||||
```
|
||||
|
||||
##### With specific baseline
|
||||
|
||||
```bash
|
||||
stella drift myregistry.io/app:v2.0 --baseline seal-xyz789
|
||||
```
|
||||
|
||||
##### JSON output for CI integration
|
||||
|
||||
```bash
|
||||
stella drift sha256:abc123 --format json > drift-report.json
|
||||
```
|
||||
|
||||
##### Fail build on quota breach
|
||||
|
||||
```bash
|
||||
stella drift sha256:abc123 --fail-on-breach
|
||||
```
|
||||
|
||||
##### Verbose output with file details
|
||||
|
||||
```bash
|
||||
stella drift sha256:abc123 --verbose
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Output Formats
|
||||
|
||||
### Table Format (Default)
|
||||
|
||||
```
|
||||
Overall Verdict: Warning
|
||||
Total Changed Files: 15
|
||||
|
||||
+----------+-------+---------+----------+---------+-----------+
|
||||
| Facet | Added | Removed | Modified | Churn % | Verdict |
|
||||
+----------+-------+---------+----------+---------+-----------+
|
||||
| runtime | 2 | 1 | 3 | 12.5% | Warning |
|
||||
| config | 5 | 0 | 2 | 8.2% | Ok |
|
||||
| static | 0 | 2 | 0 | 3.1% | Ok |
|
||||
+----------+-------+---------+----------+---------+-----------+
|
||||
```
|
||||
|
||||
With `--verbose`:
|
||||
|
||||
```
|
||||
File Changes:
|
||||
|
||||
runtime
|
||||
+ /usr/lib/libcrypto.so.3.0.1
|
||||
+ /usr/lib/libssl.so.3.0.1
|
||||
- /usr/lib/libcrypto.so.3.0.0
|
||||
~ /usr/bin/app (sha256:old -> sha256:new)
|
||||
~ /etc/app/config.yaml
|
||||
~ /var/lib/app/data.db
|
||||
```
|
||||
|
||||
### JSON Format
|
||||
|
||||
```json
|
||||
{
|
||||
"imageDigest": "sha256:abc123...",
|
||||
"baselineSealId": "seal-xyz789",
|
||||
"analyzedAt": "2026-01-05T10:30:00Z",
|
||||
"overallVerdict": "warning",
|
||||
"totalChangedFiles": 15,
|
||||
"facetDrifts": [
|
||||
{
|
||||
"facetId": "runtime",
|
||||
"baselineFileCount": 48,
|
||||
"added": [
|
||||
{
|
||||
"path": "/usr/lib/libcrypto.so.3.0.1",
|
||||
"digest": "sha256:new...",
|
||||
"sizeBytes": 3145728,
|
||||
"modifiedAt": null
|
||||
}
|
||||
],
|
||||
"removed": [
|
||||
{
|
||||
"path": "/usr/lib/libcrypto.so.3.0.0",
|
||||
"digest": "sha256:old...",
|
||||
"sizeBytes": 3145600,
|
||||
"modifiedAt": null
|
||||
}
|
||||
],
|
||||
"modified": [
|
||||
{
|
||||
"path": "/usr/bin/app",
|
||||
"previousDigest": "sha256:prev...",
|
||||
"currentDigest": "sha256:curr...",
|
||||
"previousSizeBytes": 15728640,
|
||||
"currentSizeBytes": 15730000
|
||||
}
|
||||
],
|
||||
"driftScore": 25.5,
|
||||
"churnPercent": 12.5,
|
||||
"quotaVerdict": "warning"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### YAML Format
|
||||
|
||||
```yaml
|
||||
imageDigest: sha256:abc123...
|
||||
baselineSealId: seal-xyz789
|
||||
overallVerdict: warning
|
||||
totalChangedFiles: 15
|
||||
facetDrifts:
|
||||
- facetId: runtime
|
||||
added: 2
|
||||
removed: 1
|
||||
modified: 3
|
||||
churnPercent: 12.50
|
||||
verdict: warning
|
||||
- facetId: config
|
||||
added: 5
|
||||
removed: 0
|
||||
modified: 2
|
||||
churnPercent: 8.20
|
||||
verdict: ok
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quota Verdicts
|
||||
|
||||
| Verdict | Description | Exit Code |
|
||||
|---------|-------------|-----------|
|
||||
| `Ok` | Drift within acceptable limits | 0 |
|
||||
| `Warning` | Approaching quota limits | 0 |
|
||||
| `Blocked` | Quota exceeded, deployment should be blocked | 2 |
|
||||
| `RequiresVex` | Significant drift, requires VEX authorization | 2 |
|
||||
|
||||
## Exit Codes
|
||||
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| `0` | Success (no breach, or breach without `--fail-on-breach`) |
|
||||
| `1` | Error (no baseline seal, image not found, etc.) |
|
||||
| `2` | Quota breached (with `--fail-on-breach`) |
|
||||
|
||||
---
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
- name: Check Facet Drift
|
||||
run: |
|
||||
stella drift ${{ env.IMAGE_DIGEST }} \
|
||||
--format json \
|
||||
--fail-on-breach > drift.json
|
||||
continue-on-error: true
|
||||
id: drift-check
|
||||
|
||||
- name: Upload Drift Report
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: facet-drift-report
|
||||
path: drift.json
|
||||
|
||||
- name: Generate VEX if needed
|
||||
if: failure() && steps.drift-check.outcome == 'failure'
|
||||
run: |
|
||||
stella vex gen --from-drift \
|
||||
--image ${{ env.IMAGE_DIGEST }} \
|
||||
--output vex-request.json
|
||||
```
|
||||
|
||||
### GitLab CI
|
||||
|
||||
```yaml
|
||||
facet-drift-check:
|
||||
script:
|
||||
- stella drift $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --fail-on-breach --format json > drift.json
|
||||
artifacts:
|
||||
paths:
|
||||
- drift.json
|
||||
reports:
|
||||
codequality: drift.json
|
||||
allow_failure: true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow: Handling Drift Breaches
|
||||
|
||||
When drift exceeds quotas:
|
||||
|
||||
1. **Review the drift report**
|
||||
```bash
|
||||
stella drift sha256:abc123 --verbose
|
||||
```
|
||||
|
||||
2. **Determine if changes are intentional**
|
||||
- Legitimate updates: Generate VEX authorization
|
||||
- Unexpected changes: Investigate and remediate
|
||||
|
||||
3. **For intentional changes, generate VEX**
|
||||
```bash
|
||||
stella vex gen --from-drift --image sha256:abc123 --output vex.json
|
||||
```
|
||||
|
||||
4. **Review and sign the VEX**
|
||||
```bash
|
||||
stella vex sign --input vex.json --key /path/to/key
|
||||
```
|
||||
|
||||
5. **Or re-seal to establish new baseline**
|
||||
```bash
|
||||
stella seal sha256:abc123 --store
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Facet Seal Command](./seal.md)
|
||||
- [VEX Generation from Drift](./vex.md#stella-vex-gen---from-drift)
|
||||
- [Reachability Drift (different concept)](./drift.md)
|
||||
- [Admission Webhook Configuration](../admin/admission-webhook.md)
|
||||
204
docs/modules/cli/guides/commands/seal.md
Normal file
204
docs/modules/cli/guides/commands/seal.md
Normal file
@@ -0,0 +1,204 @@
|
||||
# stella seal - Command Guide
|
||||
|
||||
**Sprint:** SPRINT_20260105_002_004_CLI
|
||||
**Task:** CLI-016 - Facet seal command documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The `stella seal` command creates cryptographic seals for container image facets. A facet seal captures the state of specific file categories (binaries, libraries, configs, etc.) within an image and produces Merkle roots for tamper detection and drift analysis.
|
||||
|
||||
## Commands
|
||||
|
||||
### stella seal
|
||||
|
||||
Create a facet seal for an image.
|
||||
|
||||
```bash
|
||||
stella seal <IMAGE> [OPTIONS]
|
||||
```
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Argument | Description |
|
||||
|----------|-------------|
|
||||
| `IMAGE` | Image reference or digest to seal (required) |
|
||||
|
||||
#### Options
|
||||
|
||||
| Option | Alias | Description | Default |
|
||||
|--------|-------|-------------|---------|
|
||||
| `--output <PATH>` | `-o` | Output file path for seal | stdout |
|
||||
| `--store` | `-s` | Store seal in remote API | `true` |
|
||||
| `--sign` | | Sign seal with DSSE | `true` |
|
||||
| `--key <PATH>` | `-k` | Private key path for signing | configured key |
|
||||
| `--facets <LIST>` | `-f` | Specific facets to seal (comma-separated) | all |
|
||||
| `--format <FMT>` | | Output format: `json`, `yaml`, `compact` | `json` |
|
||||
| `--verbose` | `-v` | Enable verbose output | `false` |
|
||||
|
||||
#### Examples
|
||||
|
||||
##### Seal all facets
|
||||
|
||||
```bash
|
||||
stella seal sha256:abc123def456...
|
||||
```
|
||||
|
||||
##### Seal specific facets
|
||||
|
||||
```bash
|
||||
stella seal myregistry.io/app:v1.0 --facets runtime,config
|
||||
```
|
||||
|
||||
##### Output to file
|
||||
|
||||
```bash
|
||||
stella seal myregistry.io/app:v1.0 --output seal.json
|
||||
```
|
||||
|
||||
##### Seal without storing remotely
|
||||
|
||||
```bash
|
||||
stella seal sha256:abc123 --no-store --output local-seal.json
|
||||
```
|
||||
|
||||
##### Seal with custom signing key
|
||||
|
||||
```bash
|
||||
stella seal sha256:abc123 --key /path/to/private.key
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Built-in Facets
|
||||
|
||||
| Facet ID | Name | Description | File Patterns |
|
||||
|----------|------|-------------|---------------|
|
||||
| `runtime` | Runtime Binaries | Executable binaries and shared libraries | `*.so`, `*.dll`, `/usr/bin/*` |
|
||||
| `config` | Configuration | Configuration files | `*.conf`, `*.yaml`, `*.json`, `/etc/*` |
|
||||
| `static` | Static Assets | Static web assets | `*.css`, `*.js`, `*.html` |
|
||||
| `scripts` | Scripts | Script files | `*.sh`, `*.py`, `*.rb` |
|
||||
| `data` | Data Files | Data and cache files | `*.db`, `*.sqlite`, `/var/lib/*` |
|
||||
|
||||
---
|
||||
|
||||
## Output Formats
|
||||
|
||||
### JSON Format (Default)
|
||||
|
||||
```json
|
||||
{
|
||||
"imageDigest": "sha256:abc123...",
|
||||
"createdAt": "2026-01-05T10:30:00Z",
|
||||
"combinedMerkleRoot": "sha256:combined...",
|
||||
"facets": [
|
||||
{
|
||||
"facetId": "runtime",
|
||||
"name": "Runtime Binaries",
|
||||
"merkleRoot": "sha256:facet...",
|
||||
"fileCount": 42,
|
||||
"totalBytes": 15728640
|
||||
}
|
||||
],
|
||||
"signature": {
|
||||
"payloadType": "application/vnd.stellaops.facetseal+json",
|
||||
"signatures": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### YAML Format
|
||||
|
||||
```yaml
|
||||
imageDigest: sha256:abc123...
|
||||
createdAt: 2026-01-05T10:30:00Z
|
||||
combinedMerkleRoot: sha256:combined...
|
||||
facets:
|
||||
- facetId: runtime
|
||||
merkleRoot: sha256:facet...
|
||||
fileCount: 42
|
||||
```
|
||||
|
||||
### Compact Format
|
||||
|
||||
Single-line format for scripting:
|
||||
|
||||
```
|
||||
sha256:abc123...|sha256:combined...|5
|
||||
```
|
||||
|
||||
Format: `imageDigest|combinedRoot|facetCount`
|
||||
|
||||
---
|
||||
|
||||
## Exit Codes
|
||||
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| `0` | Success |
|
||||
| `1` | General error |
|
||||
| `2` | Image resolution failed |
|
||||
| `3` | Signing failed |
|
||||
| `4` | Storage failed |
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `STELLAOPS_BACKEND_URL` | Backend API URL for seal storage |
|
||||
| `STELLAOPS_SIGNING_KEY` | Default signing key path |
|
||||
| `STELLAOPS_TRUST_ROOTS` | Trust roots for verification |
|
||||
|
||||
---
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
- name: Seal Container Image
|
||||
run: |
|
||||
stella seal ${{ env.IMAGE_DIGEST }} \
|
||||
--output seal.json \
|
||||
--store
|
||||
|
||||
- name: Upload Seal Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: facet-seal
|
||||
path: seal.json
|
||||
```
|
||||
|
||||
### GitLab CI
|
||||
|
||||
```yaml
|
||||
seal-image:
|
||||
script:
|
||||
- stella seal $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --output seal.json
|
||||
artifacts:
|
||||
paths:
|
||||
- seal.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Admission Integration
|
||||
|
||||
When Kubernetes admission is configured with facet seal validation, the webhook will:
|
||||
|
||||
1. Check if namespace has `stellaops.io/facet-seal-required=true` annotation
|
||||
2. Load the seal for the image being deployed
|
||||
3. Verify the seal signature
|
||||
4. Compute drift against current image state
|
||||
5. Admit/reject based on quota verdicts
|
||||
|
||||
See [Admission Webhook Configuration](../admin/admission-webhook.md) for setup details.
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Facet Drift Analysis](./facet-drift.md)
|
||||
- [VEX Generation from Drift](./vex.md#stella-vex-gen---from-drift)
|
||||
- [Admission Webhook](../admin/admission-webhook.md)
|
||||
@@ -1,9 +1,11 @@
|
||||
# stella vex — Command Guide
|
||||
# stella vex - Command Guide
|
||||
|
||||
## Commands
|
||||
|
||||
- `stella vex consensus --query <filter> [--output json|ndjson|table] [--offline]`
|
||||
- `stella vex get --id <consensusId> [--offline]`
|
||||
- `stella vex simulate --input <vexDocs> --policy <policyConfig> [--offline]`
|
||||
- `stella vex gen --from-drift --image <IMAGE> [--baseline <SEAL_ID>] [--output <PATH>]`
|
||||
|
||||
## Flags (common)
|
||||
- `--offline`: use cached consensus snapshots; fail with exit code 5 if remote would be hit.
|
||||
@@ -21,3 +23,126 @@
|
||||
## Offline/air-gap notes
|
||||
- Cached snapshots are required when `--offline`; otherwise exit code 5 with remediation message.
|
||||
- Trust roots for signature verification are loaded from `STELLA_TRUST_ROOTS` when verifying cached snapshots.
|
||||
|
||||
---
|
||||
|
||||
## stella vex gen --from-drift
|
||||
|
||||
**Sprint:** SPRINT_20260105_002_004_CLI
|
||||
|
||||
Generate VEX statements from facet drift analysis. This command analyzes drift between a baseline seal and the current image state, then generates OpenVEX documents for facets that require authorization.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
stella vex gen --from-drift --image <IMAGE> [OPTIONS]
|
||||
```
|
||||
|
||||
### Required Options
|
||||
|
||||
| Option | Alias | Description |
|
||||
|--------|-------|-------------|
|
||||
| `--from-drift` | | Enable drift-based VEX generation |
|
||||
| `--image <REF>` | `-i` | Image reference or digest to analyze |
|
||||
|
||||
### Optional Options
|
||||
|
||||
| Option | Alias | Description | Default |
|
||||
|--------|-------|-------------|---------|
|
||||
| `--baseline <ID>` | `-b` | Baseline seal ID for comparison | latest seal |
|
||||
| `--output <PATH>` | `-o` | Output file path | stdout |
|
||||
| `--format <FMT>` | `-f` | VEX format: `openvex`, `csaf` | `openvex` |
|
||||
| `--status <STATUS>` | `-s` | VEX status: `under_investigation`, `not_affected`, `affected` | `under_investigation` |
|
||||
| `--verbose` | `-v` | Enable verbose output | `false` |
|
||||
|
||||
### Examples
|
||||
|
||||
#### Generate VEX from drift
|
||||
|
||||
```bash
|
||||
stella vex gen --from-drift --image sha256:abc123
|
||||
```
|
||||
|
||||
#### Specify baseline seal
|
||||
|
||||
```bash
|
||||
stella vex gen --from-drift --image myregistry.io/app:v2.0 --baseline seal-xyz789
|
||||
```
|
||||
|
||||
#### Output to file with specific status
|
||||
|
||||
```bash
|
||||
stella vex gen --from-drift --image sha256:abc123 \
|
||||
--output vex-authorization.json \
|
||||
--status not_affected
|
||||
```
|
||||
|
||||
### Output Format (OpenVEX)
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://openvex.dev/ns",
|
||||
"@id": "https://stellaops.io/vex/abc123-def456",
|
||||
"author": "StellaOps CLI",
|
||||
"timestamp": "2026-01-05T10:30:00Z",
|
||||
"version": 1,
|
||||
"statements": [
|
||||
{
|
||||
"@id": "vex:statement-1",
|
||||
"status": "under_investigation",
|
||||
"timestamp": "2026-01-05T10:30:00Z",
|
||||
"products": [
|
||||
{
|
||||
"@id": "sha256:abc123...",
|
||||
"identifiers": {
|
||||
"facet": "runtime"
|
||||
}
|
||||
}
|
||||
],
|
||||
"justification": "Facet drift authorization for runtime. Churn: 15.50% (3 added, 1 removed, 2 modified)",
|
||||
"action_statement": "Review required before deployment"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Exit Codes
|
||||
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| `0` | Success |
|
||||
| `1` | Error or no baseline seal found |
|
||||
| `2` | Image resolution failed |
|
||||
|
||||
### Workflow Integration
|
||||
|
||||
The `vex gen --from-drift` command is typically used in a deployment pipeline:
|
||||
|
||||
1. **Build**: Container image is built
|
||||
2. **Seal**: `stella seal` creates baseline seal at build time
|
||||
3. **Deploy**: Deployment triggers admission webhook
|
||||
4. **Drift Detection**: If drift exceeds quota, deployment is blocked
|
||||
5. **VEX Generation**: `stella vex gen --from-drift` creates authorization document
|
||||
6. **Review**: Security team reviews and signs VEX
|
||||
7. **Retry Deploy**: With VEX in place, deployment proceeds
|
||||
|
||||
```bash
|
||||
# After deployment blocked due to drift
|
||||
stella vex gen --from-drift --image $IMAGE_DIGEST \
|
||||
--output vex-authorization.json
|
||||
|
||||
# Review and sign the VEX document
|
||||
stella vex sign --input vex-authorization.json --key $SIGNING_KEY
|
||||
|
||||
# Ingest the signed VEX
|
||||
stella vex ingest --input vex-authorization.signed.json
|
||||
|
||||
# Retry deployment (webhook will now accept)
|
||||
kubectl apply -f deployment.yaml
|
||||
```
|
||||
|
||||
### Related Documentation
|
||||
|
||||
- [Facet Seal Command](./seal.md)
|
||||
- [Facet Drift Analysis](./facet-drift.md)
|
||||
- [Admission Webhook Configuration](../admin/admission-webhook.md)
|
||||
|
||||
Reference in New Issue
Block a user