build: provision and verify Whitehat foundational plane

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02878-7c21-7692-bcd6-ce2838c4b448
This commit is contained in:
tegwick 2026-08-22 11:26:49 +02:00
parent acab22ff25
commit c26a6e59de
6 changed files with 244 additions and 5 deletions

View file

@ -0,0 +1,137 @@
{
"apply": {
"field_manager": "ops-mason",
"persisted_manifests": [
"manifests/whitehat-plane/namespace.yaml",
"manifests/whitehat-plane/network-policy.yaml",
"manifests/whitehat-plane/service-account.yaml"
],
"server_validated_manifests": [
"manifests/whitehat-plane/namespace.yaml",
"manifests/whitehat-plane/network-policy.yaml",
"manifests/whitehat-plane/service-account.yaml"
]
},
"plan": {
"approved_at": "2026-08-22",
"approved_by": "Bernd Worsch",
"id": "whitehat-foundational-plane"
},
"preflight": {
"bundle_digest": "9636f48f0b994118ff60a8c014e0099486945d66a2b3d3582dc57a09862b2035",
"bundle_id": "whitehat-foundational-plane",
"client_validated_manifests": [
"manifests/whitehat-plane/namespace.yaml",
"manifests/whitehat-plane/network-policy.yaml",
"manifests/whitehat-plane/service-account.yaml"
],
"context": "default",
"deferred_server_validation": [
"manifests/whitehat-plane/network-policy.yaml",
"manifests/whitehat-plane/service-account.yaml"
],
"dependencies": [
{
"assertions": {
"/spec/ports/0/port": 8080
},
"name": "audit-core",
"namespace": "audit-core",
"resource": "services"
},
{
"assertions": {
"/spec/ingress/0/from/0/namespaceSelector/matchLabels/kubernetes.io~1metadata.name": "whitehat",
"/spec/ingress/0/from/0/podSelector/matchLabels/whitehat.security~1plane": "true",
"/spec/ingress/0/from/0/podSelector/matchLabels/whitehat.security~1target": "audit-core",
"/spec/ingress/0/ports/0/port": 8080
},
"name": "audit-core-whitehat-ingress",
"namespace": "audit-core",
"resource": "networkpolicies.networking.k8s.io"
}
],
"objects": [
{
"object": "Namespace/whitehat",
"state": "absent"
},
{
"object": "NetworkPolicy/whitehat/default-deny",
"state": "absent"
},
{
"object": "NetworkPolicy/whitehat/allow-audit-core-e2",
"state": "absent"
},
{
"object": "ServiceAccount/whitehat/whitehat-runner",
"state": "absent"
}
],
"ok": true,
"plan_approved": true,
"plan_id": "whitehat-foundational-plane",
"server_validated_manifests": [
"manifests/whitehat-plane/namespace.yaml"
]
},
"recorded_at": "2026-08-22T09:24:44.407612+00:00",
"rollback": {
"bundle_id": "whitehat-foundational-plane",
"conditional_namespace_commands": [
"kubectl delete namespaces whitehat"
],
"inventory_before_namespace_delete": [
"kubectl -n whitehat get all,configmaps,secrets,serviceaccounts,networkpolicies"
],
"object_scoped_commands": [
"kubectl -n whitehat delete networkpolicies.networking.k8s.io default-deny",
"kubectl -n whitehat delete networkpolicies.networking.k8s.io allow-audit-core-e2",
"kubectl -n whitehat delete serviceaccounts whitehat-runner"
],
"warning": "Delete the namespace only after proving it contains no later or unrelated objects."
},
"schema_version": "ops-mason.kubernetes-plane-evidence/v1",
"source": {
"implementation_revision": "95129d7a35c8999be359b163b554853c9c6afa3a",
"repo": "whitehat-security",
"revision": "4882c2d47a826a305d5c4e05aa7fcc1252c3887e"
},
"verification": {
"bundle_digest": "9636f48f0b994118ff60a8c014e0099486945d66a2b3d3582dc57a09862b2035",
"bundle_id": "whitehat-foundational-plane",
"context": "default",
"negative_scope": {
"pods": 0,
"secrets": 0
},
"objects": [
{
"generation": null,
"object": "Namespace/whitehat",
"resource_version": "50841574",
"uid": "b0f97761-28a2-4b50-b4cb-890995fc0993"
},
{
"generation": 1,
"object": "NetworkPolicy/whitehat/default-deny",
"resource_version": "50841577",
"uid": "f4143fc9-4e42-454e-867b-c3fe5a050945"
},
{
"generation": 1,
"object": "NetworkPolicy/whitehat/allow-audit-core-e2",
"resource_version": "50841578",
"uid": "84ba88a8-74df-448d-b9ba-066083c49b0f"
},
{
"generation": null,
"object": "ServiceAccount/whitehat/whitehat-runner",
"resource_version": "50841583",
"uid": "6229deb0-82b8-4ca7-aee5-e00b4eff81a9"
}
],
"ok": true
}
}

