Skip to content

Commit 0977141

Browse files
authored
Merge pull request #4940 from muraee/rosa-external-oidc-docs
🐛 ROSA: Fix missing permissions & Add external OIDC docs
2 parents f20c52d + 0db3858 commit 0977141

File tree

9 files changed

+217
-24
lines changed

9 files changed

+217
-24
lines changed

config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -335,13 +335,12 @@ spec:
335335
If unset, system trust is used instead.
336336
properties:
337337
name:
338-
description: |-
339-
Name of the referent.
340-
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
341-
TODO: Add other useful fields. apiVersion, kind, uid?
338+
description: Name is the metadata.name of the referenced
339+
object.
342340
type: string
341+
required:
342+
- name
343343
type: object
344-
x-kubernetes-map-type: atomic
345344
issuerURL:
346345
description: |-
347346
URL is the serving URL of the token issuer.
@@ -376,15 +375,12 @@ spec:
376375
contains the client secret in the `clientSecret` key of the `.data` field
377376
properties:
378377
name:
379-
description: name is unique within a namespace to
380-
reference a secret resource.
381-
type: string
382-
namespace:
383-
description: namespace defines the space within which
384-
the secret name must be unique.
378+
description: Name is the metadata.name of the referenced
379+
object.
385380
type: string
381+
required:
382+
- name
386383
type: object
387-
x-kubernetes-map-type: atomic
388384
componentName:
389385
description: |-
390386
ComponentName is the name of the component that is supposed to consume this

config/rbac/role.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ kind: ClusterRole
44
metadata:
55
name: manager-role
66
rules:
7+
- apiGroups:
8+
- ""
9+
resources:
10+
- configmaps
11+
verbs:
12+
- create
13+
- delete
14+
- get
15+
- list
16+
- patch
17+
- update
18+
- watch
719
- apiGroups:
820
- ""
921
resources:

controlplane/rosa/api/v1beta2/external_auth_types.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package v1beta2
22

