stella drift (Facet Analysis) - Command Guide

Audience: release engineers and security reviewers who gate deployments on file-level change between a sealed baseline image and a candidate build.

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 the call paths to vulnerable code, facet drift tracks file-level changes within categorized image layers (runtime, config, static, and so on) and grades each facet against its quota.

Two kinds of drift. This guide covers facet drift. For reachability drift — changes in how vulnerable code can be reached between scans — see stella drift (Reachability).

Commands

stella drift

Analyze facet drift for an image against a baseline seal.

stella drift <IMAGE> [OPTIONS]

Arguments

ArgumentDescription
IMAGEImage reference or digest to analyze (required)

Options

OptionAliasDescriptionDefault
--baseline <ID>-bBaseline seal ID for comparisonlatest seal
--format <FMT>-fOutput format: table, json, yamltable
--verbose-vShow detailed file changesfalse
--fail-on-breachExit with error code if quota breachedfalse

Examples

Basic drift analysis
stella drift sha256:abc123def456...
With specific baseline
stella drift myregistry.io/app:v2.0 --baseline seal-xyz789
JSON output for CI integration
stella drift sha256:abc123 --format json > drift-report.json
Fail build on quota breach
stella drift sha256:abc123 --fail-on-breach
Verbose output with file details
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

{
  "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

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

VerdictDescriptionExit Code
OkDrift within acceptable limits0
WarningApproaching quota limits0
BlockedQuota exceeded, deployment should be blocked2
RequiresVexSignificant drift, requires VEX authorization2

Exit Codes

CodeDescription
0Success (no breach, or breach without --fail-on-breach)
1Error (no baseline seal, image not found, etc.)
2Quota breached (with --fail-on-breach)

CI/CD Integration

GitHub Actions

- 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

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

    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

    stella vex gen --from-drift --image sha256:abc123 --output vex.json
    
  4. Review and sign the VEX

    stella vex sign --input vex.json --key /path/to/key
    
  5. Or re-seal to establish new baseline

    stella seal sha256:abc123 --store