-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathclusterrole.yaml
More file actions
134 lines (122 loc) · 5.69 KB
/
Copy pathclusterrole.yaml
File metadata and controls
134 lines (122 loc) · 5.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# 5-Spot Controller ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: 5spot-controller
labels:
app.kubernetes.io/name: 5spot
app.kubernetes.io/component: controller
rules:
# ScheduledMachine CRD management
- apiGroups: ["5spot.finos.org"]
resources: ["scheduledmachines", "scheduledmachines/status"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# ScheduledMachine finalizers — required because the controller sets
# `blockOwnerDeletion: true` on the ownerReference it writes from every
# child CAPI Machine back to its parent ScheduledMachine
# (src/reconcilers/helpers.rs). The API server treats blockOwnerDeletion
# as equivalent to holding a finalizer on the owner, so it checks that
# the creating identity has `update` on <owner-resource>/finalizers.
# Without this rule, Machine creation is rejected with:
# cannot set blockOwnerDeletion if an ownerReference refers to a
# resource you can't set finalizers on
# Verb is intentionally just `update` — the minimum the subresource
# check requires; the broader CRUD set on the main resource above is
# not needed here.
- apiGroups: ["5spot.finos.org"]
resources: ["scheduledmachines/finalizers"]
verbs: ["update"]
# CAPI Machine management
- apiGroups: ["cluster.x-k8s.io"]
resources: ["machines", "machines/status"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Bootstrap provider resources (wildcard required — controller is provider-agnostic
# and must support any CAPI bootstrap provider installed in the cluster)
- apiGroups: ["bootstrap.cluster.x-k8s.io"]
resources: ["*"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Infrastructure provider resources (wildcard required — provider-agnostic)
- apiGroups: ["infrastructure.cluster.x-k8s.io"]
resources: ["*"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# k0smotron resources — explicitly enumerated (known provider)
- apiGroups: ["k0smotron.io"]
resources:
- "k0sworkerconfigs"
- "k0sworkerconfigs/status"
- "remotemachines"
- "remotemachines/status"
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Events for recording reconciliation events (core v1 and events.k8s.io/v1)
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "patch"]
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["create", "patch"]
# Secrets for SSH keys, bootstrap data, and child-cluster kubeconfigs.
#
# Read-only. Also covers reading a `kata` source Secret on the workload
# cluster in the degenerate co-located case (ADR 0002); in true multi-cluster
# that read rides the kubeconfig identity. The controller never writes
# Secrets, so no create/patch/delete here.
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch"]
# ConfigMaps — read-only.
#
# `get` is the kata source-object existence probe (ADR 0002): the controller
# checks that the referenced source ConfigMap exists, then stamps a Node label
# + reference annotation. The node-side agent — not the controller — reads the
# source and writes the host drop-in, so the controller never writes a kata
# ConfigMap.
#
# The reclaim-agent per-node ConfigMap projection (`reclaim-agent-<node>`) does
# write ConfigMaps, but on the workload cluster via the resolved
# `kubeconfig-<clusterName>` child-cluster identity — not this controller
# token. This matches the posture that shipped with reclaim: before the kata
# branch this ClusterRole had no `configmaps` rule at all. Keeping write verbs
# off the controller ServiceAccount preserves least privilege and avoids the
# Trivy KSV-0049 finding entirely (no suppression needed).
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get"]
# Namespaces — read-only. The `kata` fail-fast probe distinguishes a missing
# source object from a missing target namespace (ADR 0002). In the degenerate
# co-located case this uses the controller SA; in multi-cluster it rides the
# kubeconfig identity.
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get"]
# Nodes for drain operations and reclaim-agent label / taint management.
#
# `update` was removed in Phase 5 of the 2026-04-25 security audit
# roadmap. Every Node touchpoint in the controller uses `.get` or
# `.patch` (cordon, reclaim-agent label, applied taints) — no path
# uses `Api::replace` or any other update-shaped call. Granting only
# the verbs that are actually exercised reduces blast radius if the
# controller's ServiceAccount token is ever compromised. If a future
# change reintroduces a need for full-object replacement, the lint
# rule in `deny.toml` will surface it before this rule has to be
# widened.
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch", "patch"]
# Pods for eviction during drain
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "delete"]
- apiGroups: [""]
resources: ["pods/eviction"]
verbs: ["create"]
# Leases for leader election (no delete needed for HA).
#
# `update` is retained: `kube_lease_manager` (the leader-election
# library used in src/main.rs) currently uses HTTP PUT semantics
# (Api::replace) on the Lease object during renewal. Removing
# `update` would break leader election. If the upstream library
# switches to merge-patch in a future release we can drop the verb;
# tracked alongside Phase 5 of the security audit roadmap.
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update", "patch"]