0
# Authorization Reviews
1
2
This document covers OpenShift authorization review operations, including access reviews, security policy reviews, and permission validation.
3
4
## Core Imports
5
6
```java { .api }
7
import io.fabric8.openshift.client.OpenShiftClient;
8
import io.fabric8.openshift.api.model.SubjectAccessReview;
9
import io.fabric8.openshift.api.model.SubjectAccessReviewResponse;
10
import io.fabric8.openshift.api.model.ResourceAccessReview;
11
import io.fabric8.openshift.api.model.ResourceAccessReviewResponse;
12
import io.fabric8.openshift.api.model.LocalSubjectAccessReview;
13
import io.fabric8.openshift.api.model.LocalResourceAccessReview;
14
import io.fabric8.openshift.api.model.SelfSubjectRulesReview;
15
import io.fabric8.openshift.api.model.SubjectRulesReview;
16
import io.fabric8.openshift.api.model.PodSecurityPolicyReview;
17
import io.fabric8.openshift.api.model.PodSecurityPolicySelfSubjectReview;
18
import io.fabric8.openshift.api.model.PodSecurityPolicySubjectReview;
19
import io.fabric8.kubernetes.client.dsl.InOutCreateable;
20
import io.fabric8.kubernetes.client.dsl.NamespacedInOutCreateable;
21
```
22
23
## Subject Access Review Operations
24
25
Subject Access Reviews check if a specific user or service account has permission to perform an action.
26
27
### Basic Subject Access Review
28
29
```java { .api }
30
// Create subject access review to check if user can create pods
31
SubjectAccessReview review = new SubjectAccessReviewBuilder()
32
.withNewSpec()
33
.withNewResourceAttributes()
34
.withNamespace("my-project")
35
.withVerb("create")
36
.withGroup("")
37
.withResource("pods")
38
.endResourceAttributes()
39
.withUser("john.doe")
40
.endSpec()
41
.build();
42
43
SubjectAccessReviewResponse response = client.subjectAccessReviews()
44
.create(review);
45
46
boolean canCreatePods = response.getAllowed();
47
String reason = response.getReason();
48
49
System.out.println("User can create pods: " + canCreatePods);
50
if (reason != null) {
51
System.out.println("Reason: " + reason);
52
}
53
```
54
55
### Subject Access Review with Groups
56
57
```java { .api }
58
// Check access for user with specific groups
59
SubjectAccessReview groupReview = new SubjectAccessReviewBuilder()
60
.withNewSpec()
61
.withNewResourceAttributes()
62
.withNamespace("my-project")
63
.withVerb("delete")
64
.withGroup("apps")
65
.withResource("deployments")
66
.withName("my-app")
67
.endResourceAttributes()
68
.withUser("jane.smith")
69
.withGroups("developers", "team-leads")
70
.endSpec()
71
.build();
72
73
SubjectAccessReviewResponse groupResponse = client.subjectAccessReviews()
74
.create(groupReview);
75
76
System.out.println("Can delete deployment: " + groupResponse.getAllowed());
77
```
78
79
### Subject Access Review for Service Accounts
80
81
```java { .api }
82
// Check service account permissions
83
SubjectAccessReview serviceAccountReview = new SubjectAccessReviewBuilder()
84
.withNewSpec()
85
.withNewResourceAttributes()
86
.withNamespace("my-project")
87
.withVerb("get")
88
.withGroup("")
89
.withResource("secrets")
90
.endResourceAttributes()
91
.withUser("system:serviceaccount:my-project:my-service-account")
92
.endSpec()
93
.build();
94
95
SubjectAccessReviewResponse saResponse = client.subjectAccessReviews()
96
.create(serviceAccountReview);
97
98
boolean canAccessSecrets = saResponse.getAllowed();
99
```
100
101
### Non-Resource URL Access Review
102
103
```java { .api }
104
// Check access to non-resource URLs
105
SubjectAccessReview nonResourceReview = new SubjectAccessReviewBuilder()
106
.withNewSpec()
107
.withNewNonResourceAttributes()
108
.withPath("/api/v1/nodes")
109
.withVerb("get")
110
.endNonResourceAttributes()
111
.withUser("cluster-reader")
112
.endSpec()
113
.build();
114
115
SubjectAccessReviewResponse nonResourceResponse = client.subjectAccessReviews()
116
.create(nonResourceReview);
117
118
boolean canAccessNodes = nonResourceResponse.getAllowed();
119
```
120
121
## Resource Access Review Operations
122
123
Resource Access Reviews determine which users can perform actions on specific resources.
124
125
### Basic Resource Access Review
126
127
```java { .api }
128
// Find who can delete pods in a namespace
129
ResourceAccessReview resourceReview = new ResourceAccessReviewBuilder()
130
.withNewSpec()
131
.withNewResourceAttributes()
132
.withNamespace("my-project")
133
.withVerb("delete")
134
.withGroup("")
135
.withResource("pods")
136
.endResourceAttributes()
137
.endSpec()
138
.build();
139
140
ResourceAccessReviewResponse resourceResponse = client.resourceAccessReviews()
141
.create(resourceReview);
142
143
List<String> users = resourceResponse.getUsers();
144
List<String> groups = resourceResponse.getGroups();
145
146
System.out.println("Users who can delete pods: " + String.join(", ", users));
147
System.out.println("Groups who can delete pods: " + String.join(", ", groups));
148
```
149
150
### Resource Access Review for Specific Resource
151
152
```java { .api }
153
// Check who can update a specific deployment
154
ResourceAccessReview specificResourceReview = new ResourceAccessReviewBuilder()
155
.withNewSpec()
156
.withNewResourceAttributes()
157
.withNamespace("my-project")
158
.withVerb("update")
159
.withGroup("apps")
160
.withResource("deployments")
161
.withName("my-app")
162
.endResourceAttributes()
163
.endSpec()
164
.build();
165
166
ResourceAccessReviewResponse specificResponse = client.resourceAccessReviews()
167
.create(specificResourceReview);
168
169
List<String> authorizedUsers = specificResponse.getUsers();
170
```
171
172
## Local Access Review Operations
173
174
Local Access Reviews are namespace-scoped versions of access reviews.
175
176
### Local Subject Access Review
177
178
```java { .api }
179
// Check user access within specific namespace
180
LocalSubjectAccessReview localReview = new LocalSubjectAccessReviewBuilder()
181
.withNewSpec()
182
.withNewResourceAttributes()
183
.withNamespace("my-project")
184
.withVerb("create")
185
.withGroup("")
186
.withResource("configmaps")
187
.endResourceAttributes()
188
.withUser("developer-user")
189
.endSpec()
190
.build();
191
192
SubjectAccessReviewResponse localResponse = client.localSubjectAccessReviews()
193
.inNamespace("my-project")
194
.create(localReview);
195
196
boolean canCreateConfigMaps = localResponse.getAllowed();
197
```
198
199
### Local Resource Access Review
200
201
```java { .api }
202
// Find who has access to secrets in specific namespace
203
LocalResourceAccessReview localResourceReview = new LocalResourceAccessReviewBuilder()
204
.withNewSpec()
205
.withNewResourceAttributes()
206
.withNamespace("my-project")
207
.withVerb("get")
208
.withGroup("")
209
.withResource("secrets")
210
.endResourceAttributes()
211
.endSpec()
212
.build();
213
214
ResourceAccessReviewResponse localResourceResponse = client.localResourceAccessReviews()
215
.inNamespace("my-project")
216
.create(localResourceReview);
217
218
List<String> secretUsers = localResourceResponse.getUsers();
219
```
220
221
## Self Subject Rules Review Operations
222
223
Self Subject Rules Reviews show what actions the current user can perform.
224
225
### Self Subject Rules Review
226
227
```java { .api }
228
// Get current user's permissions in namespace
229
SelfSubjectRulesReview selfReview = new SelfSubjectRulesReviewBuilder()
230
.withNewSpec()
231
.withNamespace("my-project")
232
.endSpec()
233
.build();
234
235
SelfSubjectRulesReview selfResponse = client.selfSubjectRulesReviews()
236
.inNamespace("my-project")
237
.create(selfReview);
238
239
List<PolicyRule> resourceRules = selfResponse.getStatus().getResourceRules();
240
List<NonResourcePolicyRule> nonResourceRules = selfResponse.getStatus().getNonResourceRules();
241
242
System.out.println("Resource permissions:");
243
for (PolicyRule rule : resourceRules) {
244
System.out.println(" Resources: " + String.join(", ", rule.getResources()));
245
System.out.println(" Verbs: " + String.join(", ", rule.getVerbs()));
246
System.out.println(" API Groups: " + String.join(", ", rule.getApiGroups()));
247
System.out.println();
248
}
249
250
System.out.println("Non-resource permissions:");
251
for (NonResourcePolicyRule rule : nonResourceRules) {
252
System.out.println(" URLs: " + String.join(", ", rule.getNonResourceURLs()));
253
System.out.println(" Verbs: " + String.join(", ", rule.getVerbs()));
254
System.out.println();
255
}
256
```
257
258
### Subject Rules Review
259
260
```java { .api }
261
// Get specific user's permissions in namespace
262
SubjectRulesReview subjectRulesReview = new SubjectRulesReviewBuilder()
263
.withNewSpec()
264
.withNamespace("my-project")
265
.withUser("developer-user")
266
.withGroups("developers")
267
.endSpec()
268
.build();
269
270
SubjectRulesReview subjectRulesResponse = client.subjectRulesReviews()
271
.inNamespace("my-project")
272
.create(subjectRulesReview);
273
274
List<PolicyRule> userRules = subjectRulesResponse.getStatus().getResourceRules();
275
boolean incomplete = subjectRulesResponse.getStatus().getIncomplete();
276
277
if (incomplete) {
278
System.out.println("Warning: Rule list may be incomplete");
279
}
280
```
281
282
## Pod Security Policy Review Operations
283
284
Pod Security Policy Reviews validate pod specifications against security policies.
285
286
### Pod Security Policy Review
287
288
```java { .api }
289
// Review pod security policy for a pod spec
290
PodSecurityPolicyReview pspReview = new PodSecurityPolicyReviewBuilder()
291
.withNewSpec()
292
.withNewTemplate()
293
.withNewSpec()
294
.addNewContainer()
295
.withName("test-container")
296
.withImage("nginx")
297
.withNewSecurityContext()
298
.withRunAsUser(0L) // Root user
299
.withPrivileged(true)
300
.endSecurityContext()
301
.endContainer()
302
.endSpec()
303
.endTemplate()
304
.withServiceAccountNames("default")
305
.endSpec()
306
.build();
307
308
PodSecurityPolicyReview pspResponse = client.podSecurityPolicyReviews()
309
.inNamespace("my-project")
310
.create(pspReview);
311
312
List<PodSecurityPolicySubjectReviewStatus> allowedBy = pspResponse.getStatus().getAllowedBy();
313
for (PodSecurityPolicySubjectReviewStatus status : allowedBy) {
314
System.out.println("Allowed by SCC: " + status.getName());
315
System.out.println(" Template: " + status.getTemplate());
316
}
317
```
318
319
### Pod Security Policy Self Subject Review
320
321
```java { .api }
322
// Review pod security for current user
323
PodSecurityPolicySelfSubjectReview selfPspReview = new PodSecurityPolicySelfSubjectReviewBuilder()
324
.withNewSpec()
325
.withNewTemplate()
326
.withNewSpec()
327
.addNewContainer()
328
.withName("app-container")
329
.withImage("my-app:latest")
330
.withNewSecurityContext()
331
.withReadOnlyRootFilesystem(true)
332
.withRunAsNonRoot(true)
333
.endSecurityContext()
334
.endContainer()
335
.endSpec()
336
.endTemplate()
337
.endSpec()
338
.build();
339
340
PodSecurityPolicySelfSubjectReview selfPspResponse = client.podSecurityPolicySelfSubjectReviews()
341
.inNamespace("my-project")
342
.create(selfPspReview);
343
344
List<PodSecurityPolicySubjectReviewStatus> selfAllowed = selfPspResponse.getStatus().getAllowedBy();
345
```
346
347
### Pod Security Policy Subject Review
348
349
```java { .api }
350
// Review pod security for specific user/group
351
PodSecurityPolicySubjectReview subjectPspReview = new PodSecurityPolicySubjectReviewBuilder()
352
.withNewSpec()
353
.withNewTemplate()
354
.withNewSpec()
355
.addNewContainer()
356
.withName("privileged-container")
357
.withImage("system-app:latest")
358
.withNewSecurityContext()
359
.withPrivileged(true)
360
.withRunAsUser(0L)
361
.endSecurityContext()
362
.endContainer()
363
.addNewVolume()
364
.withName("host-volume")
365
.withNewHostPath()
366
.withPath("/var/lib/data")
367
.endHostPath()
368
.endVolume()
369
.endSpec()
370
.endTemplate()
371
.withUser("system-admin")
372
.withGroups("system:authenticated")
373
.endSpec()
374
.build();
375
376
PodSecurityPolicySubjectReview subjectPspResponse = client.podSecurityPolicySubjectReviews()
377
.inNamespace("my-project")
378
.create(subjectPspReview);
379
380
List<PodSecurityPolicySubjectReviewStatus> subjectAllowed = subjectPspResponse.getStatus().getAllowedBy();
381
```
382
383
## Advanced Authorization Operations
384
385
### Batch Permission Checking
386
387
```java { .api }
388
public class PermissionChecker {
389
private final OpenShiftClient client;
390
391
public PermissionChecker(OpenShiftClient client) {
392
this.client = client;
393
}
394
395
public Map<String, Boolean> checkMultiplePermissions(String user, String namespace,
396
Map<String, String[]> permissions) {
397
Map<String, Boolean> results = new HashMap<>();
398
399
for (Map.Entry<String, String[]> entry : permissions.entrySet()) {
400
String resource = entry.getKey();
401
String[] verbs = entry.getValue();
402
403
for (String verb : verbs) {
404
String permissionKey = resource + ":" + verb;
405
406
SubjectAccessReview review = new SubjectAccessReviewBuilder()
407
.withNewSpec()
408
.withNewResourceAttributes()
409
.withNamespace(namespace)
410
.withVerb(verb)
411
.withResource(resource)
412
.withGroup("")
413
.endResourceAttributes()
414
.withUser(user)
415
.endSpec()
416
.build();
417
418
SubjectAccessReviewResponse response = client.subjectAccessReviews()
419
.create(review);
420
421
results.put(permissionKey, response.getAllowed());
422
}
423
}
424
425
return results;
426
}
427
}
428
```
429
430
### Permission Audit
431
432
```java { .api }
433
public class PermissionAuditor {
434
private final OpenShiftClient client;
435
436
public PermissionAuditor(OpenShiftClient client) {
437
this.client = client;
438
}
439
440
public void auditNamespacePermissions(String namespace) {
441
System.out.println("=== Permission Audit for Namespace: " + namespace + " ===\n");
442
443
// Audit who can perform critical operations
444
String[] criticalActions = {"delete", "update", "patch"};
445
String[] criticalResources = {"pods", "services", "secrets", "configmaps"};
446
447
for (String resource : criticalResources) {
448
System.out.println("Resource: " + resource);
449
450
for (String action : criticalActions) {
451
ResourceAccessReview review = new ResourceAccessReviewBuilder()
452
.withNewSpec()
453
.withNewResourceAttributes()
454
.withNamespace(namespace)
455
.withVerb(action)
456
.withGroup("")
457
.withResource(resource)
458
.endResourceAttributes()
459
.endSpec()
460
.build();
461
462
ResourceAccessReviewResponse response = client.resourceAccessReviews()
463
.create(review);
464
465
System.out.println(" " + action + ": " +
466
"users=" + response.getUsers().size() +
467
", groups=" + response.getGroups().size());
468
}
469
System.out.println();
470
}
471
}
472
473
public void auditUserPermissions(String user, String namespace) {
474
System.out.println("=== User Permission Audit: " + user + " ===\n");
475
476
SelfSubjectRulesReview rulesReview = new SelfSubjectRulesReviewBuilder()
477
.withNewSpec()
478
.withNamespace(namespace)
479
.endSpec()
480
.build();
481
482
// Note: This would need to be done with proper user context
483
// For demonstration, we'll check specific permissions
484
485
String[] commonResources = {"pods", "services", "deployments", "secrets"};
486
String[] commonVerbs = {"get", "list", "create", "update", "delete"};
487
488
for (String resource : commonResources) {
489
System.out.println("Resource: " + resource);
490
491
for (String verb : commonVerbs) {
492
SubjectAccessReview review = new SubjectAccessReviewBuilder()
493
.withNewSpec()
494
.withNewResourceAttributes()
495
.withNamespace(namespace)
496
.withVerb(verb)
497
.withGroup("")
498
.withResource(resource)
499
.endResourceAttributes()
500
.withUser(user)
501
.endSpec()
502
.build();
503
504
SubjectAccessReviewResponse response = client.subjectAccessReviews()
505
.create(review);
506
507
System.out.print(" " + verb + ": " +
508
(response.getAllowed() ? "✓" : "✗"));
509
}
510
System.out.println();
511
}
512
}
513
}
514
```
515
516
## Usage Examples
517
518
### Complete Authorization Validation Example
519
520
```java
521
import io.fabric8.openshift.client.OpenShiftClient;
522
import io.fabric8.openshift.api.model.*;
523
524
public class AuthorizationValidator {
525
private final OpenShiftClient client;
526
527
public AuthorizationValidator(OpenShiftClient client) {
528
this.client = client;
529
}
530
531
public boolean validateDeploymentPermissions(String user, String namespace,
532
String deploymentName) {
533
System.out.println("Validating deployment permissions for user: " + user);
534
535
// Required permissions for deployment management
536
String[][] requiredPermissions = {
537
{"deployments", "get"},
538
{"deployments", "update"},
539
{"deployments", "patch"},
540
{"replicasets", "get"},
541
{"replicasets", "list"},
542
{"pods", "get"},
543
{"pods", "list"}
544
};
545
546
boolean allPermissionsGranted = true;
547
548
for (String[] permission : requiredPermissions) {
549
String resource = permission[0];
550
String verb = permission[1];
551
552
SubjectAccessReview review = new SubjectAccessReviewBuilder()
553
.withNewSpec()
554
.withNewResourceAttributes()
555
.withNamespace(namespace)
556
.withVerb(verb)
557
.withGroup("apps")
558
.withResource(resource)
559
.withName(deploymentName)
560
.endResourceAttributes()
561
.withUser(user)
562
.endSpec()
563
.build();
564
565
SubjectAccessReviewResponse response = client.subjectAccessReviews()
566
.create(review);
567
568
if (!response.getAllowed()) {
569
System.out.println(" ✗ Missing permission: " + verb + " " + resource);
570
allPermissionsGranted = false;
571
} else {
572
System.out.println(" ✓ Has permission: " + verb + " " + resource);
573
}
574
}
575
576
return allPermissionsGranted;
577
}
578
579
public SecurityValidationResult validatePodSecurity(PodSpec podSpec,
580
String namespace) {
581
PodSecurityPolicyReview review = new PodSecurityPolicyReviewBuilder()
582
.withNewSpec()
583
.withNewTemplate()
584
.withSpec(podSpec)
585
.endTemplate()
586
.withServiceAccountNames("default")
587
.endSpec()
588
.build();
589
590
PodSecurityPolicyReview response = client.podSecurityPolicyReviews()
591
.inNamespace(namespace)
592
.create(review);
593
594
SecurityValidationResult result = new SecurityValidationResult();
595
result.setAllowed(!response.getStatus().getAllowedBy().isEmpty());
596
597
if (result.isAllowed()) {
598
List<String> allowedBySCCs = response.getStatus().getAllowedBy().stream()
599
.map(PodSecurityPolicySubjectReviewStatus::getName)
600
.collect(Collectors.toList());
601
result.setAllowedBySCCs(allowedBySCCs);
602
}
603
604
return result;
605
}
606
607
public List<String> getUsersWithAccess(String namespace, String resource, String verb) {
608
ResourceAccessReview review = new ResourceAccessReviewBuilder()
609
.withNewSpec()
610
.withNewResourceAttributes()
611
.withNamespace(namespace)
612
.withVerb(verb)
613
.withGroup("")
614
.withResource(resource)
615
.endResourceAttributes()
616
.endSpec()
617
.build();
618
619
ResourceAccessReviewResponse response = client.resourceAccessReviews()
620
.create(review);
621
622
return response.getUsers();
623
}
624
625
public static class SecurityValidationResult {
626
private boolean allowed;
627
private List<String> allowedBySCCs = new ArrayList<>();
628
629
// Getters and setters
630
public boolean isAllowed() { return allowed; }
631
public void setAllowed(boolean allowed) { this.allowed = allowed; }
632
public List<String> getAllowedBySCCs() { return allowedBySCCs; }
633
public void setAllowedBySCCs(List<String> allowedBySCCs) { this.allowedBySCCs = allowedBySCCs; }
634
}
635
}
636
```
637
638
## Types
639
640
### Access Review Types
641
642
```java { .api }
643
public class SubjectAccessReview implements HasMetadata {
644
public ObjectMeta getMetadata();
645
public SubjectAccessReviewSpec getSpec();
646
}
647
648
public class SubjectAccessReviewSpec {
649
public ResourceAttributes getResourceAttributes();
650
public NonResourceAttributes getNonResourceAttributes();
651
public String getUser();
652
public List<String> getGroups();
653
public Map<String, List<String>> getExtra();
654
}
655
656
public class SubjectAccessReviewResponse {
657
public Boolean getAllowed();
658
public String getDenied();
659
public String getReason();
660
public String getEvaluationError();
661
}
662
663
public class ResourceAttributes {
664
public String getNamespace();
665
public String getVerb();
666
public String getGroup();
667
public String getVersion();
668
public String getResource();
669
public String getSubresource();
670
public String getName();
671
}
672
673
public class NonResourceAttributes {
674
public String getPath();
675
public String getVerb();
676
}
677
```
678
679
### Resource Access Review Types
680
681
```java { .api }
682
public class ResourceAccessReview implements HasMetadata {
683
public ObjectMeta getMetadata();
684
public ResourceAccessReviewSpec getSpec();
685
}
686
687
public class ResourceAccessReviewResponse {
688
public List<String> getUsers();
689
public List<String> getGroups();
690
}
691
```
692
693
### Rules Review Types
694
695
```java { .api }
696
public class SelfSubjectRulesReview implements HasMetadata {
697
public ObjectMeta getMetadata();
698
public SelfSubjectRulesReviewSpec getSpec();
699
public SubjectRulesReviewStatus getStatus();
700
}
701
702
public class SubjectRulesReviewStatus {
703
public List<PolicyRule> getResourceRules();
704
public List<NonResourcePolicyRule> getNonResourceRules();
705
public Boolean getIncomplete();
706
public String getEvaluationError();
707
}
708
709
public class PolicyRule {
710
public List<String> getVerbs();
711
public List<String> getApiGroups();
712
public List<String> getResources();
713
public List<String> getResourceNames();
714
}
715
716
public class NonResourcePolicyRule {
717
public List<String> getVerbs();
718
public List<String> getNonResourceURLs();
719
}
720
```
721
722
### Pod Security Policy Review Types
723
724
```java { .api }
725
public class PodSecurityPolicyReview implements HasMetadata {
726
public ObjectMeta getMetadata();
727
public PodSecurityPolicyReviewSpec getSpec();
728
public PodSecurityPolicyReviewStatus getStatus();
729
}
730
731
public class PodSecurityPolicyReviewSpec {
732
public PodTemplateSpec getTemplate();
733
public List<String> getServiceAccountNames();
734
}
735
736
public class PodSecurityPolicyReviewStatus {
737
public List<PodSecurityPolicySubjectReviewStatus> getAllowedBy();
738
}
739
740
public class PodSecurityPolicySubjectReviewStatus {
741
public String getName();
742
public PodTemplateSpec getTemplate();
743
}
744
```