View file

@ -0,0 +1,62 @@
# Whitehat foundational plane apply evidence
Applied: `2026-08-22T09:24:44Z`
Plan: `whitehat-foundational-plane`
Approved by: Bernd Worsch, 2026-08-22
Executor source: ops-mason `2b31863`
Bundle digest: `9636f48f0b994118ff60a8c014e0099486945d66a2b3d3582dc57a09862b2035`
## Provenance and guard result
- Whitehat coordination revision:
`4882c2d47a826a305d5c4e05aa7fcc1252c3887e`
- Plane implementation revision:
`95129d7a35c8999be359b163b554853c9c6afa3a`
- The three source files and Mason pins are byte-identical.
- Context `default`, create RBAC, audit-core Service TCP 8080, and
`audit-core-whitehat-ingress` exact selectors/port passed.
- All four objects were absent before apply.
- All three manifests passed client validation and server dry-run before
persistence.
## Live objects
| Object | UID | Resource version |
| --- | --- | --- |
| Namespace `whitehat` | `b0f97761-28a2-4b50-b4cb-890995fc0993` | `50841574` |
| NetworkPolicy `default-deny` | `f4143fc9-4e42-454e-867b-c3fe5a050945` | `50841577` |
| NetworkPolicy `allow-audit-core-e2` | `84ba88a8-74df-448d-b9ba-066083c49b0f` | `50841578` |
| ServiceAccount `whitehat-runner` | `6229deb0-82b8-4ca7-aee5-e00b4eff81a9` | `50841583` |
Post-apply preflight classifies every object as `exact` and server-validates
all manifests. ServiceAccount token automount is `false`. The namespace has
zero Pods and zero Secrets. Kubernetes created its normal `default`
ServiceAccount and `kube-root-ca.crt` ConfigMap; neither is part of the bundle.
No runner Pod, credential, projected identity, custody lease, new engagement,
or target request was created or sent.
## Rollback
Object-scoped rollback, in order:
```bash
kubectl -n whitehat delete networkpolicies.networking.k8s.io default-deny
kubectl -n whitehat delete networkpolicies.networking.k8s.io allow-audit-core-e2
kubectl -n whitehat delete serviceaccounts whitehat-runner
```
Before considering Namespace deletion, inventory it:
```bash
kubectl -n whitehat get all,configmaps,secrets,serviceaccounts,networkpolicies
```
Only if no later or unrelated object exists:
```bash
kubectl delete namespaces whitehat
```
No rollback command was executed. Machine-readable evidence is in
`docs/evidence/whitehat-foundational-plane.json`.

View file

@ -3,7 +3,7 @@ id: whitehat-foundational-plane
demand_source: "statehub-message:311a274e-9434-4fc3-bc52-8ea15ca68274" demand_source: "statehub-message:311a274e-9434-4fc3-bc52-8ea15ca68274"
consumer_repo: whitehat-security consumer_repo: whitehat-security
credential_type: kubernetes-foundational-plane credential_type: kubernetes-foundational-plane
status: approved status: built
approved_by: "Bernd Worsch" approved_by: "Bernd Worsch"
approved_at: "2026-08-22" approved_at: "2026-08-22"
created: "2026-08-22" created: "2026-08-22"
@ -84,4 +84,20 @@ above and does not extend to a runner, credential, engagement, or traffic.
## 6. Build result ## 6. Build result
Pending guarded apply and metadata-only verification. Built and verified on 2026-08-22 with the guarded executor introduced in
ops-mason commit `2b31863` and immutable bundle digest
`9636f48f0b994118ff60a8c014e0099486945d66a2b3d3582dc57a09862b2035`.
- created Namespace `whitehat` with restricted Pod Security enforcement;
- created NetworkPolicies `default-deny` and `allow-audit-core-e2`;
- created ServiceAccount `whitehat-runner` with token automount disabled;
- server-dry-ran every manifest before persistence;
- independently re-verified all desired fields and found zero live drift;
- found zero Pods and zero Secrets in the namespace;
- generated object-scoped rollback plus a separately conditional Namespace
rollback; no rollback command was executed.
Kubernetes automatically created only its normal `default` ServiceAccount and
`kube-root-ca.crt` ConfigMap alongside the four governed objects. No runner,
credential, projected identity, lease, engagement, or target request exists.
Evidence: `docs/evidence/whitehat-foundational-plane.json` and `.md`.

