audit work, fixed StellaOps.sln warnings/errors, fixed tests, sprints work, new advisories
This commit is contained in:
242
docs/modules/cli/guides/admin/admission-webhook.md
Normal file
242
docs/modules/cli/guides/admin/admission-webhook.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# 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:
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```yaml
|
||||
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)
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```yaml
|
||||
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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```yaml
|
||||
env:
|
||||
- name: STELLAOPS_LOG_LEVEL
|
||||
value: "Debug"
|
||||
```
|
||||
|
||||
View webhook logs:
|
||||
|
||||
```bash
|
||||
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 |
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [stella seal Command](../commands/seal.md)
|
||||
- [stella vex gen --from-drift](../commands/vex.md#stella-vex-gen---from-drift)
|
||||
- [Facet Drift Analysis](../commands/facet-drift.md)
|
||||
Reference in New Issue
Block a user