|
| 1 | +# OpenID Connect Authentication |
| 2 | + |
| 3 | +By default, OKE clusters are set up to authenticate individuals (human users, groups or service principals) accessing the API endpoint using OCI Identity and Access Management (IAM). |
| 4 | + |
| 5 | +Using OKE OIDC Authentication, we can authenticate OKE API Endpoint requests (from human users or service principals) using tokens issued by third-party Identity Providers without the need for federation with OCI IAM. |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | + |
| 9 | +Note the following prerequisites for enabling a cluster for OIDC authentication: |
| 10 | + |
| 11 | +- The cluster must be an enhanced cluster. OIDC authentication is not supported for basic clusters. |
| 12 | +- The cluster must be running Kubernetes version 1.21 (or later) -- for single external OIDC IdP setup. |
| 13 | +- The cluster must be running Kubernetes version 1.30 (or later) -- for multiple external OIDC IdPs setup. |
| 14 | + |
| 15 | +## Configuration |
| 16 | + |
| 17 | +In addition to the implicit OCI IAM, you can configure the OKE cluster to authenticate the cluster API endpoint requests using a **single** external OIDC (OpenID Connect) Identity Provider (IdP). |
| 18 | + |
| 19 | +For this is necessary to set the following variables: |
| 20 | + |
| 21 | +``` |
| 22 | +oidc_discovery_enabled = true |
| 23 | +oidc_token_authentication_config = { |
| 24 | + client_id = ..., |
| 25 | + issuer_url = ..., |
| 26 | + username_claim = ..., |
| 27 | + username_prefix = ..., |
| 28 | + groups_claim = ..., |
| 29 | + groups_prefix = ..., |
| 30 | + required_claims = [ |
| 31 | + { |
| 32 | + key = ..., |
| 33 | + value = ... |
| 34 | + }, |
| 35 | + { |
| 36 | + key = ..., |
| 37 | + value = ... |
| 38 | + } |
| 39 | + ], |
| 40 | + ca_certificate = ..., |
| 41 | + signing_algorithms = [] |
| 42 | +} |
| 43 | +``` |
| 44 | + |
| 45 | +In case you're looking to authenticate the cluster API endpoint requests with **multiple** OIDC IdPs, you can take advantage of the [authentication configuration via file Kubernetes feature](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-authentication-configuration). |
| 46 | + |
| 47 | +``` |
| 48 | +oidc_discovery_enabled = true |
| 49 | +oidc_token_authentication_config = { |
| 50 | + configuration_file = base64encode(yamlencode( |
| 51 | + { |
| 52 | + "apiVersion" = "apiserver.config.k8s.io/v1beta1" |
| 53 | + "kind" = "AuthenticationConfiguration" |
| 54 | + "jwt" = [ |
| 55 | + { |
| 56 | + "issuer"= { |
| 57 | + "url" = "...", |
| 58 | + "audiences" = [ |
| 59 | + "..." |
| 60 | + ], |
| 61 | + "audienceMatchPolicy" = "MatchAny" |
| 62 | + } |
| 63 | + "claimMappings" = { |
| 64 | + "username" = { |
| 65 | + "claim" = "..." |
| 66 | + "prefix" = "" |
| 67 | + } |
| 68 | + } |
| 69 | + "claimValidationRules" = [ |
| 70 | + { |
| 71 | + "claim" = "..." |
| 72 | + "requiredValue" = "..." |
| 73 | + } |
| 74 | + ] |
| 75 | + } |
| 76 | + ] |
| 77 | + } |
| 78 | + )) |
| 79 | +} |
| 80 | +``` |
| 81 | + |
| 82 | +The authenticated users are mapped to a `User` resource in Kubernetes and you have to setup the desired RBAC polices to provide access. |
| 83 | + |
| 84 | +E.g. for Github Action workflow: |
| 85 | + |
| 86 | +``` |
| 87 | +--- |
| 88 | +apiVersion: rbac.authorization.k8s.io/v1 |
| 89 | +kind: Role |
| 90 | +metadata: |
| 91 | + namespace: default |
| 92 | + name: actions-oidc-role |
| 93 | +rules: |
| 94 | + - apiGroups: [""] |
| 95 | + resources: ["pods"] |
| 96 | + verbs: ["get", "watch", "list"] |
| 97 | + - apiGroups: ["apps"] |
| 98 | + resources: ["deployments"] |
| 99 | + verbs: ["get", "watch", "list", "create", "update", "delete"] |
| 100 | +--- |
| 101 | +apiVersion: rbac.authorization.k8s.io/v1 |
| 102 | +kind: RoleBinding |
| 103 | +metadata: |
| 104 | + name: actions-oidc-binding |
| 105 | + namespace: default |
| 106 | +roleRef: |
| 107 | + apiGroup: rbac.authorization.k8s.io |
| 108 | + kind: Role |
| 109 | + name: actions-oidc-role |
| 110 | +subjects: |
| 111 | + - apiGroup: rbac.authorization.k8s.io |
| 112 | + kind: User |
| 113 | + name: actions-oidc:repo:GH-ACCOUNT/GH-REPO:ref:refs/heads/main |
| 114 | +``` |
| 115 | + |
| 116 | +**Note:** |
| 117 | +1. You need to make sure the OKE Control Plane endpoint is allowed to connect to the IdP. |
| 118 | + |
| 119 | +``` |
| 120 | +allow_rules_cp = { |
| 121 | + "Allow egress to anywhere HTTPS from OKE CP" : { |
| 122 | + protocol = "6", port=443, destination = "0.0.0.0/0", destination_type = "CIDR_BLOCK", |
| 123 | + } |
| 124 | +} |
| 125 | +``` |
| 126 | +2. You cannot configure cluster OIDC Authentication using the arguments of the `oidc_token_authentication_config` (`client_id`, `issuer_url`, etc..) **and** the `configuration_file` at the same time. |
| 127 | + |
| 128 | +## OpenID Connect Discovery |
| 129 | + |
| 130 | +### Prerequisites |
| 131 | + |
| 132 | +Note the following points when using OIDC Discovery: |
| 133 | + |
| 134 | +- The cluster must be an enhanced cluster. OIDC Discovery is not supported for basic clusters. |
| 135 | +- The cluster must be running Kubernetes version 1.21 (or later). |
| 136 | + |
| 137 | +### Configuration |
| 138 | + |
| 139 | +OKE already supports Workload Identity to enable Kubernetes pods to access OCI resources, such as a secret or cloud storage bucket without storing access credentials in your Kubernetes cluster. |
| 140 | + |
| 141 | +If you are looking to authorize Kubernetes pods to access non-OCI resources you can enable OKE OIDC Discovery. |
| 142 | + |
| 143 | +When you enable OIDC discovery for an OKE cluster, OKE provides an OpenID Connect issuer endpoint. This endpoint serves the OIDC discovery document and the JSON web key set (JWKS), which contain the public key necessary for token validation. These resources enable third-party IdP to validate tokens issued for pods in the OKE cluster, allowing those pods to access non-OCI resources. |
| 144 | + |
| 145 | +[  ](../images/oidc-discovery.png) |
| 146 | +*Figure 1: OIDC Discovery* |
| 147 | + |
| 148 | +To enable the OKE OIDC Discovery, you have to set the following variable: |
| 149 | + |
| 150 | +``` |
| 151 | +open_id_connect_discovery_enabled = true |
| 152 | +``` |
| 153 | + |
| 154 | +The OpenID Connect issuer endpoint is available in the output: |
| 155 | + |
| 156 | +``` |
| 157 | +cluster_oidc_discovery_endpoint |
| 158 | +``` |
| 159 | + |
| 160 | +## Example usage |
| 161 | + |
| 162 | +OIDC Authentication setup using Kubernetes API server flags |
| 163 | + |
| 164 | +```javascript |
| 165 | +{{#include ../../../examples/cluster-addons/vars-cluster-oidc-auth-single.auto.tfvars:4:}} |
| 166 | +``` |
| 167 | + |
| 168 | +OIDC Authentication setup using Kubernetes API server configuration file |
| 169 | + |
| 170 | +```javascript |
| 171 | +{{#include ../../../examples/cluster-addons/vars-cluster-oidc-auth-multiple.auto.tfvars:4:}} |
| 172 | +``` |
| 173 | + |
| 174 | +## Reference |
| 175 | +* [OKE OpenID Authetication](https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengOpenIDConnect-Authentication.htm) |
| 176 | +* [OKE Cluster Terraform resource](https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/containerengine_cluster) |
| 177 | +* [Github workflow OKE OIDC authentication](https://docs.oracle.com/en/learn/gaw-oke-odic/index.html#introduction) |
| 178 | +* [Kubernetes OIDC Authentication setup using Kubernetes API server configuration file](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-authentication-configuration) |
| 179 | +* [Kubernetes OIDC Authentication setup using Kubernetes API server flags](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-flags) |
0 commit comments