Skip to content

Commit d310b61

Browse files
kvapsclaude
andcommitted
feat(rbac): satellite ServiceAccount + ClusterRole (Phase 10.1)
The contract for the satellite-as-controller-runtime migration: RBAC the satellite needs once it watches the apiserver directly instead of going through the controller's gRPC. Verbs follow least privilege — - read-only on RG / RD / Node / Snapshot / ControllerConfig (consumed inputs) - read+update+patch on Resource (Spec mutations and finalizer) - read+update+patch on Resource/StoragePool/Node/Snapshot/ PhysicalDevice */status (observed-state writes via Status subresource + SSA field manager from Phase 10.2) - full CRUD on PhysicalDevice (discovery loop publishes / deletes-on-attach) - read on Secrets (LUKS passphrase + DRBD shared-secret fetched on reconcile rather than mounted, so rotation doesn't need a DaemonSet restart) - emit Events for `kubectl describe`-driven debugging - leader-election Leases scoped per node-name The role doesn't take effect until Phase 10.1 promotes the satellite agent to a controller-runtime manager — until then the satellite still gets its inputs via the controller's gRPC and this role is dormant. Pinning the contract early lets ops/Helm charts stage the deployment side without waiting for the code side. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
1 parent 89cf947 commit d310b61

2 files changed

Lines changed: 151 additions & 0 deletions

File tree

config/rbac/kustomization.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@ resources:
4343
- node_admin_role.yaml
4444
- node_editor_role.yaml
4545
- node_viewer_role.yaml
46+
# Phase 10.1: ClusterRole + ServiceAccount + binding the satellite
47+
# DaemonSet (or controller-runtime-promoted satellite agent) uses
48+
# to watch the apiserver directly. ClusterRoleBinding subjects'
49+
# namespace is patched at deploy time.
50+
- satellite_role.yaml
4651

config/rbac/satellite_role.yaml

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
---
2+
# Phase 10.1 satellite-side RBAC. The satellite — once promoted to a
3+
# controller-runtime controller in Phase 10.1 — watches the apiserver
4+
# directly for the CRDs it acts on. Until that lands the satellite
5+
# still talks to the controller via gRPC; this role is the contract
6+
# the migration moves to.
7+
#
8+
# Verbs follow the principle of least privilege:
9+
# - read-only on resources the satellite consumes (RG, RD, Node, Snapshot, ControllerConfig).
10+
# - write on Resource (own finalizer) + Resource/status (observed state).
11+
# - write on StoragePool/status (capacity reports).
12+
# - write on PhysicalDevice + PhysicalDevice/status (discovery loop publishes
13+
# and consumes).
14+
# - read on Secret (LUKS passphrase + DRBD shared secret are stored as
15+
# Secrets in the controller's namespace; the satellite mounts them
16+
# as in-cluster reads via the apiserver, not via volume mounts —
17+
# volume mounts would require restart on rotation).
18+
apiVersion: rbac.authorization.k8s.io/v1
19+
kind: ClusterRole
20+
metadata:
21+
name: satellite-role
22+
rules:
23+
- apiGroups:
24+
- blockstor.io.blockstor.io
25+
resources:
26+
- resourcegroups
27+
- resourcedefinitions
28+
- nodes
29+
- snapshots
30+
- controllerconfigs
31+
verbs:
32+
- get
33+
- list
34+
- watch
35+
- apiGroups:
36+
- blockstor.io.blockstor.io
37+
resources:
38+
- resources
39+
verbs:
40+
- get
41+
- list
42+
- watch
43+
- update
44+
- patch
45+
- apiGroups:
46+
- blockstor.io.blockstor.io
47+
resources:
48+
- resources/finalizers
49+
verbs:
50+
- update
51+
- apiGroups:
52+
- blockstor.io.blockstor.io
53+
resources:
54+
- resources/status
55+
- storagepools/status
56+
- nodes/status
57+
- snapshots/status
58+
- physicaldevices/status
59+
verbs:
60+
- get
61+
- update
62+
- patch
63+
- apiGroups:
64+
- blockstor.io.blockstor.io
65+
resources:
66+
- storagepools
67+
verbs:
68+
- get
69+
- list
70+
- watch
71+
- update
72+
- patch
73+
- apiGroups:
74+
- blockstor.io.blockstor.io
75+
resources:
76+
- physicaldevices
77+
verbs:
78+
- create
79+
- delete
80+
- get
81+
- list
82+
- patch
83+
- update
84+
- watch
85+
# Secrets — read-only access to the controller's namespace where
86+
# DRBD shared secrets and LUKS passphrases live. Limited to specific
87+
# names via a Role binding in the deployment manifest (the
88+
# ClusterRole only enumerates the verbs).
89+
- apiGroups:
90+
- ""
91+
resources:
92+
- secrets
93+
verbs:
94+
- get
95+
- list
96+
- watch
97+
# Events — emit per-Resource events the operator can `kubectl
98+
# describe` to debug a stuck reconcile.
99+
- apiGroups:
100+
- ""
101+
resources:
102+
- events
103+
verbs:
104+
- create
105+
- patch
106+
# Leader election — the satellite is per-node singleton via host
107+
# DaemonSet, so leader election is technically optional, but the
108+
# controller-runtime manager wires it by default. Use a Lease per
109+
# node-name to keep the locking blast radius scoped.
110+
- apiGroups:
111+
- coordination.k8s.io
112+
resources:
113+
- leases
114+
verbs:
115+
- get
116+
- list
117+
- watch
118+
- create
119+
- update
120+
- patch
121+
- delete
122+
---
123+
apiVersion: v1
124+
kind: ServiceAccount
125+
metadata:
126+
name: blockstor-satellite
127+
# The DaemonSet that runs the satellite mounts this ServiceAccount;
128+
# populated when the deployment manifest is generated in Phase
129+
# 10.1. namespace is controller-managed.
130+
---
131+
# Cluster-wide binding: satellite needs to read RGs / RDs / Nodes
132+
# everywhere because Resource placement is a cross-namespace concern
133+
# (Nodes are cluster-scoped CRDs; the controller-managed namespace
134+
# is irrelevant to a satellite that just reads them).
135+
apiVersion: rbac.authorization.k8s.io/v1
136+
kind: ClusterRoleBinding
137+
metadata:
138+
name: blockstor-satellite-rolebinding
139+
subjects:
140+
- kind: ServiceAccount
141+
name: blockstor-satellite
142+
# namespace populated at deploy time
143+
roleRef:
144+
apiGroup: rbac.authorization.k8s.io
145+
kind: ClusterRole
146+
name: satellite-role

0 commit comments

Comments
 (0)