3-
import corev1 "k8s.io/api/core/v1"
4-
53
// ExternalAuthProvider is an external OIDC identity provider that can issue tokens for this cluster
64
type ExternalAuthProvider struct {
75
// Name of the OIDC provider
@@ -68,7 +66,7 @@ type TokenIssuer struct {
6866
// configuration namespace. The .data of the configMap must contain
6967
// the "ca-bundle.crt" key.
7068
// If unset, system trust is used instead.
71-
CertificateAuthority *corev1.LocalObjectReference `json:"issuerCertificateAuthority,omitempty"`
69+
CertificateAuthority *LocalObjectReference `json:"issuerCertificateAuthority,omitempty"`
7270
}
7371

7472
// OIDCClientConfig contains configuration for the platform's client that
@@ -101,7 +99,7 @@ type OIDCClientConfig struct {
10199

102100
// ClientSecret refers to a secret that
103101
// contains the client secret in the `clientSecret` key of the `.data` field
104-
ClientSecret corev1.SecretReference `json:"clientSecret"` //TODO: required or optional?
102+
ClientSecret LocalObjectReference `json:"clientSecret"`
105103

106104
// ExtraScopes is an optional set of scopes to request tokens with.
107105
//
@@ -240,3 +238,12 @@ type TokenRequiredClaim struct {
240238
// +required
241239
RequiredValue string `json:"requiredValue"`
242240
}
241+
242+
// LocalObjectReference references an object in the same namespace.
243+
type LocalObjectReference struct {
244+
// Name is the metadata.name of the referenced object.
245+
//
246+
// +kubebuilder:validation:Required
247+
// +required
248+
Name string `json:"name"`
249+
}

controlplane/rosa/api/v1beta2/zz_generated.deepcopy.go

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

controlplane/rosa/controllers/rosacontrolplane_controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ func (r *ROSAControlPlaneReconciler) SetupWithManager(ctx context.Context, mgr c
121121

122122
// +kubebuilder:rbac:groups=core,resources=events,verbs=get;list;watch;create;patch
123123
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;delete;patch
124+
// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;delete;patch
124125
// +kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;watch
125126
// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters;clusters/status,verbs=get;list;watch
126127
// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machinedeployments,verbs=get;list;watch

docs/book/src/SUMMARY_PREFIX.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- [Creating a cluster](./topics/rosa/creating-a-cluster.md)
2727
- [Creating MachinePools](./topics/rosa/creating-rosa-machinepools.md)
2828
- [Upgrades](./topics/rosa/upgrades.md)
29+
- [External Auth Providers](./topics/rosa/external-auth.md)
2930
- [Bring Your Own AWS Infrastructure](./topics/bring-your-own-aws-infrastructure.md)
3031
- [Specifying the IAM Role to use for Management Components](./topics/specify-management-iam-role.md)
3132
- [Using external cloud provider with EBS CSI driver](./topics/external-cloud-provider-with-ebs-csi-driver.md)

docs/book/src/crd/index.md

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8635,6 +8635,35 @@ ID token into a cluster identity</p>
86358635
</tr>
86368636
</tbody>
86378637
</table>
8638+
<h3 id="controlplane.cluster.x-k8s.io/v1beta2.LocalObjectReference">LocalObjectReference
8639+
</h3>
8640+
<p>
8641+
(<em>Appears on:</em><a href="#controlplane.cluster.x-k8s.io/v1beta2.OIDCClientConfig">OIDCClientConfig</a>, <a href="#controlplane.cluster.x-k8s.io/v1beta2.TokenIssuer">TokenIssuer</a>)
8642+
</p>
8643+
<p>
8644+
<p>LocalObjectReference references an object in the same namespace.</p>
8645+
</p>
8646+
<table>
8647+
<thead>
8648+
<tr>
8649+
<th>Field</th>
8650+
<th>Description</th>
8651+
</tr>
8652+
</thead>
8653+
<tbody>
8654+
<tr>
8655+
<td>
8656+
<code>name</code><br/>
8657+
<em>
8658+
string
8659+
</em>
8660+
</td>
8661+
<td>
8662+
<p>Name is the metadata.name of the referenced object.</p>
8663+
</td>
8664+
</tr>
8665+
</tbody>
8666+
</table>
86388667
<h3 id="controlplane.cluster.x-k8s.io/v1beta2.NetworkSpec">NetworkSpec
86398668
</h3>
86408669
<p>
@@ -8769,8 +8798,8 @@ string
87698798
<td>
87708799
<code>clientSecret</code><br/>
87718800
<em>
8772-
<a href="https://v1-18.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#secretreference-v1-core">
8773-
Kubernetes core/v1.SecretReference
8801+
<a href="#controlplane.cluster.x-k8s.io/v1beta2.LocalObjectReference">
8802+
LocalObjectReference
87748803
</a>
87758804
</em>
87768805
</td>
@@ -9702,8 +9731,7 @@ private node communication with the control plane.</p>
97029731
(<em>Appears on:</em><a href="#controlplane.cluster.x-k8s.io/v1beta2.TokenIssuer">TokenIssuer</a>)
97039732
</p>
97049733
<p>
9705-
<pre><code>TokenAudience is the audience that the token was issued for.
9706-
</code></pre>
9734+
<p>TokenAudience is the audience that the token was issued for.</p>
97079735
</p>
97089736
<h3 id="controlplane.cluster.x-k8s.io/v1beta2.TokenClaimMappings">TokenClaimMappings
97099737
</h3>
@@ -9848,8 +9876,8 @@ Must be set to exactly one value.</p>
98489876
<td>
98499877
<code>issuerCertificateAuthority</code><br/>
98509878
<em>
9851-
<a href="https://v1-18.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#localobjectreference-v1-core">
9852-
Kubernetes core/v1.LocalObjectReference
9879+
<a href="#controlplane.cluster.x-k8s.io/v1beta2.LocalObjectReference">
9880+
LocalObjectReference
98539881
</a>
98549882
</em>
98559883
</td>
@@ -10001,6 +10029,25 @@ string
1000110029
<p>
1000210030
<p>UsernamePrefixPolicy specifies how a prefix should apply.</p>
1000310031
</p>
10032+
<table>
10033+
<thead>
10034+
<tr>
10035+
<th>Value</th>
10036+
<th>Description</th>
10037+
</tr>
10038+
</thead>
10039+
<tbody><tr><td><p>&#34;&#34;</p></td>
10040+
<td><p>NoOpinion let&rsquo;s the cluster assign prefixes. If the username claim is email, there is no prefix
10041+
If the username claim is anything else, it is prefixed by the issuerURL</p>
10042+
</td>
10043+
</tr><tr><td><p>&#34;NoPrefix&#34;</p></td>
10044+
<td><p>NoPrefix means the username claim value will not have any prefix</p>
10045+
</td>
10046+
</tr><tr><td><p>&#34;Prefix&#34;</p></td>
10047+
<td><p>Prefix means the prefix value must be specified. It cannot be empty</p>
10048+
</td>
10049+
</tr></tbody>
10050+
</table>
1000410051
<hr/>
1000510052
<h2 id="infrastructure.cluster.x-k8s.io/v1beta1">infrastructure.cluster.x-k8s.io/v1beta1</h2>
1000610053
<p>
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# External Auth Providers (BYOI)
2+
3+
ROSA allows you to Bring Your Own Identity (BYOI) to manage and authenticate cluster users.
4+
5+
## Enabling
6+
7+
To enable this feature, `enableExternalAuthProviders` field should be set to `true` on cluster creation. Changing this field afterwards will have no effect:
8+
```yaml
9+
---
10+
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
11+
kind: ROSAControlPlane
12+
metadata:
13+
name: "capi-rosa-quickstart-control-plane"
14+
spec:
15+
enableExternalAuthProviders: true
16+
....
17+
```
18+
19+
Note: This feauture requires OpenShift version `4.15.5` or newer.
20+
21+
## Usage
22+
23+
After creating and configuring your OIDC provider of choice, the next step is to configure ROSAControlPlane `externalAuthProviders` as follows:
24+
```yaml
25+
---
26+
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
27+
kind: ROSAControlPlane
28+
metadata:
29+
name: "capi-rosa-quickstart-control-plane"
30+
spec:
31+
enableExternalAuthProviders: true
32+
externalAuthProviders:
33+
- name: my-oidc-provider
34+
issuer:
35+
issuerURL: https://login.microsoftonline.com/<tenant-id>/v2.0 # e.g. if using Microsoft Entra ID
36+
audiences: # audiences that will be trusted by the kube-apiserver
37+
- "audience1" # usually the client ID
38+
claimMappings:
39+
username:
40+
claim: email
41+
prefixPolicy: ""
42+
groups:
43+
claim: groups
44+
....
45+
```
46+
47+
Note: `oidcProviders` only accepts one entry at the moment.
48+
49+
## Accessing the cluster
50+
51+
### Setting up RBAC
52+
53+
When `enableExternalAuthProviders` is set to `true`, ROSA provider will generate a temporary admin kubeconfig secret in the same namespace named `<cluster-name>-bootstrap-kubeconfig`. This kubeconfig can be used to access the cluster to setup RBAC for OIDC users/groups.
54+
55+
The following example binds the `cluster-admin` role to an OIDC group, giving all users in that group admin permissions.
56+
```shell
57+
kubectl get secret <cluster-name>-bootstrap-kubeconfig -o jsonpath='{.data.value}' | base64 -d > /tmp/capi-admin-kubeconfig
58+
export KUBECONFIG=/tmp/capi-admin-kubeconfig
59+
60+
kubectl create clusterrolebinding oidc-cluster-admins --clusterrole cluster-admin --group <group-id>
61+
```
62+
63+
Note: The generated bootstrap kubeconfig is only valid for 24h, and will not be usable afterwards. However, users can opt to manually delete the secret object to trigger the generation of a new one which will be valid for another 24h.
64+
65+
### Login using the cli
66+
67+
The [kubelogin kubectl plugin](https://github.com/int128/kubelogin/tree/master) can be used to login with OIDC credentials using the cli.
68+
69+
### Configuring OpenShift Console
70+
71+
The OpenShift Console needs to be configured before it can be used to authenticate and login to the cluster.
72+
1. Setup a new client in your OIDC provider with the following Redirect URL: `<console-url>/auth/callback`. You can find the console URL in the status field of the `ROSAControlPlane` once the cluster is ready:
73+
```shell
74+
kubectl get rosacontrolplane <control-plane-name> -o jsonpath='{.status.consoleURL}'
75+
```
76+
77+
2. Create a new client secret in your OIDC provider and store the value in a kubernetes secret in the same namespace as your cluster:
78+
```shell
79+
kubectl create secret generic console-client-secret --from-literal=clientSecret='<client-secret-value>'
80+
```
81+
82+
3. Configure `ROSAControlPlane` external auth provider with the created client:
83+
```yaml
84+
---
85+
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
86+
kind: ROSAControlPlane
87+
metadata:
88+
name: "capi-rosa-quickstart-control-plane"
89+
spec:
90+
enableExternalAuthProviders: true
91+
externalAuthProviders:
92+
- name: my-oidc-provider
93+
issuer:
94+
issuerURL: https://login.microsoftonline.com/<tenant-id>/v2.0 # e.g. if using Microsoft Entra ID
95+
audiences: # audiences that will be trusted by the kube-apiserver
96+
- "audience1"
97+
- <console-client-id> # <----New
98+
claimMappings:
99+
username:
100+
claim: email
101+
prefixPolicy: ""
102+
groups:
103+
claim: groups
104+
oidcClients: # <----New
105+
- componentName: console
106+
componentNamespace: openshift-console
107+
clientID: <console-client-id>
108+
clientSecret:
109+
name: console-client-secret # secret name created in step 2
110+
....
111+
```
112+
113+
see [ROSAControlPlane CRD Reference](https://cluster-api-aws.sigs.k8s.io/crd/#controlplane.cluster.x-k8s.io/v1beta2.ExternalAuthProvider) for all possible configurations.

docs/book/src/topics/rosa/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ A new template is available in the templates folder for creating a managed ROSA
2121
* [Enabling ROSA Support](enabling.md)
2222
* [Creating a cluster](creating-a-cluster.md)
2323
* [Creating MachinePools](creating-rosa-machinepools.md)
24-
* [Upgrades](upgrades.md)
24+
* [Upgrades](upgrades.md)
25+
* [External Auth Providers](external-auth.md)

0 commit comments

Comments
 (0)