Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
name: CI & Compliance Validation Workflow

on:
push:
branches: [ main, "feat/**", "fix/**", "feature/**" ]
pull_request:
branches: [ main ]

env:
LULA_VERSION: v0.8.0

jobs:
static-checks:
name: Lint, Static Checks & Shift-Left Gates
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install Python Dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install pyyaml ruff

- name: Install Defense Unicorns Lula CLI
run: |
curl -sSL "https://github.com/defenseunicorns-labs/lula1/releases/download/${LULA_VERSION}/lula_${LULA_VERSION}_Linux_amd64" -o /usr/local/bin/lula
chmod +x /usr/local/bin/lula
lula version

- name: Validate OSCAL Component & Assessment Models with Lula CLI
run: |
lula tools lint -f docs/compliance/oscal-il5.yaml,docs/compliance/assessment-results.yaml

- name: Lint Shell Scripts with ShellCheck
run: |
shellcheck scripts/*.sh

- name: Lint & Compile Python Modules
run: |
python3 -m py_compile scripts/*.py tests/*.py
ruff check --select E,F,W --ignore E501 scripts/ tests/

- name: Validate Zarf, UDS Bundle, K8s Manifests & OSCAL Schema
run: |
python3 -c '
import pathlib, yaml
for pattern in ["bundles/*.yaml", "packages/**/*.yaml", "docs/compliance/*.yaml"]:
for path in sorted(pathlib.Path(".").glob(pattern)):
docs = list(yaml.safe_load_all(path.read_text()))
assert len(docs) > 0, f"Empty YAML file: {path}"
print(f"Validated YAML: {path} ({len(docs)} document(s))")
'

- name: Run Automated Unit & Shift-Left IL5 Compliance Tests
run: |
make test
make drill-list > /dev/null
make drill-cheatsheet > /dev/null

- name: Run Gitleaks Secret Scanner
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

runtime-compliance:
name: Ephemeral KinD Runtime Lula Compliance Gate
runs-on: ubuntu-latest
needs: [ static-checks ]

steps:
- name: Checkout Repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install PyYAML
run: python3 -m pip install pyyaml

- name: Set up KinD Cluster
uses: helm/kind-action@v1.12.0
with:
cluster_name: kind-lula-ci
wait: 120s

- name: Install Defense Unicorns Lula CLI
run: |
curl -sSL "https://github.com/defenseunicorns-labs/lula1/releases/download/${LULA_VERSION}/lula_${LULA_VERSION}_Linux_amd64" -o /usr/local/bin/lula
chmod +x /usr/local/bin/lula
lula version

- name: Deploy Training App Workloads to Ephemeral Cluster
run: |
kubectl apply -f packages/training-app/manifests/namespace.yaml
kubectl apply -f packages/training-app/manifests/
# Wait up to 60s for order-api deployment availability
kubectl rollout status deployment/order-api -n training-app --timeout=60s || true
kubectl get all,netpol -n training-app

- name: Execute Live Lula DoD IL5 Runtime Validation
run: |
lula validate -f docs/compliance/oscal-il5.yaml -o /tmp/lula-runtime-assessment.yaml

- name: Evaluate OSCAL Compliance Controls Against IL5 Baseline
run: |
python3 -c '
import yaml, sys
data = yaml.safe_load(open("/tmp/lula-runtime-assessment.yaml"))
results = data.get("assessment-results", {}).get("results", [])
if not results:
print("Error: No assessment results generated by Lula!", file=sys.stderr)
sys.exit(1)

failed = []
for res in results:
for finding in res.get("findings", []):
target_id = finding.get("target", {}).get("target-id", "unknown")
state = finding.get("target", {}).get("status", {}).get("state", "unknown")
if state != "satisfied":
failed.append((target_id, state))

if failed:
print(f"❌ COMPLIANCE REGRESSION: Unsatisfied Lula controls: {failed}", file=sys.stderr)
sys.exit(1)

print("✅ All NIST SP 800-53 Rev 5 Lula controls are SATISFIED at runtime!")
'

- name: Upload OSCAL Assessment Results Artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: oscal-runtime-assessment-results
path: /tmp/lula-runtime-assessment.yaml
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ drill-verify: ## Observe live symptoms of a scenario (Usage: make drill-verify S
drill-heal: ## Heal a scenario or all scenarios (Usage: make drill-heal SCENARIO=<id|all>)
@python3 scripts/drill_manager.py --heal "$(SCENARIO)"

.PHONY: lint
lint: ## Lint shell scripts, Python modules, and Zarf/UDS/OSCAL YAML manifests
@shellcheck scripts/*.sh
@python3 -m py_compile scripts/*.py tests/*.py
@python3 -c 'import pathlib, yaml; [list(yaml.safe_load_all(p.read_text())) for pat in ("bundles/*.yaml", "packages/**/*.yaml", "docs/compliance/*.yaml", ".github/workflows/*.yml") for p in sorted(pathlib.Path(".").glob(pat))]'
@PATH="$$HOME/.local/bin:$$HOME/Projects/uds-platform-prep/payloads/bin:$$PATH"; \
if command -v lula >/dev/null 2>&1; then \
lula tools lint -f docs/compliance/oscal-il5.yaml,docs/compliance/assessment-results.yaml; \
fi
@echo "✓ All shell scripts, Python modules, and Lula OSCAL / YAML manifests passed lint checks."

.PHONY: test
test: ## Run automated unit and schema tests for the drill engine and OSCAL rules
@python3 -m unittest discover -v -s tests
50 changes: 42 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,28 @@ For the architectural rationale, see [ADR 0001: Separation of Environment Infras

```
uds-bundle-dev-test/
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions CI: Lula lint, KinD runtime gate, unit tests, Gitleaks
├── bundles/ # Top-level UDS bundle definitions
│ ├── uds-bundle.yaml # Bundle orchestrating Zarf packages & dependencies
│ └── zarf.yaml # Demo / local package definition
├── packages/ # Modular Zarf packages (argocd, monitoring, training-app)
├── scripts/ # Build, compliance, and chaos/tutor automation
│ ├── common.py # KUBECONFIG discovery & terminal utilities
│ ├── common.py # KUBECONFIG discovery, SSH tunnel auto-recovery & runner
│ ├── drill_manager.py # Interactive CLI Tutor & Chaos Injection Engine
│ ├── build-bundle.sh # Builds Zarf packages and creates .tar.zst bundle
│ ├── test-deploy.sh # Deploys the compiled UDS bundle to target cluster
│ ├── test-compliance.sh # Runs Lula OSCAL IL5 compliance validation
│ └── verify-airgap.sh # Audits network isolation / zero egress
│ └── verify-airgap.sh # Audits network isolation / zero egress (auto-delegates via SSH)
├── docs/ # Architecture decision records, OSCAL, & drill runbooks
│ ├── adr/ # Architectural Decision Records (0001–0003)
│ ├── compliance/oscal-il5.yaml # NIST SP 800-53 Rev 5 Lula OSCAL component definition
│ └── troubleshooting-drills/ # 4-Phase CLI Diagnostic Runbooks
├── tests/ # Automated unit & schema test suite
│ ├── compliance/ # NIST SP 800-53 Rev 5 OSCAL 1.1.2 component & assessment
│ │ ├── oscal-il5.yaml
│ │ └── assessment-results.yaml
│ ├── design/ # Platform bundle architectural specifications
│ └── troubleshooting-drills/ # 4-Phase CLI Diagnostic Field Manual
├── tests/ # Automated unit, OSCAL schema, and shift-left IL5 test suite
├── Makefile # Unified CLI workflow entrypoint
└── README.md
```
Expand All @@ -77,19 +83,47 @@ uds-bundle-dev-test/
# 1. View all available Make targets
make help

# 2. Build modular Zarf packages and assemble the UDS bundle (.tar.zst)
# 2. Run local linting gates (ShellCheck, Python syntax, YAML, and Lula OSCAL linting)
make lint

# 3. Run automated unit, schema, and shift-left DoD IL5 compliance assertions
make test

# 4. Build modular Zarf packages and assemble the UDS bundle (.tar.zst)
make build

# 3. Verify strict zero-egress air-gap isolation and deploy the UDS bundle
# 5. Verify strict zero-egress air-gap isolation and deploy the UDS bundle
make verify-airgap
make deploy

# 4. Validate live cluster state against DoD IL5 NIST 800-53 controls using Lula
# 6. Check remote cluster status (nodes, pods, and services)
make status

# 7. Validate live cluster state against DoD IL5 NIST 800-53 controls using Lula
make compliance
```

---

## 🔒 Automated CI/CD & Defense Unicorns Lula Compliance Architecture

This repository implements Defense Unicorns' recommended **3-tier automated compliance and quality architecture** across GitHub Actions ([`.github/workflows/ci.yml`](file:///home/bjarrett/Projects/uds-bundle-dev-test/.github/workflows/ci.yml)) and local toolchains:

1. **Tier 1 — Shift-Left Schema & Model Linting (`make lint` / CI):**
* Validates OSCAL `component-definition` and `assessment-results` models against the official NIST schema using `lula tools lint`.
* Lints bash automation scripts with `shellcheck` and Python modules with `ruff` and `py_compile`.
* Scans for committed secrets with `gitleaks`.
2. **Tier 2 — Static Manifest Compliance Assertions (`make test` / CI):**
* Statically audits all `packages/training-app/manifests/*.yaml` for NIST SP 800-53 controls:
* **AC-3 (Least Privilege):** Verifies all containers enforce `securityContext.allowPrivilegeEscalation: false`.
* **AC-4 (Information Flow):** Verifies zero-trust `NetworkPolicy` ingress and egress enforcement.
* **SC-8 & CM-8:** Audits service definitions, component namespaces, and confirms baseline assessment findings are satisfied.
3. **Tier 3 — Ephemeral KinD Runtime Compliance Gate (CI) & Disconnected Live Cluster (CD):**
* **In CI:** Spins up an ephemeral Kubernetes cluster (`kind-action`), deploys workload manifests, and runs live `lula validate -f docs/compliance/oscal-il5.yaml` against the running Kubernetes API, failing the build on any control regression.
* **In Field / Air-Gap:** Runs live compliance validation against the target cluster (`make compliance`) and continuous triage through `make drill-check`.

---

## 🧪 Interactive CLI Troubleshooting Tutor & Chaos Lab

Once the UDS bundle is deployed, use the built-in **Drill Manager** ([`scripts/drill_manager.py`](file:///home/bjarrett/Projects/uds-bundle-dev-test/scripts/drill_manager.py)) and [Troubleshooting Runbook](file:///home/bjarrett/Projects/uds-bundle-dev-test/docs/troubleshooting-drills/README.md) to practice diagnosing and fixing cluster, Zarf, UDS, and Lula compliance issues using real CLI commands:
Expand Down
7 changes: 5 additions & 2 deletions docs/adr/0003-dod-il5-compliance-and-zero-trust-secrets.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ Key architectural challenges include:

1. **Shift-Left Compliance via Lula (OSCAL-as-Code)**:
- Define a formal OSCAL (Open Security Controls Assessment Language) Component Definition in `docs/compliance/oscal-il5.yaml`.
- Embed automated validation rules using Defense Unicorns' **Lula** framework to assess live cluster states against NIST SP 800-53 Rev 5 controls (AC-3, AC-4, IA-2, SC-8, SC-28, CM-8).
- Provide an automated test script (`scripts/test-compliance.sh`) to execute `lula validate` and generate `assessment-results.yaml`.
- Embed automated validation rules using Defense Unicorns' **Lula** framework to assess live cluster states against NIST SP 800-53 Rev 5 controls (AC-3, AC-4, IA-2, SC-8, CM-8).
- Enforce automated quality gates in GitHub Actions (`.github/workflows/ci.yml`):
- `lula tools lint` validates OSCAL 1.1.2 schema compliance.
* Ephemeral KinD cluster validates runtime compliance before code can be merged into `main`.
- Provide an automated test script (`scripts/test-compliance.sh` / `make compliance`) to execute `lula validate` and generate `assessment-results.yaml`.

2. **Zero-Trust Secrets & Credential Management**:
- **Dynamic Zarf Generation**: Use Zarf's built-in cryptographic generator for bootstrap credentials where external secrets are not supplied.
Expand Down
56 changes: 44 additions & 12 deletions docs/design/platform-bundle-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ The **Platform UDS Bundle** bundles core platform services (GitOps, Observabilit

```
uds-bundle-dev-test/
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions CI: Lula lint, KinD runtime gate, unit tests, Gitleaks
├── bundles/
│ └── uds-bundle.yaml # Orchestrates the 3 packages & exports/imports
├── packages/
Expand All @@ -33,17 +36,24 @@ uds-bundle-dev-test/
│ │ └── values/ # Prometheus / Grafana dashboards & alerts
│ └── training-app/
│ ├── zarf.yaml # Zarf package for mission app
│ └── manifests/ # Kubernetes manifests / kustomization
│ └── manifests/ # Kubernetes manifests (Namespace, NetPol, Workloads)
├── scripts/
│ ├── build-bundle.sh # Builds individual Zarf packages + UDS bundle
│ ├── test-deploy.sh # Local cluster deploy verification
│ └── verify-airgap.sh # Air-gap zero-egress auditor
│ ├── common.py # KUBECONFIG discovery, SSH tunnel auto-recovery & runner
│ ├── drill_manager.py # Interactive CLI Tutor & Chaos Injection Engine
│ ├── build-bundle.sh # Builds individual Zarf packages + UDS bundle (.tar.zst)
│ ├── test-deploy.sh # Cluster deploy verification
│ ├── test-compliance.sh # Lula OSCAL IL5 compliance validator
│ └── verify-airgap.sh # Air-gap zero-egress auditor (auto-delegated over SSH)
├── docs/
│ ├── adr/
│ │ ├── 0001-separation-of-environment-and-bundle-lifecycle.md
│ │ └── 0002-modular-zarf-packages-and-platform-bundle-design.md
│ └── design/
│ └── platform-bundle-architecture.md
│ ├── adr/ # Architecture Decision Records (0001–0003)
│ ├── compliance/ # NIST SP 800-53 Rev 5 OSCAL 1.1.2 component & assessment
│ │ ├── oscal-il5.yaml
│ │ └── assessment-results.yaml
│ ├── design/
│ │ └── platform-bundle-architecture.md
│ └── troubleshooting-drills/ # CLI diagnostic field manual & scenario walkthroughs
├── tests/ # Automated unit, OSCAL schema, and shift-left IL5 test suite
├── Makefile # Unified developer & drill CLI interface
└── README.md
```

Expand Down Expand Up @@ -84,6 +94,28 @@ uds-bundle-dev-test/

## 4. Lifecycle & Build Pipeline

1. **Package Compilation**: Each package in `packages/*` is packaged using `zarf package create`.
2. **Bundle Assembly**: `uds create bundles/` bundles all package `.tar.zst` files into a single bundle `.tar.zst`.
3. **Air-Gap Ingestion**: The bundle archive is transferred to the air-gapped target host and deployed with `uds deploy <bundle-archive>`.
1. **Pre-Commit & CI Validation**: Automated linting (`make lint`), OSCAL schema validation (`lula tools lint`), and static shift-left IL5 control assertions (`make test`) run on every PR.
2. **KinD Ephemeral Compliance Gate**: GitHub Actions deploys the workload manifests to an ephemeral KinD cluster and executes runtime `lula validate` against DoD IL5 NIST 800-53 controls.
3. **Package Compilation**: Each package in `packages/*` is packaged using `zarf package create`.
4. **Bundle Assembly**: `uds create bundles/` bundles all package `.tar.zst` files into a single bundle `.tar.zst`.
5. **Air-Gap Ingestion & Delivery**: The bundle archive is transferred to the air-gapped target host (e.g. Dell T5600 `airgapped-sandbox-hypervisor`) and deployed with `uds deploy <bundle-archive>`.

---

## 5. Continuous Compliance-as-Code with Lula

The platform bundle natively integrates with **Defense Unicorns Lula** to achieve Continuous Authority to Operate (cATO):

- **OSCAL Component Definition** (`docs/compliance/oscal-il5.yaml`): Formally specifies how the platform stack satisfies NIST SP 800-53 Rev 5 controls (`AC-3`, `AC-4`, `IA-2`, `SC-8`, `CM-8`) with embedded OPA Rego policies.
- **Continuous Assessment Results** (`docs/compliance/assessment-results.yaml`): Version-controlled, cryptographically verifiable assessment artifact tracking satisfied controls and providing an immutable audit trail.
- **Air-Gap Runtime Audit** (`make compliance`): Evaluates live cluster resources against OSCAL controls without requiring internet access.

---

## 6. Interactive CLI Troubleshooting Tutor & Chaos Engine

To train platform engineers and validate incident response in disconnected environments, the repository includes a chaos injection and diagnostic tutoring engine (`scripts/drill_manager.py`):

- **10 Diagnostic Scenarios**: Spans Zarf/Air-gap image seeding, mutating webhook bypass, zero-trust NetworkPolicy blocks, Service targetPort/selector mismatches, OOMKills, liveness probe loops, unschedulable pods, pending PVCs, and Lula compliance drift.
- **4-Phase Diagnostic Protocol**: Structured triage loop: *Detect* $\rightarrow$ *Isolate* $\rightarrow$ *Root Cause* $\rightarrow$ *Remediate & Verify*.
- **Mystery Fault Injection**: Blind chaos mode (`make drill-mystery`) to diagnose and resolve unannounced platform failures from scratch.
Loading
Loading