Skip to main content
< All Topics

OIDC Connecting Kubernetes to Google, Okta, and Active Directory

Imagine you have a big team, and creating individual user accounts inside your Kubernetes cluster is becoming a major headache. OpenID Connect (OIDC) solves this problem by allowing your team to use their existing company emails and passwords to log into the cluster safely. It is an industry standard that makes life easier for developers and makes security much stronger for administrators. By outsourcing authentication to a centralized Identity Provider (IdP) like Google Workspace, Okta, or Active Directory, you eliminate the need to manage local cluster credentials.

Think of the Kubernetes cluster as a highly secure office building and the API Server as the security guard at the front desk. Instead of the guard keeping a giant book of every employee’s face and ID (which is hard to manage), the building partners with a trusted external ID agency (like Google or Okta).

When you arrive, you show a stamped badge (a JWT token) from that agency. The guard just checks the agency’s stamp to see if it’s valid and lets you in without needing to know your personal life history!

Quick Reference
  • OIDC: OpenID Connect, an identity layer built on top of the OAuth 2.0 protocol.
  • JWT Token: JSON Web Token, the digital “badge” carrying user details (known as claims).
  • API Server Flags: You strictly need to configure --oidc-issuer-url, --oidc-client-id, and --oidc-username-claim.
  • RBAC: Role-Based Access Control is still 100% required. OIDC authenticates who you are; RBAC authorizes what you can do.

OpenID Connect (OIDC) solves this by allowing you to outsource Kubernetes authentication to a centralized Identity Provider (IdP) like Google Workspace, Okta, or Active Directory.

How OIDC Works in Kubernetes

Kubernetes does not have its own identity database. By configuring OIDC, the Kubernetes API server acts as a trusting client of your IdP.

The standard flow looks like this:

  1. Authentication: A user initiates a login via kubectl. A browser window opens, directing the user to the IdP (Google, Okta, AD).
  2. Token Issuance: Upon successful login, the IdP returns an id_token (a JWT – JSON Web Token) and a refresh_token.
  3. API Request: kubectl attaches the id_token as a Bearer token in the Authorization header of requests to the Kubernetes API server.
  4. Verification: The API server verifies the token’s signature using the IdP’s public keys (retrieved via the IdP’s discovery URL).
  5. Authorization: Once verified, the API server extracts the user’s identity and group membership from the token’s claims and evaluates them against Kubernetes RBAC (Role-Based Access Control) policies.

Let’s break down the basic steps to get this working:

  • Step 1: Get an Identity Provider. You need an account with Google Workspace, Okta, or Azure AD. You create an “App” there to get a Client ID and Client Secret.
  • Step 2: Teach Kubernetes about the Provider. You must edit the Kubernetes API server configuration. This usually means editing the /etc/kubernetes/manifests/kube-apiserver.yaml file on your control plane node and adding OIDC flags.
  • Step 3: Tell Kubernetes what the user can do. Just because someone can log in doesn’t mean they can delete pods! You have to write a ClusterRoleBinding that says “User Alice from Okta is a cluster-admin.”
  • Step 4: User Login. The user needs a helper tool like kubelogin (also known as oidc-login) to fetch the token and securely update their kubeconfig file.

Core API Server Configuration

For advanced architects, OIDC integration involves a deep understanding of JWT validation, secure Public Key Infrastructure (PKI) handling, and custom claim mappings.

