, ,

VKS Identity and Access with External Providers and Admin Credentials (VCAP-VKS Exam Series, Part 8)

Objective 2.4 is one registration screen and two authorisation surfaces that look like one. Full lab, the Pinniped path, the empty groups claim that costs candidates ninety minutes, and the break glass kubeconfig secret.

VCAP-VKS Exam Series · Part 8 of 34
Question from a workshop: A candidate asked me why a RoleBinding for his Okta group worked fine on paper but returned Forbidden on every VKS cluster underneath his Supervisor. His RoleBinding was correct. His problem was one optional field he had left blank three weeks earlier, on a screen he had visited once.
Key takeaways: This Part covers Objective 2.4, published as Configure VKS identity and access using external providers and Kubernetes admin credentials. Registration happens once on the Supervisor and applies to every VKS cluster on it. Pinniped Supervisor and Concierge run on the Supervisor; only Concierge runs on the workload clusters. Username Claim and Groups Claim are marked Optional and are the two fields that break authorisation when left blank. Headline command: vcf context create vvks-super –endpoint=$SUPERVISOR_ENDPOINT –type=k8s –username=$IDP_USER. Break glass lives in the secret named CLUSTER-kubeconfig.
Who this is for: You have a Supervisor enabled, storage policies attached and at least one VKS cluster running, which is where Part 7 left the lab. You know what a RoleBinding is. You have never wired an OIDC provider into a Supervisor and you are sitting 3V0-24.25.

Identity path from vCenter SSO to Pinniped Concierge

Authentication in a VKS estate runs through two Pinniped components and one decision you made months earlier. Pinniped is the open source authentication service Broadcom ships inside vSphere Supervisor. It splits into a Supervisor half that speaks OIDC to your identity provider, and a Concierge half that exchanges the resulting token for a short lived client certificate the Kubernetes API server will accept. Both halves run as pods on the Supervisor. Only the Concierge half runs on each VKS cluster, which is vSphere Kubernetes Service, the product Broadcom used to call TKG Service and before that TKGS.

That split explains most identity failures you will meet. With no external identity provider registered, VCF CLI forwards your login to vCenter Single Sign On, obtains a token, and writes the vSphere Namespaces you can reach into your kubeconfig. Register an OIDC provider and that path changes for every VKS cluster on that Supervisor at once, whether or not the team running cluster three asked for it. Resource names, API groups and documentation URLs still carry tkg throughout, so do not be surprised when a secret you are hunting is named after a Tanzu Kubernetes cluster. Nothing about the rename is finished on disk.

flowchart TD A[Operator runs vcf context create] –> B{External IdP registered on Supervisor} B — No –> C[vCenter Single Sign On issues a token] B — Yes –> D[Pinniped Supervisor redirects to the IdP] D –> E[IdP returns an ID token carrying username and groups claims] E –> F[Pinniped Concierge on Supervisor exchanges it for a client certificate] C –> G[Supervisor API server checks vSphere Namespace permissions] F –> G G –> H[Pinniped Concierge on each VKS cluster repeats the exchange per cluster] H –> I[Cluster RBAC decides what you can actually do]
Two authorisation surfaces sit at the end of one authentication flow, and they are evaluated independently.

Read the bottom of that diagram twice, because it is where candidates lose marks. Access to a vSphere Namespace, which is the resource boundary the Supervisor projects into Kubernetes, is granted in the vSphere Client under the namespace Permissions card, where you pick an identity source and a role of Viewer, Editor or Owner. Access inside a VKS cluster is granted with ordinary Kubernetes RBAC, meaning Role Based Access Control, using Role, ClusterRole, RoleBinding and ClusterRoleBinding objects. One federated user can hold Editor on a vSphere Namespace and still be Forbidden inside the workload cluster because nobody wrote the RoleBinding. Those two surfaces share an identity and share nothing else. General Kubernetes RBAC mechanics are covered in the VKS Series and this Part does not re-teach them.

Preflight and version record

Three things must be true before you open the Identity Providers screen. Your Supervisor must be Ready, because registration writes to Pinniped custom resources and a Supervisor mid reconcile will accept the form and quietly fail to roll it out. Your identity provider must be OIDC compliant, meaning it publishes a discovery document at the issuer URL. And DNS used by both the Supervisor and the VKS clusters must resolve whatever hostname you put in the callback URL, because the browser redirect and the token validation happen from different places on the network.

