Helm chart¶
The xila-guard chart deploys the observer and a bundled core evaluator
in-cluster, installs the guard.xila.us CRDs and RBAC, and — behind opt-in flags
— the enforcement scheduler + webhook, SPIRE-based collector identity, and
orchestrator integrations. With every opt-in flag off, helm template is
byte-identical to the observe-only baseline.
Container images (built from source)¶
Each component has a multi-stage Dockerfile that builds from source into a minimal, non-root (uid 65532), read-only-rootfs image.
| Image | Source | Base |
|---|---|---|
xila-guard-server |
xila-guard-core |
distroless/cc (≈ 29.5 MB) |
xila-guard-controller |
xila-guard-k8s (COMPONENT=controller) |
distroless/static (≈ 44 MB) |
xila-guard-scheduler |
xila-guard-k8s (COMPONENT=scheduler) |
distroless/static (≈ 75 MB) |
xila-guard-webhook |
xila-guard-k8s (COMPONENT=webhook) |
distroless/static (≈ 41 MB) |
The one-command end-to-end path that builds all images, loads them into a kind
cluster, installs the chart, and exercises observe + enforcement is
xila-guard-lab's make demo-incluster.
Core values¶
| Key | Default | Description |
|---|---|---|
installCRDs |
true |
Render the guard.xila.us CRDs with the release |
namespace |
xila-guard-system |
Namespace for the workloads |
mode |
observe |
Operating mode; only observe is implemented (chart fails otherwise) |
coreServer.enabled |
true |
Deploy the bundled core evaluator |
coreServer.service.port |
8080 |
Core service port |
serviceAccount.create / rbac.create |
true |
Create SA / ClusterRole + binding |
controller.replicas |
1 |
Observer replicas; >1 enables leader election + lease RBAC |
Enforcement values (opt-in)¶
| Key | Default | Description |
|---|---|---|
enforcement.enabled |
false |
Render the scheduler + fail-closed webhook + RBAC |
enforcement.scheduler.replicas |
1 |
>1 enables scheduler leader election |
enforcement.scheduler.acceptMock |
false |
Production rejects mock; true = lab-simulated profile |
enforcement.webhook.tls.caBundle |
— | Base64 CA for the webhook ValidatingWebhookConfiguration |
enforcement.webhook.certManager.enabled |
false |
Issue + rotate the webhook cert via cert-manager (Certificate + inject-ca-from) instead of a manual caBundle |
helm upgrade xila-guard charts/xila-guard -n xila-guard-system \
--set enforcement.enabled=true \
--set enforcement.webhook.tls.caBundle="$(base64 -w0 < ca.crt)"
See enforcement for behavior and the fail-closed matrix.
Identity values (opt-in SPIRE)¶
| Key | Default | Description |
|---|---|---|
identity.enabled |
false |
Opt-in SPIRE collector identity; nothing renders when off |
identity.spire.install |
true |
Render bundled SPIRE infra; false = BYO SPIRE (consumers only) |
identity.spire.trustDomain |
xila.us |
Trust domain the SVIDs are issued under |
identity.spire.csiDriverName |
csi.spiffe.io |
SPIFFE CSI driver the consumer pods mount |
identity.inventory.port |
8443 |
HTTPS port of the inventory receiver |
identity.collector.intervalSecs |
10 |
Collector re-POST interval (re-POST = 409 replay) |
identity.spiffeHelper.daemon |
true |
spiffe-helper as a rotating sidecar; false = one-shot init (no rotation) |
identity.observer.useAuthenticatedInventory |
false |
Give the observer an SVID + mTLS client to call evaluate-node |
identity.observer.mode |
require |
prefer (fall back to NodeSecurityState) or require (fail-closed) |
See identity for the SPIRE wiring and BYO-SPIRE setup.
Orchestrator integrations (opt-in, default empty)¶
orchestratorIntegrations is a modular, default-empty list that co-registers
Xila Guard's fail-closed admission boundary with a third-party GPU
orchestrator / scheduler without modifying, rebuilding, or importing it. Each
entry is a profile — pure data: an external schedulerName plus a
workloadSelector.
| Key | Default | Description |
|---|---|---|
orchestratorIntegrations |
[] |
Opt-in list of profiles; empty renders nothing (byte-identical to baseline) |
orchestratorIntegrations[].name |
— | DNS-safe id; names the rendered <fullname>-<name> ValidatingWebhookConfiguration |
orchestratorIntegrations[].schedulerName |
— | Scheduler the orchestrator sets on its pods (union → webhook --external-schedulers) |
orchestratorIntegrations[].workloadSelector |
— | Standard LabelSelector selecting the orchestrator's pods (webhook objectSelector) |
orchestratorIntegrations[].failurePolicy |
Fail |
Per-profile admission failure policy |
orchestratorIntegrations[].namespaceSelector |
none | Optional LabelSelector scoping the profile webhook |
orchestratorIntegrations:
- name: runai
schedulerName: runai-scheduler
failurePolicy: Fail
workloadSelector:
matchExpressions:
- { key: run.ai/application, operator: Exists }
If enforcement.enabled=false, the chart still renders the minimal webhook
these integrations need (ServiceAccount + read-only RBAC + Deployment + Service +
TLS) — not the controlled scheduler. See
orchestrators.
Security notes¶
- Default mode is observe: no scheduling changes, no GPU selection, no eviction.
- Enforcement, in the lab, is simulated over
mock(acceptMock=true) — never real GPU isolation or attestation. The production profile rejectsmock. - Pods run as non-root (uid 65532), read-only root filesystem, all capabilities
dropped,
seccompProfile: RuntimeDefault. - The core service is cluster-internal; exposing the evaluator beyond the cluster would additionally require TLS, caller authentication, and restricted network access (not configured by the chart).
- The webhook uses
failurePolicy: Failscoped to protected namespaces, so an unavailable webhook blocks protected Pods rather than silently admitting them.
Before any real publication
Chart images are dev-tagged and built from source; they are not published
and not digest-pinned. Generate an SBOM and scan licenses / vulnerabilities
(syft, grype) and pin images by digest before a real release. This is not
performed automatically. See supply-chain ADR.