Files
git.stella-ops.org/docs/operations/facet-quota-configuration.md

6.4 KiB

Facet Quota Configuration Guide

Version: 1.0.0
Sprint: SPRINT_20260105_002_003_FACET
Last Updated: 2026-01-07

This guide covers configuration and operation of per-facet drift quotas in StellaOps.


Overview

Facet quotas control how much change is acceptable in different parts of a container image between builds. When drift exceeds a quota, StellaOps can:

  • Warn: Log and report the drift, continue processing
  • Block: Fail the policy gate, prevent deployment
  • Auto-VEX: Generate a VEX draft for human review

What are Facets?

Facets are logical groupings of files in a container image:

Facet Description Typical Files
binaries Executables and libraries *.so, *.dll, ELF files
lang-deps Language package dependencies node_modules/, site-packages/, .m2/
os-packages OS-level packages RPM, DEB, APK metadata
configs Configuration files *.conf, *.yaml, *.json
data Static data files Images, fonts, templates

Why Per-Facet Quotas?

Different file types have different risk profiles:

  • A single binary change might be intentional (rebuild) or might indicate compromise
  • 100 new npm packages might be a normal dependency update
  • Removing OS security packages is always suspicious

Per-facet quotas let you apply appropriate controls to each category.


Configuration

File Location

/etc/stellaops/facet-quotas.yaml

Or via environment variable:

STELLAOPS_FACET_QUOTAS_PATH=/path/to/facet-quotas.yaml

Basic Structure

# Default quota for all facets
defaults:
  maxChurnPercent: 30       # Max % of files that can change
  maxChangedFiles: 100      # Max absolute changed files
  maxAddedFiles: 50         # Max new files
  maxRemovedFiles: 50       # Max removed files
  action: warn              # warn | block | auto-vex

# Per-facet overrides
facets:
  binaries:
    maxChurnPercent: 10
    action: block
  lang-deps:
    maxChurnPercent: 40
    action: auto-vex

Quota Parameters

Parameter Type Description
maxChurnPercent decimal Maximum percentage of files in the facet that can change
maxChangedFiles int Maximum absolute number of changed files
maxAddedFiles int Maximum number of new files (optional)
maxRemovedFiles int Maximum number of removed files (optional)
action string Action when quota exceeded: warn, block, auto-vex
allowlist list Glob patterns to exclude from quota calculation

Using Profiles

StellaOps includes predefined quota profiles:

# Use a predefined profile
profile: moderate  # strict | moderate | permissive

# Optionally override specific facets
facets:
  binaries:
    action: block  # Override from profile
Profile Description Use Case
strict Minimal tolerance, blocks most drift Production, regulated
moderate Balanced, auto-VEX for review Staging, pre-prod
permissive Relaxed, warnings only Development

Policy Integration

Enabling Quota Gates

In your policy configuration:

# policy-gates.yaml
gates:
  - name: facet-quota
    enabled: true
    options:
      configPath: /etc/stellaops/facet-quotas.yaml
      failOnMissingSeal: true  # Fail if no baseline seal exists

Seal Management

Quotas compare current state against a "sealed" baseline:

# Seal current image as baseline
stella facet seal --image myapp:v1.2.3 --tenant production

# List seals
stella facet seals list --tenant production

# Compare against seal
stella facet drift --image myapp:v1.2.4 --baseline v1.2.3

Auto-VEX Workflow

When quota action is auto-vex, StellaOps:

  1. Generates a VEX draft with drift justification
  2. Queues the draft for human review
  3. Sends notifications to configured channels

VEX Draft Structure

{
  "statements": [{
    "vulnerability": "FACET-DRIFT-2026-001234",
    "status": "under_investigation",
    "justification": "facet_drift_detected",
    "impact_statement": "Drift in 'binaries' facet: 15% churn (quota: 10%), 12 files changed"
  }]
}

Approving VEX Drafts

# List pending drafts
stella vex drafts list --status pending

# Approve a draft
stella vex draft approve --id <draft-id> --reason "Expected rebuild"

# Reject a draft
stella vex draft reject --id <draft-id> --reason "Unexpected changes"

Monitoring

Metrics

Metric Description
facet_drift_evaluations_total Total drift evaluations
facet_quota_exceeded_total Quota breaches by facet and action
facet_vex_drafts_created_total Auto-VEX drafts generated
facet_seal_operations_total Seal create/update operations

Grafana Dashboard

Import the facet quota dashboard:

devops/observability/grafana/facet-quota-metrics.json

Alerts

Key alerts to configure:

  • FacetQuotaBlockRate: High rate of blocked builds
  • FacetDriftAnomalous: Unusual drift patterns
  • FacetVexDraftBacklog: Growing VEX draft queue

Troubleshooting

Quota Unexpectedly Blocking

  1. Check current quota configuration:

    stella facet quota show --facet binaries
    
  2. Review drift details:

    stella facet drift --image myapp:latest --verbose
    
  3. Check allowlist patterns:

    stella facet quota test-allowlist --pattern "**/__pycache__/**"
    

Missing Baseline Seal

# Create initial seal
stella facet seal --image myapp:v1.0.0 --tenant production

# Or skip quota check for first build
stella scan --image myapp:v1.0.0 --skip-facet-quota

VEX Draft Not Generated

  1. Verify action is auto-vex not warn:

    facets:
      binaries:
        action: auto-vex  # Not 'warn'
    
  2. Check VEX emitter is enabled:

    stella config get excititor.vex.facetDriftEnabled
    

Best Practices

  1. Start with moderate profile in staging, tune based on observations
  2. Use strict for production with explicit allowlists
  3. Review auto-VEX drafts daily to prevent backlog
  4. Seal after each release to establish new baseline
  5. Monitor quota metrics to detect configuration drift

Revision History

Version Date Author Changes
1.0.0 2026-01-07 Agent Initial release