# Reference estate for this Part, recorded before any change # VCF 9.0, vCenter 9.0.0.0, Supervisor 1.32.0, VKS 3.3.1 # kubectl v1.32.3, VCF CLI v1.5.0, three vSphere Zones, NSX VPC networking $ kubectl get pods -n vmware-system-pinniped NAME READY STATUS RESTARTS AGE pinniped-concierge-7c9d6b4f8b-4k2xd 1/1 Running 0 21d pinniped-concierge-7c9d6b4f8b-r8vqm 1/1 Running 0 21d pinniped-supervisor-6d5f9c7d44-2mnbt 1/1 Running 0 21d pinniped-supervisor-6d5f9c7d44-9wshc 1/1 Running 0 21d $ kubectl get vsphereclusteridentities,federationdomains -A 2>/dev/null | head -5 No resources found # Empty is correct here. Nothing has been registered yet.

Four Pinniped pods on a three zone Supervisor is what a healthy estate looks like. If pinniped-supervisor is missing entirely and only Concierge is present, you are looking at a Supervisor that has never been given an external provider, which is fine, or one that lost the component during an upgrade, which is not. Broadcom has a knowledge base article for the latter and it is worth knowing that the symptom is a Kubernetes status warning rather than a login failure.

Registration procedure in four steps

Step 1, collect the callback URL and three values from the IdP

Registration is a two sided handshake and the Supervisor side comes first. In the vSphere Client go to Supervisor Management, then Supervisors, then Configure, then Identity Providers, and copy the Identity Provider Callback URL shown there. It takes the form https://SUPERVISOR-VIP/wcp/pinniped/callback. Paste that value into your provider as the sign in redirect URI and, if the provider asks for one, the sign out redirect URI. Broadcom documents Okta, Workspace ONE Access, Dex, GitLab and Google OAuth 2 as tested providers, and any OIDC compliant provider will work. Set the grant type to Authorization Code and add Refresh Token, because without refresh the session dies at the first token expiry and your operators will blame the cluster.

Come back with three values: Issuer URL, Client ID and Client Secret. Before you leave the provider, configure the groups claim on the provider side as well. In Okta that lives under the Sign On tab, OpenID Connect ID Token section, where you set a Groups claim type filter. Matching the claim name groups against a regex of asterisk sends every group. That is fine for a lab and too broad for production, where you should filter to the prefix your platform groups use.

Step 2, fill the provider fields that decide authorisation

Click the plus sign on the Identity Providers screen and work through provider configuration, OAuth 2.0 client details, and additional settings. Broadcom marks four of those fields Required and the rest Optional, and that labelling is honest about registration and misleading about outcomes. Two Optional fields decide whether anyone can do anything. Keep the table below next to you while you fill the form; it is the artifact from this Part worth saving, an IdP field to failure lookup.

FieldMarkedGet it wrong and this is the symptom
Provider NameRequiredCosmetic. Appears in the vSphere Client and in the Pinniped resources.
Issuer URLRequiredOIDC discovery fails, registration never completes, no VKS cluster is touched.
Username ClaimOptionalUsername becomes the issuer URL concatenated with the sub claim, so it reads as https://ISSUER?sub=UUID and every RoleBinding on a named user misses.
Groups ClaimOptionalNo groups are carried from the provider at all. Every group RoleBinding misses silently and login still succeeds.
Client IDRequiredBrowser stops at the provider with invalid_client before any consent screen.
Client SecretRequiredConsent succeeds, token exchange fails, callback returns an error page.
Additional ScopesOptionalClaim names are right and the claims are absent, because the provider was never asked for that scope.
Certificate Authority DataOptionalx509 certificate signed by unknown authority when the provider uses a private CA.
Additional Authorize ParametersOptionalProvider specific. Usually a missing prompt or audience parameter the IdP demands.
Production gotcha: One Supervisor supports one external identity provider. Registering it reconfigures the Pinniped Concierge pods on every VKS cluster running on that Supervisor, and in my three zone lab that rollout took 6 minutes 40 seconds across four clusters. Plan it as a change window that touches all tenants, not as a per team change, and tell the tenants before you click Finish.

Step 3, bind an IdP group inside the VKS cluster

Namespace permission on the Supervisor is a vSphere Client action, so grant your federated group Editor on the team-payments vSphere Namespace there first. Inside the workload cluster you write RBAC yourself, and this is the object that proves whether the groups claim survived the journey.

# team-payments-idp-binding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: team-payments-editors namespace: default subjects: – kind: Group name: k8s-platform-admins apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: edit apiGroup: rbac.authorization.k8s.io $ kubectl –context team-payments-prod apply -f team-payments-idp-binding.yaml rolebinding.rbac.authorization.k8s.io/team-payments-editors created

Step 4, log in as a federated user and read the claims back

Never type a password on a command line and never bake one into a script. Export the username and let the browser flow carry the secret. Verification is not that login succeeded; login succeeds even when everything downstream is broken. Verification is what kubectl auth whoami prints, which needs a kubectl client of 1.28 or later.

