From 710fb145be574576da68f3337d29c62e306ae480 Mon Sep 17 00:00:00 2001 From: Chris Christiansen Date: Wed, 2 Sep 2026 19:35:58 +0000 Subject: [PATCH] feat(tyr): write gatekeeper container security policy --- project/roadmap.md | 4 ++ tyr/memory_bank/completed.md | 4 ++ tyr/policy/container_security.yaml | 70 ++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 tyr/policy/container_security.yaml diff --git a/project/roadmap.md b/project/roadmap.md index 9a09713..7131d6e 100644 --- a/project/roadmap.md +++ b/project/roadmap.md @@ -14,8 +14,12 @@ This document tracks the high-level goals and future development milestones for ## Phase 2: Network Hardening & Perimeter Defense - [x] Establish GCP VPC Service Controls (VPC-SC) perimeter. - [x] Configure Private Service Connect (PSC) for all Google APIs. +- [x] Deploy Cloud Armor WAF policy. - [x] Enforce IAP-only SSH and restrict Cloud Run ingress. +## Phase 3: Runtime Enforcers & Workload Security +- [x] Draft Gatekeeper container security policy. + ## Phase 3: Memory Bank & Project Management - [x] Implement `read_memory_bank` and `write_memory_bank` MCP tools. - [x] Implement `build_and_deploy_service` MCP tool. diff --git a/tyr/memory_bank/completed.md b/tyr/memory_bank/completed.md index 1c405d6..b0f1aa2 100644 --- a/tyr/memory_bank/completed.md +++ b/tyr/memory_bank/completed.md @@ -27,3 +27,7 @@ - **Task 2.4: Harden Ingress** - Status: **Complete** - Notes: Replaced default SSH rule with IAP-only rule and set Cloud Run ingress to internal. + +- **Task 3.1: Draft Gatekeeper Policy** + - Status: **Complete** + - Notes: Wrote `container_security.yaml` with policies to disallow root and require resource limits. diff --git a/tyr/policy/container_security.yaml b/tyr/policy/container_security.yaml new file mode 100644 index 0000000..163bd93 --- /dev/null +++ b/tyr/policy/container_security.yaml @@ -0,0 +1,70 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8sdisallowroot +spec: + crd: + spec: + names: + kind: K8sDisallowRoot + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8sdisallowroot + + violation[{"msg": msg}] { + input.review.object.spec.securityContext.runAsNonRoot == false + msg := "Containers must not run as root. Set spec.securityContext.runAsNonRoot to true." + } + + violation[{"msg": msg}] { + some c in input.review.object.spec.containers + c.securityContext.runAsNonRoot == false + msg := sprintf("Container %v must not run as root. Set securityContext.runAsNonRoot to true.", [c.name]) + } +--- +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sDisallowRoot +metadata: + name: disallow-root-containers +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] +--- +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8srequiredlimits +spec: + crd: + spec: + names: + kind: K8sRequiredLimits + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package k8srequiredlimits + + violation[{"msg": msg}] { + some c in input.review.object.spec.containers + not c.resources.limits.cpu + msg := sprintf("Container %v must have a CPU limit.", [c.name]) + } + + violation[{"msg": msg}] { + some c in input.review.object.spec.containers + not c.resources.limits.memory + msg := sprintf("Container %v must have a memory limit.", [c.name]) + } +--- +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sRequiredLimits +metadata: + name: require-resource-limits +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"]