Files
git.stella-ops.org/docs/modules/cli/guides/admin/admission-webhook.md

5.6 KiB

Facet Seal Admission Webhook Configuration

Sprint: SPRINT_20260105_002_004_CLI Task: CLI-017 - Admission webhook configuration documentation

Overview

The StellaOps Zastava admission webhook validates facet seals during Kubernetes pod admission. When enabled, it ensures that container images have valid facet seals and that any drift from the baseline is within acceptable quotas.

Prerequisites

  • Kubernetes cluster with admission webhook support
  • StellaOps Zastava webhook deployed
  • Certificate management for webhook TLS
  • Network access from API server to webhook endpoint

Enabling Facet Validation

Facet seal validation is opt-in per namespace using annotations.

Namespace Annotation

Add the following annotation to enable facet validation:

apiVersion: v1
kind: Namespace
metadata:
  name: production
  annotations:
    stellaops.io/facet-seal-required: "true"

Annotation Values

Value Behavior
"true" Facet seal validation enabled
"false" Facet seal validation disabled
(not set) Facet seal validation disabled

Validation Behavior

When facet validation is enabled, the webhook performs these checks:

  1. Seal Lookup: Load the facet seal for the image digest
  2. Signature Verification: Verify the seal's DSSE signature (if present)
  3. Drift Computation: Compare current image state against baseline seal
  4. Quota Evaluation: Check drift against configured quotas

Verdict Outcomes

Verdict Result Description
Ok Allow Drift within quotas
Warning Allow (with warning) Approaching quota limits
Blocked Deny Quota exceeded
RequiresVex Deny Requires VEX authorization

Configuration Options

Webhook Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: zastava-webhook
  namespace: stellaops-system
spec:
  replicas: 3
  selector:
    matchLabels:
      app: zastava-webhook
  template:
    metadata:
      labels:
        app: zastava-webhook
    spec:
      containers:
      - name: webhook
        image: stellaops/zastava-webhook:latest
        ports:
        - containerPort: 8443
        env:
        - name: STELLAOPS_BACKEND_URL
          value: "https://api.stellaops.internal"
        - name: STELLAOPS_FACET_SEAL_STORE
          value: "remote"
        volumeMounts:
        - name: webhook-certs
          mountPath: /etc/webhook/certs
          readOnly: true
      volumes:
      - name: webhook-certs
        secret:
          secretName: zastava-webhook-certs

ValidatingWebhookConfiguration

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: stellaops-facet-admission
webhooks:
- name: facet.admission.stellaops.io
  clientConfig:
    service:
      name: zastava-webhook
      namespace: stellaops-system
      path: /validate
    caBundle: ${CA_BUNDLE}
  rules:
  - operations: ["CREATE", "UPDATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
  namespaceSelector:
    matchExpressions:
    - key: stellaops.io/facet-seal-required
      operator: In
      values: ["true"]
  failurePolicy: Fail
  sideEffects: None
  admissionReviewVersions: ["v1"]

Quota Configuration

Facet drift quotas can be configured per namespace or globally.

Global Quotas (ConfigMap)

apiVersion: v1
kind: ConfigMap
metadata:
  name: stellaops-facet-quotas
  namespace: stellaops-system
data:
  default.yaml: |
    quotas:
      runtime:
        warningThreshold: 10
        blockThreshold: 25
        vexThreshold: 50
      config:
        warningThreshold: 20
        blockThreshold: 40
        vexThreshold: 60
      static:
        warningThreshold: 30
        blockThreshold: 50
        vexThreshold: 75

Per-Namespace Overrides

apiVersion: v1
kind: Namespace
metadata:
  name: staging
  annotations:
    stellaops.io/facet-seal-required: "true"
    stellaops.io/facet-quota-runtime-warn: "20"
    stellaops.io/facet-quota-runtime-block: "50"

Troubleshooting

Common Issues

Seal Not Found

Admission denied: facet.seal.missing
No facet seal found for image sha256:abc123...

Resolution: Ensure the image was sealed before deployment:

stella seal sha256:abc123 --store

Invalid Signature

Admission denied: facet.seal.invalid_signature
Facet seal signature verification failed

Resolution: Verify the seal was signed with a trusted key and the trust roots are configured.

Quota Exceeded

Admission denied: facet.quota.exceeded
Facet quota exceeded: runtime(45.2%)

Resolution: Either:

  1. Re-seal the image with current state
  2. Generate and approve a VEX authorization
  3. Adjust quota thresholds

Debugging

Enable verbose logging:

env:
- name: STELLAOPS_LOG_LEVEL
  value: "Debug"

View webhook logs:

kubectl logs -n stellaops-system -l app=zastava-webhook

Metrics

The webhook exposes Prometheus metrics:

Metric Type Description
stellaops_facet_admission_total Counter Total admission requests
stellaops_facet_admission_allowed Counter Allowed admissions
stellaops_facet_admission_denied Counter Denied admissions
stellaops_facet_drift_percent Histogram Drift percentage distribution
stellaops_facet_validation_duration_seconds Histogram Validation latency