$ export SUPERVISOR_ENDPOINT=supervisor.wld01.lab.local $ export IDP_USER=pjha@lab.local # password is never passed as a flag $ vcf context create vvks-super –endpoint=$SUPERVISOR_ENDPOINT –type=k8s –username=$IDP_USER Detected an external identity provider on the target Supervisor. Opening a browser window to complete authentication. Successfully created context vvks-super $ kubectl config use-context team-payments Switched to context "team-payments". $ kubectl auth whoami ATTRIBUTE VALUE Username pjha@lab.local Groups [k8s-platform-admins system:authenticated]

Green looks exactly like that. A readable username and a named group. Anything else and you have work to do, no matter what the vSphere Client says about the provider being registered.

Seconds to a working kubectl contextReference estate, median of five runs per pathvCenter SSO login4.2First federated login41Cached federated re-auth2.8Break glass kubeconfig1.1First federated login includes the interactive browser round trip to the provider.
Federated login is slow once and fast afterwards, which is why nobody notices a broken refresh token until Monday.

Empty groups claim, diagnosis and rollback

Here is the failure I promised, taken from a customer Supervisor where I had left both Optional claim fields blank because the form said Optional and I was in a hurry. Login worked. Everything after login did not.

$ kubectl auth whoami ATTRIBUTE VALUE Username https://trial-4359939.okta.com?sub=00u8fq2k1nZ4rTqL5d7 Groups [system:authenticated] $ kubectl get pods -n default Error from server (Forbidden): pods is forbidden: User "https://trial-4359939.okta.com?sub=00u8fq2k1nZ4rTqL5d7" cannot list resource "pods" in API group "" in the namespace "default"

Both blanks are visible in six lines of output. Username is an opaque issuer plus sub string rather than an email, which is what Broadcom documents will happen when Username Claim is empty. Groups contains only system:authenticated, which every authenticated caller gets for free, so the k8s-platform-admins RoleBinding never matched. No error was raised at registration time and no warning appeared in the vSphere Client. That cost me ninety minutes and two people staring at a perfectly correct RoleBinding.

Fixing it is an edit, not a rebuild. Return to Supervisor Management, Supervisors, Configure, Identity Providers, edit the registered provider, set Username Claim to email and Groups Claim to groups, and save. Pinniped rewrites its resources and the Concierge pods restart on the Supervisor and on every VKS cluster. Users must log out and log in again, because the old ID token in their cache still carries no groups. Repeat the kubectl auth whoami check and expect the readable username and named group from Step 4.

Backing out an IdP registration safely

Removing the provider from that same screen returns the Supervisor to vCenter Single Sign On for VCF CLI logins. Deletion is as wide as registration was, so every VKS cluster reverts together and every federated session is invalidated. Do two things before you remove anything. Confirm at least one vCenter Single Sign On account still holds Owner on the vSphere Namespaces you care about, otherwise you will hand back a namespace nobody can administer. And pull the kubeconfig secret for each cluster to a safe location first, so that a botched revert leaves you a way in. That is the whole point of the next section.

Break glass access with cluster secrets

Every VKS cluster carries a small set of secrets in its vSphere Namespace on the Supervisor, and objective 2.4 names Kubernetes admin credentials explicitly, so know these by name and by purpose. Broadcom is direct about the intent of the kubeconfig one: it exists so you can reach a cluster when vCenter Single Sign On authentication is not available.

Secret nameWhat it holdsRotation
CLUSTER-kubeconfigA kubeconfig for the kubernetes-admin user on the cluster control planeManaged by the cluster controllers. Treat as break glass, not a daily driver.
CLUSTER-caRoot CA certificate for the cluster control plane used by kubectlRotates with cluster certificate lifecycle.
CLUSTER-sshSSH private key for the vmware-system-user account on any nodeUsed for node level troubleshooting only.
CLUSTER-ssh-passwordPassword for vmware-system-user on any nodeUsed for node level troubleshooting only.
CLUSTER-ccm-token-RANDOMService account token for the paravirtual cloud controller managerDelete the secret to trigger rotation.
CLUSTER-pvcsi-token-RANDOMService account token for the paravirtual CSI plug inDelete the secret to trigger rotation.
$ kubectl get secrets -n team-payments | grep team-payments-prod team-payments-prod-ca Opaque 3 26d team-payments-prod-ccm-token-hq8vn Opaque 3 26d team-payments-prod-kubeconfig Opaque 1 26d team-payments-prod-pvcsi-token-w2r6c Opaque 3 26d team-payments-prod-ssh Opaque 1 26d team-payments-prod-ssh-password Opaque 1 26d $ kubectl get secret team-payments-prod-kubeconfig -n team-payments -o jsonpath='{.data.value}’ | base64 -d > /tmp/tp-prod.kubeconfig $ KUBECONFIG=/tmp/tp-prod.kubeconfig kubectl auth whoami ATTRIBUTE VALUE Username kubernetes-admin Groups [system:masters system:authenticated] $ shred -u /tmp/tp-prod.kubeconfig # do this every single time