View file

@ -555,7 +555,10 @@ def apply(
_check_inputs_clean(bundle, runner) _check_inputs_clean(bundle, runner)
before = preflight(bundle, runner) before = preflight(bundle, runner)
server_validated = list(before["server_validated_manifests"])
persisted: list[str] = []
for manifest in bundle.manifests: for manifest in bundle.manifests:
relative_path = str(manifest.path.relative_to(bundle.repo_root))
docs = list(yaml.safe_load_all(manifest.path.read_text())) docs = list(yaml.safe_load_all(manifest.path.read_text()))
namespaced = any(doc.get("metadata", {}).get("namespace") for doc in docs) namespaced = any(doc.get("metadata", {}).get("namespace") for doc in docs)
if namespaced: if namespaced:
@ -571,6 +574,7 @@ def apply(
str(manifest.path), str(manifest.path),
], ],
) )
server_validated.append(relative_path)
_run( _run(
runner, runner,
[ [
@ -582,6 +586,7 @@ def apply(
str(manifest.path), str(manifest.path),
], ],
) )
persisted.append(relative_path)
verified = verify(bundle, runner) verified = verify(bundle, runner)
evidence = { evidence = {
@ -597,6 +602,11 @@ def apply(
"revision": bundle.source_revision, "revision": bundle.source_revision,
"implementation_revision": bundle.implementation_revision, "implementation_revision": bundle.implementation_revision,
}, },
"apply": {
"field_manager": "ops-mason",
"server_validated_manifests": server_validated,
"persisted_manifests": persisted,
},
"preflight": before, "preflight": before,
"verification": verified, "verification": verified,
"rollback": rollback_plan(bundle), "rollback": rollback_plan(bundle),

View file

@ -28,7 +28,10 @@ def test_whitehat_bundle_is_exactly_four_allowlisted_objects() -> None:
"NetworkPolicy/whitehat/allow-audit-core-e2", "NetworkPolicy/whitehat/allow-audit-core-e2",
"ServiceAccount/whitehat/whitehat-runner", "ServiceAccount/whitehat/whitehat-runner",
] ]
assert bundle.plan().is_approved() plan = bundle.plan()
assert plan.status == "built"
assert plan.approved_by == "Bernd Worsch"
assert plan.approved_at == "2026-08-22"
assert {doc["kind"] for doc in bundle.documents} == { assert {doc["kind"] for doc in bundle.documents} == {
"Namespace", "Namespace",
"NetworkPolicy", "NetworkPolicy",
@ -234,6 +237,11 @@ def test_apply_runs_guarded_path_and_writes_metadata_only_evidence(tmp_path: Pat
runner=cluster, runner=cluster,
) )
assert evidence["verification"]["negative_scope"] == {"pods": 0, "secrets": 0} assert evidence["verification"]["negative_scope"] == {"pods": 0, "secrets": 0}
assert evidence["apply"] == {
"field_manager": "ops-mason",
"server_validated_manifests": ["manifests/plane.yaml"],
"persisted_manifests": ["manifests/plane.yaml"],
}
assert bundle.evidence_path.exists() assert bundle.evidence_path.exists()
text = bundle.evidence_path.read_text() text = bundle.evidence_path.read_text()
assert "uid-1" in text assert "uid-1" in text

View file

@ -94,7 +94,7 @@ Whitehat README alignment request: State Hub message
```task ```task
id: MASON-WP-0002-T02 id: MASON-WP-0002-T02
status: progress status: done
priority: high priority: high
state_hub_task_id: "23f78bc5-4185-5181-9f3c-fd718641d2a5" state_hub_task_id: "23f78bc5-4185-5181-9f3c-fd718641d2a5"
``` ```
@ -124,11 +124,17 @@ or broad selector for rollback.
checks are clean, and the exact rollback commands have been captured without checks are clean, and the exact rollback commands have been captured without
executing them. executing them.
**Done (2026-08-22):** guarded apply created exactly the four approved objects.
All desired fields re-verify as exact, every manifest passed server dry-run,
`whitehat-runner` reports token automount `false`, and the namespace has zero
Pods and zero Secrets. Evidence includes object UIDs/resource versions and
rollback; no rollback command or target packet was executed.
## Return evidence and bounded handoff ## Return evidence and bounded handoff
```task ```task
id: MASON-WP-0002-T03 id: MASON-WP-0002-T03
status: todo status: progress
priority: high priority: high
state_hub_task_id: "a9c0844b-bf0a-5a53-b7e7-c0c2fbb842e6" state_hub_task_id: "a9c0844b-bf0a-5a53-b7e7-c0c2fbb842e6"
``` ```