To enable OIDC, the Kubernetes API server requires specific startup flags in the kube-apiserver manifest:

  • --oidc-issuer-url: The URL of your IdP (e.g., https://accounts.google.com). The API server fetches the OIDC discovery document (/.well-known/openid-configuration) from this URL to find the jwks_uri (JSON Web Key Set) for cryptographic signature verification. This URL must perfectly match the iss claim in the JWT.
  • --oidc-client-id: The Client ID generated when you registered Kubernetes as an application in your IdP.
  • --oidc-username-claim: The JWT claim to use as the Kubernetes username (often email or sub).
  • --oidc-groups-claim: The JWT claim that contains the user’s group memberships (e.g., groups). Custom Claim Mapping: If your IdP sends group data in a custom claim, map it using --oidc-groups-claim=custom_groups_claim.
  • --oidc-username-prefix / --oidc-groups-prefix: Optional prefixes added to the claims to prevent clashes with built-in Kubernetes system names. Prefixing is absolutely crucial (e.g., setting the group prefix to oidc:) to prevent privilege escalation where an external IdP user spoofs an internal Kubernetes system group like system:masters.
  • Token Refresh Handling: ID tokens are intentionally short-lived (usually 1 hour). A refresh token must be securely stored in the kubeconfig via the auth-provider exec plugin. The CLI handles the PKCE flow and refresh logic transparently. Ensure your IdP is configured to grant the offline_access scope, which is strictly required to issue refresh tokens.
DevSecOps Architect level

At a production-grade DevSecOps level, direct API server modification isn’t always feasible (e.g., using managed services like EKS or GKE). Here is how you handle enterprise environments:

  • Managed Clusters: For GKE, use the native “GKE Identity Service”. For Amazon EKS, associate an OIDC identity provider directly via the AWS Console or Terraform.
  • Impersonation Proxies: If you cannot modify the API Server due to strict enterprise constraints, deploy an OIDC impersonation proxy like Pinniped. Pinniped provides a standardized, cluster-native way to manage identities across massive fleets of clusters.
  • Legacy AD Integration: Traditional On-Premises LDAP/AD does not speak OIDC natively. You must use an identity broker. Dex (an open-source CNCF project) is the industry standard here. Dex connects to your LDAP server, speaks LDAP on the backend, and exposes a fully compliant OIDC endpoint to the Kubernetes API server.
  • The Client Side: Kubernetes does not handle the browser-based login dance natively. The most widely adopted community standard is kubelogin (often installed via krew).

Connecting Specific Identity Providers

1. Google Workspace / Cloud Identity

Google provides a highly reliable OIDC endpoint.

  • Setup: You must create an OAuth 2.0 Client ID in the Google Cloud Console. Select “Desktop app” or “Web application” depending on how your CLI helper tools are configured.
  • Claims: Google standardizes on the email claim for the username.
  • Limitation: Google’s default OIDC tokens do not inherently include a groups claim. If you need group-based RBAC with Google, you typically have to use a shim/broker like Dex or rely on a managed service like GKE, which integrates Google Groups directly.

2. Okta

Okta is highly flexible and built for enterprise OIDC workflows.

  • Setup: Create a new “Native” or “Web” Application in Okta. Assign the app to the relevant users or groups.
  • Claims: Ensure you configure Okta’s Authorization Server to include a custom groups claim in the id_token. You will need to write a simple Okta expression (like Matches regex ".*") to populate this claim.
  • API Server Flags: Map --oidc-username-claim=email and --oidc-groups-claim=groups.

3. Active Directory (On-Prem and Azure AD / Entra ID)

Integrating Microsoft environments depends on where the directory lives.

  • Azure AD (Entra ID): Azure provides native OIDC support. Register an Enterprise Application, configure API permissions to read user profiles and groups, and ensure the “Group claim” is emitted in the token.
    • Note: By default, Azure AD emits Object IDs (UUIDs) for groups, not human-readable names. You either use the UUIDs in your Kubernetes RBAC or configure Azure to emit sAMAccountName.
  • On-Premises AD: Traditional LDAP/AD does not speak OIDC natively. You must use an identity broker. Dex (an open-source CNCF project) is the industry standard here. Dex connects to your LDAP server, speaks LDAP on the backend, and exposes a compliant OIDC endpoint to the Kubernetes API server.

The Client Side: Configuring kubectl

Kubernetes does not handle the browser-based login dance natively. You need an OIDC helper plugin. The most widely adopted community standard is kubelogin (often installed via krew).

Standard kubeconfig setup using kubelogin:

YAML
users:
- name: oidc-user
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      command: kubectl
      args:
      - oidc-login
      - get-token
      - --oidc-issuer-url=https://your-idp.com
      - --oidc-client-id=YOUR_CLIENT_ID
      - --oidc-client-secret=YOUR_CLIENT_SECRET

Tying it Together with RBAC

Once the API server trusts the IdP, you must create Kubernetes RoleBindings or ClusterRoleBindings that map to the OIDC claims.

YAML
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: devsecops-admin-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: Group
  name: oidc:devsecops-team # Assuming a prefix of "oidc:" was used
  apiGroup: rbac.authorization.k8s.io

Additional Details
  • Clock Skew: A common, hidden issue is clock drift. If the system clock on the Kubernetes control plane nodes drifts away from the IdP’s time servers, the API server will immediately reject perfectly valid tokens, claiming they are “issued in the future” or “expired.” Always run NTP on your nodes.
  • Token Revocation Limitation: Kubernetes cannot inherently “revoke” a specific JWT before it expires. It only checks the signature and the expiration time statically. If a user is fired, disabling them in Okta stops them from getting new tokens, but their existing 1-hour token remains valid until it naturally expires. Keep token lifespans short!
  • Lack of Native UI: Kubernetes has no built-in web login interface to trigger the OIDC flow natively; it strictly relies on CLI plugins or third-party dashboards.
  1. Key Components
    • Identity Provider (IdP): Google, Okta, AD.
    • Kubernetes API Server: Validates the cryptographic signature of the token.
    • kubectl & kubelogin: The client-side execution tools.
    • JWT (ID Token): The base64-encoded assertion of identity.
  2. Key Characteristics
    • Stateless authentication on the Kubernetes side.
    • Delegated credential management.
    • Token-based authorization (Bearer tokens).
  3. Use case
    • Enterprise Single Sign-On (SSO) for developer and pipeline access to Kubernetes clusters.
    • Centralized offboarding (revoking access in Okta immediately blocks Kubernetes access).
  4. Benefits
    • No need to generate and distribute individual client certificates.
    • Eliminates local, hard-to-track Kubernetes user accounts.
    • Seamless integration with existing corporate security policies.
  5. Best practices
    • Always use strict prefixes for users and groups (e.g., --oidc-groups-prefix=oidc:).
    • Keep ID token lifespans short (e.g., 15-60 minutes).
    • Automate the onboarding of RBAC roles using GitOps tools like ArgoCD.
  6. Technical challenges
    • Debugging API server flag misconfigurations can be frustrating (the server might crash loop and fail to start).
    • Clock skew between the IdP and the Kubernetes control plane can cause immediate token validation failures.
  7. Limitations
    • Kubernetes has no built-in web login interface to trigger the OIDC flow natively; it strictly relies on CLI plugins.
    • Kubernetes cannot revoke a specific JWT before it expires; it only checks the signature and the expiration time statically.
  8. Common issues
    • API Server failing to start due to an unreachable --oidc-issuer-url.
    • RBAC bindings not taking effect because the groups claim is missing entirely from the ID Token.
  9. Problems and solutions
    • Problem: Users are getting “Unauthorized” errors.
      • Solution: Verify the kubeconfig is correctly executing the oidc-login plugin and that the token hasn’t expired. Check API server audit logs for rejection reasons.
    • Problem: Groups are not mapping correctly to ClusterRoles.
      • Solution: Decode the JWT using a tool like jwt.io (never paste production tokens online, use local tools) and verify the exact string name of the groups claim. Adjust --oidc-groups-claim to match the exact JSON key.

Conclusion

Integrating OIDC with your Kubernetes cluster is a fundamental step in building a mature DevSecOps platform. By offloading authentication to robust providers like Google, Okta, or Active Directory, you not only enhance the security posture of your infrastructure but also provide a smooth, frictionless experience for your engineering teams. Keep learning and secure those clusters!

Contents
Scroll to Top