Notice what that identity is. Username kubernetes-admin, group system:masters, which is unconditional cluster-admin that bypasses every RoleBinding you just wrote and leaves no useful attribution in an audit log. A great deal of published guidance treats this secret as the convenient way to give platform engineers access when SSO is inconvenient. Reject that advice. It converts your carefully federated estate into a shared root password, and on this exam it is also the wrong answer to any question that includes the phrase least privilege. Extract it during an incident, use it, then destroy the local copy.

Failures to remediation

What you seeCauseFix
Groups shows only system:authenticatedGroups Claim blank, or the provider is not emitting a groups claimSet Groups Claim to groups, add the groups claim filter on the provider, log out and back in
Username reads as an issuer URL with a sub query stringUsername Claim blankSet Username Claim to email or preferred_username, then rewrite any RoleBinding that named the old value
Browser stops at the provider with invalid_clientClient ID mismatch between provider and SupervisorRecopy Client ID, confirm you are looking at the same application integration
Callback returns an error page after consentRedirect URI on the provider does not match the Supervisor callback URL exactlyRepaste https://SUPERVISOR-VIP/wcp/pinniped/callback, check for a trailing slash and for FQDN versus VIP drift
x509 certificate signed by unknown authority during loginProvider fronted by a private CA and Certificate Authority Data left emptyPaste the base64 encoded CA chain into Certificate Authority Data and save
Login works on Supervisor, Forbidden on one VKS cluster onlyConcierge on that cluster has not finished reconciling, or nobody wrote cluster RBACCheck Pinniped pods on that cluster, then apply the RoleBinding for the group
Sessions expire after a short period and users must re-authenticate constantlyRefresh Token grant not enabled on the provider applicationAdd Refresh Token to the grant types alongside Authorization Code

Exam focus for objective 2.4

Objective 2.4, Configure VKS identity and access using external providers and Kubernetes admin credentials: What this objective expects you to be able to do is register an OIDC provider against a Supervisor, predict which clusters that change reaches, name the fields the registration needs, and produce cluster admin credentials from a named secret when federated login is unavailable. Expect it in multiple choice and multiple selection items about which fields are required, in matching items that pair a secret name to its contents, and in point and click or hot area items on the Identity Providers screen. The trap that catches experienced admins is scope: they answer as though the identity provider is configured per VKS cluster, because that is how every other Kubernetes distribution they have run works. It is a Supervisor object. Registering it reconfigures Pinniped Concierge on every VKS cluster on that Supervisor, and removing it reverts all of them. A second, quieter trap is reading Optional as unimportant, when Username Claim and Groups Claim are the two fields that decide whether authorisation works at all.

Objective checkpoint

Original practice questionAnswer and reasoning
An administrator registers an OIDC provider on a Supervisor that hosts four VKS clusters. Which clusters use the new provider?All four. Registration is a Supervisor level object and the system reconfigures Pinniped Concierge on every VKS cluster on that Supervisor.
A federated user logs in successfully but every group RoleBinding is ignored. Which single setting is the most likely cause?Groups Claim left empty on the provider registration. When it is blank no groups are carried from the provider, so only system:authenticated is present and authentication still succeeds.
vCenter Single Sign On is unavailable and a VKS cluster must be reached to collect diagnostics. Which secret provides administrator access, and what identity does it carry?CLUSTER-kubeconfig, in the cluster vSphere Namespace. It authenticates as kubernetes-admin in the system:masters group, which is why it is a break glass credential rather than a standing grant.

Identity plan for the reference estate

My recommendation for this lab, and for most estates that look like it, is one external provider registered at the Supervisor with Username Claim set to email and Groups Claim set to groups from day one, a small number of platform groups rather than per team groups, and vCenter Single Sign On retained for vSphere administrators who manage namespaces in the vSphere Client. Avoid the pattern where operators keep an extracted kubeconfig on their laptop because federated login is thirty seconds slower on the first attempt. That trade is not worth it: you lose attribution, you lose revocation, and on exam day it is the answer that looks convenient and scores zero.

Tonight, in your own lab, run kubectl auth whoami against your Supervisor context and against one VKS cluster. If Groups shows anything other than a named group you recognise, you have the bug from this Part sitting in production right now, and you can fix it in about four minutes plus a rollout. Part 9 picks the lab up at Kubernetes releases and content libraries, including the air gapped case, which is where the next objective lands.

VCAP-VKS Exam Series · Part 8 of 34
« Previous: Part 7  |  Guide  |  Next: Part 9 »

References

About The Author


Discover more from Journal of Intelligent Infrastructure

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure

Subscribe now to keep reading and get access to the full archive.

Continue reading