@raishin/vanguard-frontier-agentic 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/kubernetes/README.md +10 -1
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/AGENT.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/claude-code.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/copilot.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/cursor.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/gemini.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/kiro-ide.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/metadata.json +5 -3
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/references/least-privilege-rbac.yaml +98 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/references/rbac-pre-flight.md +108 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/references/refusal-list.md +112 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/AGENT.md +13 -1
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/claude-code.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/copilot.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/cursor.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/gemini.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/kiro-ide.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/metadata.json +5 -3
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/references/least-privilege-rbac.yaml +92 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/references/rbac-pre-flight.md +108 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/references/refusal-list.md +112 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/AGENT.md +13 -1
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/claude-code.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/copilot.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/cursor.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/gemini.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/kiro-ide.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/metadata.json +5 -3
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/references/least-privilege-rbac.yaml +101 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/references/rbac-pre-flight.md +106 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/references/refusal-list.md +102 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/AGENT.md +71 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/claude-code.agent.md +54 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/codex.toml +38 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/copilot.agent.md +54 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/cursor.agent.md +54 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/gemini.agent.md +54 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/kiro-ide.agent.md +54 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/metadata.json +44 -0
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/AGENT.md +14 -2
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/claude-code.agent.md +13 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/copilot.agent.md +13 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/cursor.agent.md +13 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/gemini.agent.md +13 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/kiro-ide.agent.md +13 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/metadata.json +5 -3
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/references/least-privilege-rbac.yaml +101 -0
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/references/rbac-pre-flight.md +106 -0
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/references/refusal-list.md +102 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/AGENT.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/claude-code.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/copilot.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/cursor.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/gemini.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/kiro-ide.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/metadata.json +6 -3
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/references/least-privilege-rbac.yaml +92 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/references/rbac-pre-flight.md +115 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/references/refusal-list.md +132 -0
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/AGENT.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/claude-code.agent.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/codex.toml +2 -2
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/copilot.agent.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/cursor.agent.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/gemini.agent.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/kiro-ide.agent.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/metadata.json +6 -4
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/references/least-privilege-rbac.yaml +92 -0
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/references/rbac-pre-flight.md +109 -0
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/references/refusal-list.md +122 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/AGENT.md +65 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/claude-code.agent.md +48 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/codex.toml +37 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/copilot.agent.md +48 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/cursor.agent.md +48 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/gemini.agent.md +48 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/kiro-ide.agent.md +48 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/metadata.json +44 -0
- package/catalog/agents.json +78 -12
- package/catalog/install-roles.json +8 -4
- package/catalog/skill-manifest.json +111 -12
- package/catalog/skills.json +67 -0
- package/package.json +1 -1
- package/skills/kubernetes/README.md +5 -1
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/SKILL.md +82 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/metadata.json +33 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/least-privilege-rbac.yaml +210 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/official-sources.md +41 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/permitted-mutations.md +173 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/rbac-pre-flight.md +252 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/refusal-list.md +313 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/rollback-patterns.md +103 -0
- package/skills/kubernetes/kubernetes-maestro/references/safety-checklist.md +1 -1
- package/skills/kubernetes/kubernetes-maestro/references/workflow-and-output.md +57 -5
- package/skills/kubernetes/kubernetes-network-architecture-review/SKILL.md +84 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/metadata.json +34 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/dataplane-and-cni.md +89 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/dns-and-discovery.md +120 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/mcp-and-evidence.md +53 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/multi-cluster-and-egress.md +69 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/official-sources.md +54 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/service-gateway-routing.md +108 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/troubleshooting-playbook.md +100 -0
- package/skills/velero/velero-backup-restore-guard/SKILL.md +2 -2
- package/skills/velero/velero-backup-restore-guard/references/safety-checklist.md +1 -1
- package/skills/velero/velero-backup-restore-guard/references/workflow-and-output.md +17 -8
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# =====================================================================
|
|
2
|
+
# Least-privilege RBAC for kubernetes-live-network-architecture-mutation-guard-agent
|
|
3
|
+
#
|
|
4
|
+
# Apply BEFORE running the agent.
|
|
5
|
+
# Authoring contract: docs/least-privilege-rbac.md
|
|
6
|
+
# Pre-flight matrix: references/rbac-pre-flight.md
|
|
7
|
+
# Refusal list: references/refusal-list.md (cluster-side enforcement of these omissions)
|
|
8
|
+
#
|
|
9
|
+
# Audit:
|
|
10
|
+
# SA="system:serviceaccount:vanguard-system:vanguard-network-arch-guard"
|
|
11
|
+
# kubectl auth can-i delete namespaces --as=$SA # must return: no
|
|
12
|
+
# kubectl auth can-i patch services -A --as=$SA # must return: yes
|
|
13
|
+
#
|
|
14
|
+
# Per upstream kubernetes.io/docs/concepts/security/rbac-good-practices:
|
|
15
|
+
# "Avoid wildcard permissions, especially to all resources, as this grants
|
|
16
|
+
# access to current and future object types."
|
|
17
|
+
# =====================================================================
|
|
18
|
+
apiVersion: v1
|
|
19
|
+
kind: Namespace
|
|
20
|
+
metadata:
|
|
21
|
+
name: vanguard-system
|
|
22
|
+
labels:
|
|
23
|
+
pod-security.kubernetes.io/enforce: restricted
|
|
24
|
+
pod-security.kubernetes.io/enforce-version: latest
|
|
25
|
+
app.kubernetes.io/managed-by: vanguard-frontier
|
|
26
|
+
---
|
|
27
|
+
apiVersion: v1
|
|
28
|
+
kind: ServiceAccount
|
|
29
|
+
metadata:
|
|
30
|
+
name: vanguard-network-arch-guard
|
|
31
|
+
namespace: vanguard-system
|
|
32
|
+
annotations:
|
|
33
|
+
vanguard.frontier/agent: "kubernetes-live-network-architecture-mutation-guard-agent"
|
|
34
|
+
vanguard.frontier/scope: "least-privilege-network-architecture"
|
|
35
|
+
vanguard.frontier/contract: "docs/least-privilege-rbac.md"
|
|
36
|
+
automountServiceAccountToken: true
|
|
37
|
+
---
|
|
38
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
39
|
+
kind: ClusterRole
|
|
40
|
+
metadata:
|
|
41
|
+
name: vanguard-network-arch-guard
|
|
42
|
+
rules:
|
|
43
|
+
# ---- READ across networking architecture surface ----
|
|
44
|
+
- apiGroups: [""]
|
|
45
|
+
resources: ["services", "endpoints", "nodes"]
|
|
46
|
+
verbs: ["get", "list", "watch"]
|
|
47
|
+
- apiGroups: ["discovery.k8s.io"]
|
|
48
|
+
resources: ["endpointslices"]
|
|
49
|
+
verbs: ["get", "list", "watch"]
|
|
50
|
+
- apiGroups: ["gateway.networking.k8s.io"]
|
|
51
|
+
resources:
|
|
52
|
+
- "gatewayclasses"
|
|
53
|
+
- "gateways"
|
|
54
|
+
- "httproutes"
|
|
55
|
+
- "grpcroutes"
|
|
56
|
+
- "tlsroutes"
|
|
57
|
+
- "tcproutes"
|
|
58
|
+
- "udproutes"
|
|
59
|
+
- "referencegrants"
|
|
60
|
+
verbs: ["get", "list", "watch"]
|
|
61
|
+
# ---- WRITE on Service spec (low blast radius, reversible) ----
|
|
62
|
+
- apiGroups: [""]
|
|
63
|
+
resources: ["services"]
|
|
64
|
+
verbs: ["patch"]
|
|
65
|
+
# NOTE: "delete" verb DELIBERATELY OMITTED. Rollback uses `kubectl apply -f baseline.yaml`.
|
|
66
|
+
# NOTE: "update" verb omitted in favor of "patch" for narrower change semantics.
|
|
67
|
+
# NOTE: CoreDNS ConfigMap read/write is intentionally ABSENT from this ClusterRole.
|
|
68
|
+
# resourceNames on a ClusterRole restricts only the object name, not the namespace;
|
|
69
|
+
# a ClusterRole rule would let the SA patch any ConfigMap named "coredns" in ANY
|
|
70
|
+
# namespace. A namespaced Role/RoleBinding in kube-system (below) provides the
|
|
71
|
+
# correct least-privilege scope. See docs/least-privilege-rbac.md §Threat model.
|
|
72
|
+
# ---- WRITE on Gateway API resources (user-owned, not control plane) ----
|
|
73
|
+
- apiGroups: ["gateway.networking.k8s.io"]
|
|
74
|
+
resources:
|
|
75
|
+
- "gateways"
|
|
76
|
+
- "httproutes"
|
|
77
|
+
- "grpcroutes"
|
|
78
|
+
- "tlsroutes"
|
|
79
|
+
- "tcproutes"
|
|
80
|
+
- "udproutes"
|
|
81
|
+
- "referencegrants"
|
|
82
|
+
verbs: ["create", "patch"]
|
|
83
|
+
# NOTE: "delete" verb DELIBERATELY OMITTED on Gateway API resources.
|
|
84
|
+
# Rollback to absent state is performed by a human-confirmed operation, not by this agent.
|
|
85
|
+
# NOTE: "gatewayclasses" is read-only; GatewayClass is installed by the controller's Helm chart.
|
|
86
|
+
# =====================================================================
|
|
87
|
+
# DELIBERATELY ABSENT — DO NOT add unless you accept the listed risk.
|
|
88
|
+
# This list is exhaustive against the destructive operations enumerated
|
|
89
|
+
# in references/refusal-list.md. The binding is deny-by-default: anything
|
|
90
|
+
# not granted above is denied at the API server. New attack vectors that
|
|
91
|
+
# emerge in future Kubernetes releases are denied automatically.
|
|
92
|
+
#
|
|
93
|
+
# === Namespaces & finalizers ===
|
|
94
|
+
# apiGroups: [""], resources: ["namespaces"] -> delete kube-system / cilium / istio-system
|
|
95
|
+
# patch with metadata.finalizers paths on any resource -> bypass namespace / PV / CRD finalizer protection
|
|
96
|
+
#
|
|
97
|
+
# === Workload writes in control-plane namespaces ===
|
|
98
|
+
# apiGroups: [""], resources: ["pods"] -> exec / delete on control-plane pods
|
|
99
|
+
# apiGroups: [""], resources: ["pods/exec"] -> shell into cilium-agent / kube-proxy / coredns
|
|
100
|
+
# apiGroups: [""], resources: ["pods/portforward"] -> NetworkPolicy bypass to any reachable Service
|
|
101
|
+
# apiGroups: [""], resources: ["pods/proxy"] -> proxy traffic via apiserver to pod
|
|
102
|
+
# apiGroups: [""], resources: ["pods/binding"] -> manual Pod-to-Node binding, scheduler bypass
|
|
103
|
+
# apiGroups: [""], resources: ["pods/eviction"] -> bypass PodDisruptionBudgets in some configs
|
|
104
|
+
# apiGroups: ["apps"], resources: ["daemonsets"], verbs: write -> remove cilium / kube-proxy / node-local-dns
|
|
105
|
+
# apiGroups: ["apps"], resources: ["deployments"], verbs: write -> remove ingress controllers / mesh control planes
|
|
106
|
+
# apiGroups: ["apps"], resources: ["statefulsets"], verbs: write -> remove etcd-replica / clustered controllers
|
|
107
|
+
#
|
|
108
|
+
# === Node lifecycle ===
|
|
109
|
+
# apiGroups: [""], resources: ["nodes"], verbs: ["patch", "update", "delete"] -> drain / cordon / delete nodes
|
|
110
|
+
# apiGroups: [""], resources: ["nodes/proxy"] -> direct kubelet API, bypasses some RBAC
|
|
111
|
+
# apiGroups: ["coordination.k8s.io"], resources: ["leases"] -> Lease in kube-node-lease, fake node liveness
|
|
112
|
+
#
|
|
113
|
+
# === Secrets & credentials ===
|
|
114
|
+
# apiGroups: [""], resources: ["secrets"] -> cluster-wide credential exposure
|
|
115
|
+
# apiGroups: [""], resources: ["serviceaccounts/token"] -> mint tokens for arbitrary SAs (TokenRequest)
|
|
116
|
+
# apiGroups: ["certificates.k8s.io"], any verb -> approve CSRs, especially with system:masters group
|
|
117
|
+
# apiGroups: ["authentication.k8s.io"], any verb -> tokenreviews, impersonation primitives
|
|
118
|
+
#
|
|
119
|
+
# === Cluster-extension surface (admission, aggregation, scheduling) ===
|
|
120
|
+
# apiGroups: ["admissionregistration.k8s.io"] -> mutating/validating webhook configs (admission bypass)
|
|
121
|
+
# apiGroups: ["apiregistration.k8s.io"] -> APIService aggregation hijack
|
|
122
|
+
# apiGroups: ["apiextensions.k8s.io"] -> CRD install / uninstall
|
|
123
|
+
# apiGroups: ["scheduling.k8s.io"] -> PriorityClass system-cluster-critical / system-node-critical
|
|
124
|
+
# apiGroups: ["policy"], resources: ["poddisruptionbudgets"], verbs: write -> remove eviction protection
|
|
125
|
+
#
|
|
126
|
+
# === Networking control plane ===
|
|
127
|
+
# apiGroups: [""], resources: ["endpoints"], verbs: write -> race with EndpointSlice controller, redirect Service traffic
|
|
128
|
+
# apiGroups: ["discovery.k8s.io"], resources: ["endpointslices"], verbs: write -> same race
|
|
129
|
+
# apiGroups: ["networking.k8s.io"], resources: ["ingressclasses"], verbs: write -> break Ingress controller binding
|
|
130
|
+
# apiGroups: ["networking.k8s.io"], resources: ["networkpolicies"] -> delegated to cilium-network-policy-review
|
|
131
|
+
# apiGroups: ["cilium.io"], resources: ["ciliumnetworkpolicies", "ciliumclusterwidenetworkpolicies"] -> delegated
|
|
132
|
+
# apiGroups: ["security.istio.io"], resources: ["authorizationpolicies", "peerauthentications"] -> delegated
|
|
133
|
+
#
|
|
134
|
+
# === Storage ===
|
|
135
|
+
# apiGroups: ["storage.k8s.io"], resources: ["storageclasses"], verbs: write -> remove default StorageClass, break PVC provisioning
|
|
136
|
+
# apiGroups: [""], resources: ["persistentvolumes"], verbs: write -> orphan cloud volumes
|
|
137
|
+
#
|
|
138
|
+
# === RBAC self-modification ===
|
|
139
|
+
# apiGroups: ["rbac.authorization.k8s.io"] -> binding self-modification, privilege escalation
|
|
140
|
+
#
|
|
141
|
+
# === Wildcards (always anti-pattern) ===
|
|
142
|
+
# any "*" verb or "*" resource -> per upstream RBAC good practices, grants future objects
|
|
143
|
+
#
|
|
144
|
+
# === Cross-cutting verbs ===
|
|
145
|
+
# any "delete" verb on cluster-scoped or namespaced resources -> rollback is `apply -f baseline.yaml`, never delete
|
|
146
|
+
#
|
|
147
|
+
# Add ClusterMesh peer Secret write access (resourceName-locked, narrow
|
|
148
|
+
# namespace) only when the operator explicitly opts in for ClusterMesh
|
|
149
|
+
# peering and accepts the additional review checklist in
|
|
150
|
+
# references/permitted-mutations.md. The narrow scope must be expressed
|
|
151
|
+
# both in the Role (resourceNames: [<peer-cluster-id>]) and in admission
|
|
152
|
+
# policy (Kyverno rule limiting Secret data field shape).
|
|
153
|
+
# =====================================================================
|
|
154
|
+
---
|
|
155
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
156
|
+
kind: ClusterRoleBinding
|
|
157
|
+
metadata:
|
|
158
|
+
name: vanguard-network-arch-guard
|
|
159
|
+
subjects:
|
|
160
|
+
- kind: ServiceAccount
|
|
161
|
+
name: vanguard-network-arch-guard
|
|
162
|
+
namespace: vanguard-system
|
|
163
|
+
roleRef:
|
|
164
|
+
kind: ClusterRole
|
|
165
|
+
name: vanguard-network-arch-guard
|
|
166
|
+
apiGroup: rbac.authorization.k8s.io
|
|
167
|
+
---
|
|
168
|
+
# =====================================================================
|
|
169
|
+
# Namespaced Role + RoleBinding for CoreDNS ConfigMap access.
|
|
170
|
+
# A ClusterRole with resourceNames restricts only the object name, not
|
|
171
|
+
# the namespace, so the SA would be able to patch any ConfigMap named
|
|
172
|
+
# "coredns" cluster-wide. This Role is bound only in kube-system,
|
|
173
|
+
# providing the correct least-privilege scope.
|
|
174
|
+
# =====================================================================
|
|
175
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
176
|
+
kind: Role
|
|
177
|
+
metadata:
|
|
178
|
+
name: vanguard-network-arch-guard-coredns
|
|
179
|
+
namespace: kube-system
|
|
180
|
+
annotations:
|
|
181
|
+
vanguard.frontier/agent: "kubernetes-live-network-architecture-mutation-guard-agent"
|
|
182
|
+
vanguard.frontier/contract: "docs/least-privilege-rbac.md"
|
|
183
|
+
rules:
|
|
184
|
+
# Broad read in kube-system — needed to inspect ConfigMap state before patching.
|
|
185
|
+
- apiGroups: [""]
|
|
186
|
+
resources: ["configmaps"]
|
|
187
|
+
verbs: ["get", "list", "watch"]
|
|
188
|
+
# Patch locked to the single ConfigMap that holds the CoreDNS Corefile.
|
|
189
|
+
# NOTE: "delete" verb DELIBERATELY OMITTED. Rollback uses `kubectl apply -f baseline.yaml`.
|
|
190
|
+
- apiGroups: [""]
|
|
191
|
+
resources: ["configmaps"]
|
|
192
|
+
resourceNames: ["coredns"]
|
|
193
|
+
verbs: ["patch"]
|
|
194
|
+
---
|
|
195
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
196
|
+
kind: RoleBinding
|
|
197
|
+
metadata:
|
|
198
|
+
name: vanguard-network-arch-guard-coredns
|
|
199
|
+
namespace: kube-system
|
|
200
|
+
annotations:
|
|
201
|
+
vanguard.frontier/agent: "kubernetes-live-network-architecture-mutation-guard-agent"
|
|
202
|
+
vanguard.frontier/contract: "docs/least-privilege-rbac.md"
|
|
203
|
+
subjects:
|
|
204
|
+
- kind: ServiceAccount
|
|
205
|
+
name: vanguard-network-arch-guard
|
|
206
|
+
namespace: vanguard-system
|
|
207
|
+
roleRef:
|
|
208
|
+
kind: Role
|
|
209
|
+
name: vanguard-network-arch-guard-coredns
|
|
210
|
+
apiGroup: rbac.authorization.k8s.io
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Official sources
|
|
2
|
+
|
|
3
|
+
Authoritative upstream documentation for the surfaces this guard mutates.
|
|
4
|
+
|
|
5
|
+
## RBAC and authorization
|
|
6
|
+
|
|
7
|
+
- [RBAC Good Practices](https://kubernetes.io/docs/concepts/security/rbac-good-practices/) — the foundational guidance this guard implements: minimal privilege, no wildcards, no `cluster-admin` for routine work, no `system:masters` group membership.
|
|
8
|
+
- [Using RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) — the API reference for `Role` / `ClusterRole` / `RoleBinding` / `ClusterRoleBinding`.
|
|
9
|
+
- [`kubectl auth can-i`](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_auth/kubectl_auth_can-i/) — the pre-flight matrix syntax.
|
|
10
|
+
- [User Impersonation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) — the recommended pattern: low-privileged operator with `impersonate` rights on the agent's ServiceAccount.
|
|
11
|
+
|
|
12
|
+
## Service traffic policy and topology-aware routing
|
|
13
|
+
|
|
14
|
+
- [Service Internal Traffic Policy](https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/) — `internalTrafficPolicy` and `externalTrafficPolicy` semantics.
|
|
15
|
+
- [Topology Aware Routing](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/) — `service.kubernetes.io/topology-mode: Auto` annotation and `spec.trafficDistribution` field.
|
|
16
|
+
|
|
17
|
+
## CoreDNS
|
|
18
|
+
|
|
19
|
+
- [CoreDNS `kubernetes` plugin](https://coredns.io/plugins/kubernetes/) — the in-cluster DNS plugin reference.
|
|
20
|
+
- [CoreDNS `reload` plugin](https://coredns.io/plugins/reload/) — Corefile change detection (default 30s poll).
|
|
21
|
+
- [CoreDNS `loop` plugin](https://coredns.io/plugins/loop/) — recursion-loop detection (silent failure mode if absent).
|
|
22
|
+
- [CoreDNS `health` plugin](https://coredns.io/plugins/health/) — liveness probe target.
|
|
23
|
+
|
|
24
|
+
## NodeLocal DNSCache
|
|
25
|
+
|
|
26
|
+
- [Using NodeLocal DNSCache in Kubernetes Clusters](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) — install manifest, the `__PILLAR__` token substitutions, and the kube-proxy / Cilium kube-proxy replacement preconditions.
|
|
27
|
+
|
|
28
|
+
## Gateway API
|
|
29
|
+
|
|
30
|
+
- [Gateway API](https://gateway-api.sigs.k8s.io/) — the SIG site (authoritative).
|
|
31
|
+
- [`Gateway` resource](https://gateway-api.sigs.k8s.io/api-types/gateway/) — the listener model and `allowedRoutes` semantics.
|
|
32
|
+
- [`HTTPRoute`](https://gateway-api.sigs.k8s.io/api-types/httproute/) — HTTP route reference.
|
|
33
|
+
- [`GRPCRoute`](https://gateway-api.sigs.k8s.io/api-types/grpcroute/) — gRPC route reference. **GA / Standard channel since Gateway API v1.1.0.**
|
|
34
|
+
- [`ReferenceGrant`](https://gateway-api.sigs.k8s.io/api-types/referencegrant/) — cross-namespace reference authorization.
|
|
35
|
+
- [Gateway API Versioning](https://gateway-api.sigs.k8s.io/concepts/versioning/) — Standard vs Experimental channel semantics.
|
|
36
|
+
|
|
37
|
+
## Cilium ClusterMesh
|
|
38
|
+
|
|
39
|
+
- [Setting up Cluster Mesh](https://docs.cilium.io/en/stable/network/clustermesh/clustermesh/) — peer Secret structure, namespace, and CA trust setup.
|
|
40
|
+
- [ClusterMesh Troubleshooting](https://docs.cilium.io/en/stable/operations/troubleshooting/) — `cilium clustermesh status`, `cilium-dbg troubleshoot clustermesh`, and the KVStoreMesh `kvstoremesh-dbg troubleshoot` command.
|
|
41
|
+
- [KVStoreMesh command reference](https://docs.cilium.io/en/stable/cmdref/clustermesh-apiserver_kvstoremesh/) — `--clustermesh-cache-ttl` (default `0s` means "never revoked"), `--global-ready-timeout` (default 10m).
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Permitted mutations
|
|
2
|
+
|
|
3
|
+
This is the explicit allowlist. Any mutation outside this list MUST be either rejected by the prompt rules OR refused by the cluster RBAC binding.
|
|
4
|
+
|
|
5
|
+
## Service spec patches (low blast radius, reversible)
|
|
6
|
+
|
|
7
|
+
### `internalTrafficPolicy` / `externalTrafficPolicy`
|
|
8
|
+
|
|
9
|
+
Reversible field on `v1.Service`. Default is `Cluster`; `Local` constrains routing to node-local endpoints.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Capture baseline
|
|
13
|
+
kubectl get svc <name> -n <ns> -o yaml > /tmp/svc-<name>.before.yaml
|
|
14
|
+
|
|
15
|
+
# Apply the patch
|
|
16
|
+
kubectl patch svc <name> -n <ns> --type=merge \
|
|
17
|
+
-p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
|
|
18
|
+
|
|
19
|
+
# Verify EndpointSlices still serve the Service
|
|
20
|
+
kubectl get endpointslice -n <ns> -l kubernetes.io/service-name=<name>
|
|
21
|
+
|
|
22
|
+
# Rollback
|
|
23
|
+
kubectl apply -f /tmp/svc-<name>.before.yaml
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Refusal triggers inside this mutation type:
|
|
27
|
+
- Setting `externalTrafficPolicy: Local` on a Service whose backend Pods are not present on every Node that the LoadBalancer health-check targets — blackhole risk.
|
|
28
|
+
- Setting `internalTrafficPolicy: Local` on a Service consumed cluster-wide where backends are not co-located with consumers on every Node.
|
|
29
|
+
|
|
30
|
+
### `service.kubernetes.io/topology-mode: Auto` annotation
|
|
31
|
+
|
|
32
|
+
Annotation, additive. Only applies when `Service` is multi-zone with sufficient endpoints per zone.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
kubectl annotate svc <name> -n <ns> \
|
|
36
|
+
service.kubernetes.io/topology-mode=Auto --overwrite
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Rollback: `kubectl annotate svc <name> -n <ns> service.kubernetes.io/topology-mode-`
|
|
40
|
+
|
|
41
|
+
### `spec.trafficDistribution` field (KEP-4444)
|
|
42
|
+
|
|
43
|
+
Newer API; supersedes the annotation when both are set. Field-level patch on `v1.Service`.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
kubectl patch svc <name> -n <ns> --type=merge \
|
|
47
|
+
-p '{"spec":{"trafficDistribution":"PreferClose"}}'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Rollback: `kubectl patch svc <name> -n <ns> --type=json -p='[{"op":"remove","path":"/spec/trafficDistribution"}]'`
|
|
51
|
+
|
|
52
|
+
## CoreDNS Corefile patch (medium blast radius, reversible with backup)
|
|
53
|
+
|
|
54
|
+
The CoreDNS `reload` plugin polls the Corefile every 30 seconds. If the new Corefile is invalid, CoreDNS rejects the reload and continues serving the previous config — but if the pod restarts for any other reason, it will fail to start. Always have a baseline.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Capture baseline (CRITICAL — never skip)
|
|
58
|
+
kubectl get cm coredns -n kube-system -o yaml > /tmp/coredns.before.yaml
|
|
59
|
+
|
|
60
|
+
# Apply
|
|
61
|
+
kubectl apply -f /tmp/coredns.new.yaml
|
|
62
|
+
|
|
63
|
+
# Verify reload (look for "Reloading complete" in logs within 60 seconds)
|
|
64
|
+
kubectl -n kube-system logs -l k8s-app=kube-dns --tail=50 --since=2m | grep -i "reload"
|
|
65
|
+
|
|
66
|
+
# Verify no CrashLoopBackOff
|
|
67
|
+
kubectl -n kube-system get pods -l k8s-app=kube-dns
|
|
68
|
+
|
|
69
|
+
# If any pod is unhealthy — rollback
|
|
70
|
+
kubectl apply -f /tmp/coredns.before.yaml
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Refusal triggers:
|
|
74
|
+
- New Corefile lacks the `reload` plugin (would prevent future zero-downtime updates).
|
|
75
|
+
- New Corefile lacks the `loop` plugin (CoreDNS forward-loop detection).
|
|
76
|
+
- New Corefile lacks the `health` plugin (liveness probe target removed).
|
|
77
|
+
- New Corefile lacks the `kubernetes` plugin or its `pods insecure` mode set to anything other than the cluster's documented standard.
|
|
78
|
+
- `forward .` target is changed to a private IP without confirming reachability from CoreDNS pod network.
|
|
79
|
+
|
|
80
|
+
## NodeLocal DNSCache install / upgrade (medium blast radius, requires explicit human gate)
|
|
81
|
+
|
|
82
|
+
Manifest from upstream `kubernetes/dns` repository (`nodelocaldns.yaml`). The install adds a `DaemonSet` and patches kube-proxy iptables / IPVS rules to redirect DNS traffic to the local cache. **This is a node-wide control-plane change**; refuse without an explicit human go-ahead even though the manifest itself is documented.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Capture cluster DNS service IP for the manifest's __PILLAR__LOCAL__DNS__ token
|
|
86
|
+
kubectl get svc -n kube-system kube-dns -o jsonpath='{.spec.clusterIP}'
|
|
87
|
+
|
|
88
|
+
# Apply the upstream-rendered manifest (with values substituted)
|
|
89
|
+
kubectl apply -f /tmp/nodelocaldns-rendered.yaml
|
|
90
|
+
|
|
91
|
+
# Verify rollout — every Node must have a Ready node-local-dns pod within 5 minutes
|
|
92
|
+
kubectl rollout status ds/node-local-dns -n kube-system --timeout=5m
|
|
93
|
+
|
|
94
|
+
# Rollback (uninstall — high impact, plan before applying)
|
|
95
|
+
kubectl delete -f /tmp/nodelocaldns-rendered.yaml
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Refusal triggers:
|
|
99
|
+
- Cluster does not run kube-proxy or Cilium kube-proxy replacement (NodeLocalDNS depends on a kube-proxy mode that supports the iptables / IPVS redirect).
|
|
100
|
+
- The `DaemonSet` request lacks `resources.limits.memory` (NodeLocal DNSCache OOM is a known node-wide DNS outage).
|
|
101
|
+
- The `DaemonSet` request lacks a `PodDisruptionBudget`.
|
|
102
|
+
- Node selector excludes any node — partial DNS coverage is worse than none.
|
|
103
|
+
|
|
104
|
+
## Gateway API resources (medium blast radius, reversible)
|
|
105
|
+
|
|
106
|
+
### `Gateway` resource
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Pre-check: GatewayClass must reference a controller that is actually running
|
|
110
|
+
GWC=$(yq '.spec.gatewayClassName' /tmp/gw.yaml)
|
|
111
|
+
CONTROLLER=$(kubectl get gatewayclass $GWC -o jsonpath='{.spec.controllerName}')
|
|
112
|
+
# Confirm controller pods are Ready before applying
|
|
113
|
+
|
|
114
|
+
kubectl apply -f /tmp/gw.yaml
|
|
115
|
+
kubectl wait --for=condition=Programmed gateway/<name> -n <ns> --timeout=2m
|
|
116
|
+
|
|
117
|
+
# Status verification
|
|
118
|
+
kubectl get gateway <name> -n <ns> -o jsonpath='{.status.conditions}'
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Refusal triggers:
|
|
122
|
+
- `GatewayClass` does not exist or its controller is not running.
|
|
123
|
+
- `spec.allowedRoutes.namespaces.from: All` without an accompanying `ReferenceGrant` strategy — security boundary expansion.
|
|
124
|
+
- `Listener` overlap on (port, protocol, hostname) with existing Gateway in same scope.
|
|
125
|
+
|
|
126
|
+
### `HTTPRoute` / `GRPCRoute` / `TLSRoute`
|
|
127
|
+
|
|
128
|
+
GA / Standard channel since Gateway API v1.1.0 (per `gateway-api.sigs.k8s.io/api-types/grpcroute`).
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
kubectl apply -f /tmp/route.yaml
|
|
132
|
+
kubectl wait --for=condition=Accepted httproute/<name> -n <ns> --timeout=1m
|
|
133
|
+
|
|
134
|
+
# Status verification — Accepted: True AND ResolvedRefs: True per parent
|
|
135
|
+
kubectl get httproute <name> -n <ns> -o jsonpath='{.status.parents}'
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Refusal triggers:
|
|
139
|
+
- Route attaches to a Gateway that is not in `Programmed: True`.
|
|
140
|
+
- `parentRefs` reference a Gateway in another namespace without a matching `ReferenceGrant`.
|
|
141
|
+
|
|
142
|
+
### `ReferenceGrant`
|
|
143
|
+
|
|
144
|
+
Cross-namespace authorization for routes. Always-additive; deletion can break in-flight routes.
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
kubectl apply -f /tmp/refgrant.yaml
|
|
148
|
+
# No status conditions; verify by querying the route's ResolvedRefs.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Cilium ClusterMesh peer Secret (medium blast radius, requires explicit human gate)
|
|
152
|
+
|
|
153
|
+
Creates a `Secret` in the Cilium namespace whose data field carries the peer cluster's etcd client certificate, key, and CA. **Never log or print the data fields.**
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Capture baseline (confirm absence)
|
|
157
|
+
kubectl get secret cilium-clustermesh -n kube-system 2>&1 | tee /tmp/clustermesh-pre.txt
|
|
158
|
+
|
|
159
|
+
# Apply the peer secret — secret data is sensitive
|
|
160
|
+
kubectl apply -f /tmp/clustermesh-peer.yaml
|
|
161
|
+
|
|
162
|
+
# Verify ClusterMesh comes up
|
|
163
|
+
kubectl exec -n kube-system ds/cilium -- cilium clustermesh status
|
|
164
|
+
|
|
165
|
+
# Rollback
|
|
166
|
+
kubectl delete secret cilium-clustermesh -n kube-system
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Refusal triggers:
|
|
170
|
+
- Secret destination namespace does not match the documented Cilium ClusterMesh namespace for this cluster.
|
|
171
|
+
- Secret name does not exactly match the peer cluster identifier.
|
|
172
|
+
- Secret data contains plaintext that looks like a CA or client key but is not properly base64-encoded for the `Secret` `data` field.
|
|
173
|
+
- ClusterMesh peer `policy-default-local-cluster` flag has not been considered (delegate to `cilium-network-policy-review-agent`).
|