Skip to content

Workload Identity Registration

Workload Identity Registration

Standard Sveltos cluster registration stores a long-lived kubeconfig in a Kubernetes Secret. With Workload Identity registration we remove that requirement. Sveltos obtains short-lived credentials at runtime instead of reading them from a Secret.

Two different mechanisms are covered by this page:

  • Cloud provider workload identity (GKE, EKS, AKS): the management cluster pod's own cloud identity is used to obtain credentials for the managed cluster. This works when the management and the managed clusters are in the same cloud account or project, and the management cluster runs with a cloud provider identity (GKE Workload Identity, AWS IRSA, or Azure Workload Identity).
  • Generic OIDC (Dex, Keycloak, Okta, or any RFC 6749 compliant identity provider): for managed clusters that are not on one of the three cloud providers above, for example an on-prem or self-managed cluster fronted by an enterprise IdP. This is not secretless: Sveltos holds a standing client_id/client_secret in a Secret and exchanges it directly at the IdP's token endpoint using the standard OAuth2 client credentials grant.

Either way, no kubeconfig Secret is stored in the Sveltos management cluster, and credentials are refreshed automatically before they expire.

Note

Workload Identity registration requires Sveltos v1.12.0 or later for GKE/EKS/AKS. Generic OIDC support was added later; check the release notes for the version that first includes it.

Which Service Accounts Need the Cloud Identity Annotation

This section applies to the three cloud providers (GKE, EKS, AKS) only. OIDC does not use a ServiceAccount annotation at all: the client credentials live in a regular Secret referenced by the SveltosCluster, so there is nothing to annotate or roll out. See Programmatic Registration below.

Only the Sveltos components that talk to managed clusters need the cloud provider's workload identity annotation on their ServiceAccount:

  • access-manager
  • addon-controller
  • event-manager
  • hc-manager
  • sc-manager
  • techsupport-controller
  • mcp-server
  • drift-detection-manager and sveltos-agent-manager, but only when Sveltos runs in agentless mode (agent.managementCluster: true in the Helm chart)

Workload identity for the per-cluster agents themselves

drift-detection-manager and sveltos-agent-manager are not installed by the Helm chart: Sveltos creates one instance of each per managed cluster. Each instance lives in the management cluster (agentless mode) or in the managed cluster itself (the default). In agentless mode, that instance needs to reach the managed cluster it was created for, which is why it's in the ServiceAccount list above. When one of these per-cluster instances needs a cloud workload identity of its own, for example an azure.workload.identity/use: "true" pod label to pull images from a private registry, patch its Deployment directly instead: see Sharing Overrides Across Multiple Clusters.

Preferred: set the annotation once via Helm

If Sveltos is installed with the projectsveltos Helm chart, set global.serviceAccountAnnotations instead of annotating each ServiceAccount by hand. The value is merged into every ServiceAccount listed above, and a component-specific <component>.serviceAccount.annotations still takes precedence on key collisions:

# values.yaml
global:
  serviceAccountAnnotations:
    iam.gke.io/gcp-service-account: sveltos-wi@<project>.iam.gserviceaccount.com   # GKE
    # eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/sveltos-wi        # EKS
    # azure.workload.identity/client-id: <client-id>                              # AKS
$ helm upgrade --install projectsveltos projectsveltos/projectsveltos \
  -n projectsveltos --create-namespace \
  -f values.yaml

The manual kubectl annotate serviceaccount steps in the guides below still work, and are the only option for installs that don't use the Helm chart.

Register a Cluster

When using cloud provider workload identity, each provider has a dedicated subcommand: register cluster-eks for Amazon EKS, register cluster-gke for Google GKE, and register cluster-aks for Azure AKS. If you are registering a cluster with a kubeconfig, use register cluster instead.

Note

OIDC has no dedicated sveltosctl register subcommand yet. Apply the SveltosCluster and its Secrets directly: see the OIDC tab under Programmatic Registration.

AWS (EKS)

$ sveltosctl register cluster-eks \
  --namespace=<namespace> \
  --cluster=<cluster-name> \
  --endpoint=<eks-api-server-url> \
  --eks-cluster-name=<eks-cluster-name> \
  --ca-file=/tmp/managed-ca.crt
Flag Required Description
--endpoint Yes API server URL of the EKS cluster (e.g. https://...).
--eks-cluster-name Yes EKS cluster name. Embedded in the bearer token so the API server can identify the target cluster.
--ca-file No Path to the CA certificate for the EKS API server. When provided, sveltosctl creates a <cluster>-sveltos-ca Secret and references it in the SveltosCluster.
--role-arn No IAM role ARN to assume before generating the token. If omitted, the pod's own IRSA role is used directly.
--region No AWS region of the EKS cluster. Defaults to the AWS_REGION environment variable injected by IRSA.

GCP (GKE)

$ sveltosctl register cluster-gke \
  --namespace=<namespace> \
  --cluster=<cluster-name> \
  --endpoint=https://<endpoint> \
  --project-id=<project-id> \
  --gke-cluster-name=<gke-cluster-name> \
  --location=<region-or-zone> \
  --ca-file=/tmp/ca.crt
Flag Required Description
--endpoint Yes API server URL of the GKE cluster (e.g. https://34.x.x.x).
--project-id Yes GCP project ID.
--gke-cluster-name Yes GKE cluster name.
--location Yes GCP region or zone (e.g. us-central1-a).
--ca-file No Path to the CA certificate for the GKE API server.

Azure (AKS)

$ sveltosctl register cluster-aks \
  --namespace=<namespace> \
  --cluster=<cluster-name> \
  --endpoint=https://<aks-api-server> \
  --tenant-id=<tenant-id> \
  --client-id=<client-id>
Flag Required Description
--endpoint Yes API server URL of the AKS cluster (e.g. https://my-aks.hcp.eastus.azmk8s.io).
--tenant-id Yes Azure AD tenant ID.
--client-id Yes Client ID of the managed identity or app registration federated with the management cluster service account.
--ca-file No Path to the CA certificate for the AKS API server.
--subscription-id No Azure subscription containing the AKS cluster.
--resource-group No Resource group containing the AKS cluster.
--aks-cluster-name No AKS cluster name.

Deregister a Cluster

$ sveltosctl deregister cluster \
  --namespace=<namespace> \
  --cluster=<cluster-name>

This deletes the SveltosCluster and the <cluster>-sveltos-ca Secret if one was created.

End-to-end Setup Guides

The guides below walk through the full cloud-side setup required before running the registration command.

Note

These guides show one specific way we configured each cloud provider. They are not the only valid approach. If you already know how to set up IRSA, GKE Workload Identity, or Azure federated credentials for a Kubernetes workload, you can skip straight to the sveltosctl register cluster-eks/cluster-gke/cluster-aks command above. The cloud setup only needs to end with the management cluster pod having permission to call the managed cluster's API server.

EKS — IRSA-based workload identity

Both the management cluster and the managed cluster are EKS clusters in the same AWS account.

Variables

$ export ACCOUNT_ID=<aws-account-id>
$ export REGION=us-east-1
$ export MGMT_CLUSTER=sveltos-mgmt
$ export MANAGED_CLUSTER=sveltos-managed
$ export SERVICE_ACCOUNTS="access-manager addon-controller event-manager hc-manager sc-manager techsupport-controller mcp-server"
# Agentless mode (agent.managementCluster: true)? drift-detection-manager and sveltos-agent-manager need access too:
# $ export SERVICE_ACCOUNTS="${SERVICE_ACCOUNTS} drift-detection-manager sveltos-agent-manager"

Step 1 — Create clusters as an IAM user (not root)

EKS grants cluster admin access to the IAM entity that creates the cluster. Root-created clusters cannot be accessed by IAM users without extra configuration.

$ eksctl create cluster --name ${MGMT_CLUSTER} --region ${REGION} --nodes 2
$ eksctl create cluster --name ${MANAGED_CLUSTER} --region ${REGION} --nodes 1

Step 2 — Install Sveltos on the management cluster

$ aws eks update-kubeconfig --name ${MGMT_CLUSTER} --region ${REGION}
$ kubectl apply -f https://raw.githubusercontent.com/projectsveltos/sveltos/main/manifest/manifest.yaml
$ kubectl get pods -n projectsveltos

Step 3 — Associate the OIDC provider

eksctl does not register the OIDC provider automatically.

$ eksctl utils associate-iam-oidc-provider \
  --cluster ${MGMT_CLUSTER} --region ${REGION} --approve

$ export OIDC_ID=$(aws eks describe-cluster --name ${MGMT_CLUSTER} --region ${REGION} \
  --query "cluster.identity.oidc.issuer" --output text | awk -F'/' '{print $NF}')

Step 4 — Create an IAM role trusted by every Sveltos service account

One IAM role is shared by all the service accounts in SERVICE_ACCOUNTS (all in namespace projectsveltos). The trust policy's sub condition lists one entry per service account.

$ SUBS=""
$ for sa in ${SERVICE_ACCOUNTS}; do
    SUBS="${SUBS}\"system:serviceaccount:projectsveltos:${sa}\","
  done
$ SUBS="[${SUBS%,}]"

$ cat > /tmp/trust-policy.json << EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/oidc.eks.${REGION}.amazonaws.com/id/${OIDC_ID}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.${REGION}.amazonaws.com/id/${OIDC_ID}:aud": "sts.amazonaws.com"
        },
        "ForAnyValue:StringEquals": {
          "oidc.eks.${REGION}.amazonaws.com/id/${OIDC_ID}:sub": ${SUBS}
        }
      }
    }
  ]
}
EOF

$ aws iam create-role \
  --role-name sveltos-wi \
  --assume-role-policy-document file:///tmp/trust-policy.json

Step 5 — Annotate every service account

$ for sa in ${SERVICE_ACCOUNTS}; do
    kubectl annotate serviceaccount ${sa} -n projectsveltos \
      eks.amazonaws.com/role-arn=arn:aws:iam::${ACCOUNT_ID}:role/sveltos-wi --overwrite
  done

$ kubectl rollout restart deployment -n projectsveltos \
  access-manager addon-controller event-manager hc-manager sc-manager techsupport-controller mcp-server

drift-detection-manager and sveltos-agent-manager (agentless mode) are not static Deployments — Sveltos (re)creates their pods on demand, so no rollout restart is needed for them; the annotation is picked up the next time a pod is created.

Verify IRSA environment variables are injected, e.g. for sc-manager:

$ kubectl describe pod -n projectsveltos -l app=sc-manager | grep "AWS_ROLE_ARN\|AWS_WEB_IDENTITY_TOKEN_FILE"

Step 6 — Grant the IAM role access to the managed cluster

$ aws eks create-access-entry \
  --cluster-name ${MANAGED_CLUSTER} \
  --principal-arn arn:aws:iam::${ACCOUNT_ID}:role/sveltos-wi \
  --region ${REGION}

$ aws eks associate-access-policy \
  --cluster-name ${MANAGED_CLUSTER} \
  --principal-arn arn:aws:iam::${ACCOUNT_ID}:role/sveltos-wi \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy \
  --access-scope type=cluster \
  --region ${REGION}

Step 7 — Get the managed cluster endpoint and CA certificate

$ export ENDPOINT=$(aws eks describe-cluster --name ${MANAGED_CLUSTER} --region ${REGION} \
  --query "cluster.endpoint" --output text)

$ aws eks describe-cluster --name ${MANAGED_CLUSTER} --region ${REGION} \
  --query "cluster.certificateAuthority.data" --output text \
  | base64 --decode > /tmp/managed-ca.crt

Step 8 — Register the managed cluster

$ sveltosctl register cluster-eks \
  --namespace=projectsveltos \
  --cluster=eks-managed \
  --endpoint=${ENDPOINT} \
  --eks-cluster-name=${MANAGED_CLUSTER} \
  --ca-file=/tmp/managed-ca.crt

Step 9 — Verify

$ kubectl get sveltoscluster eks-managed -n projectsveltos

READY should become true within a few seconds.

Troubleshooting

"the server has asked for the client to provide credentials": Verify the access entry and policy association:

$ aws eks list-associated-access-policies \
  --cluster-name ${MANAGED_CLUSTER} \
  --principal-arn arn:aws:iam::${ACCOUNT_ID}:role/sveltos-wi \
  --region ${REGION}

OIDC provider missing: aws iam list-open-id-connect-providers returns an empty list. Re-run step 3.

Cluster created as root: Only the creating IAM entity has access by default. Delete and recreate the cluster as your IAM user, or add the IAM user via an EKS access entry using root credentials.

AWS_REGION not set: --region is optional and falls back to the AWS_REGION environment variable injected by IRSA. Set it explicitly in the flag if you see a region error.

GKE — Workload Identity

Both the management cluster and the managed cluster are GKE clusters in the same GCP project.

Variables

$ export PROJECT=<project-id>
$ export MGMT_CLUSTER=cluster-mgmt
$ export MANAGED_CLUSTER=cluster-managed
$ export ZONE=us-central1-a
$ export SERVICE_ACCOUNTS="access-manager addon-controller event-manager hc-manager sc-manager techsupport-controller mcp-server"
# Agentless mode (agent.managementCluster: true)? drift-detection-manager and sveltos-agent-manager need access too:
# $ export SERVICE_ACCOUNTS="${SERVICE_ACCOUNTS} drift-detection-manager sveltos-agent-manager"

Step 1 — Create clusters

$ gcloud container clusters create ${MGMT_CLUSTER} \
  --zone=${ZONE} --project=${PROJECT}

$ gcloud container clusters create ${MANAGED_CLUSTER} \
  --zone=${ZONE} --project=${PROJECT}

Step 2 — Enable Workload Identity on the management cluster

$ gcloud container clusters update ${MGMT_CLUSTER} \
  --workload-pool=${PROJECT}.svc.id.goog \
  --zone=${ZONE} --project=${PROJECT}

Step 3 — Enable GKE_METADATA on the management node pool

Without this, pods cannot use Workload Identity even when the cluster has it enabled.

$ gcloud container node-pools update default-pool \
  --cluster=${MGMT_CLUSTER} \
  --zone=${ZONE} --project=${PROJECT} \
  --workload-metadata=GKE_METADATA

Wait for node rotation to complete:

$ gcloud container node-pools describe default-pool \
  --cluster=${MGMT_CLUSTER} --zone=${ZONE} --project=${PROJECT} \
  --format='value(config.workloadMetadataConfig.mode)'
# should print: GKE_METADATA

Step 4 — Install Sveltos on the management cluster

$ gcloud container clusters get-credentials ${MGMT_CLUSTER} \
  --zone=${ZONE} --project=${PROJECT}

$ kubectl apply -f https://raw.githubusercontent.com/projectsveltos/sveltos/main/manifest/manifest.yaml

Step 5 — Create a Google Service Account for Sveltos

$ gcloud iam service-accounts create sveltos-wi --project=${PROJECT}

Step 6 — Link every Kubernetes service account to the GSA

$ for sa in ${SERVICE_ACCOUNTS}; do
    gcloud iam service-accounts add-iam-policy-binding \
      sveltos-wi@${PROJECT}.iam.gserviceaccount.com \
      --role=roles/iam.workloadIdentityUser \
      --member="serviceAccount:${PROJECT}.svc.id.goog[projectsveltos/${sa}]" \
      --project=${PROJECT}

    kubectl annotate serviceaccount ${sa} \
      -n projectsveltos \
      iam.gke.io/gcp-service-account=sveltos-wi@${PROJECT}.iam.gserviceaccount.com --overwrite
  done

$ kubectl rollout restart deployment -n projectsveltos \
  access-manager addon-controller event-manager hc-manager sc-manager techsupport-controller mcp-server

drift-detection-manager and sveltos-agent-manager (agentless mode) are not static Deployments — Sveltos (re)creates their pods on demand, so no rollout restart is needed for them; the annotation is picked up the next time a pod is created.

Step 7 — Grant the GSA access to the managed cluster

$ gcloud projects add-iam-policy-binding ${PROJECT} \
  --member=serviceAccount:sveltos-wi@${PROJECT}.iam.gserviceaccount.com \
  --role=roles/container.admin

Step 8 — Get the managed cluster endpoint and CA certificate

$ export ENDPOINT=$(gcloud container clusters describe ${MANAGED_CLUSTER} \
  --zone=${ZONE} --project=${PROJECT} \
  --format='value(endpoint)')

$ gcloud container clusters describe ${MANAGED_CLUSTER} \
  --zone=${ZONE} --project=${PROJECT} \
  --format='value(masterAuth.clusterCaCertificate)' \
  | base64 --decode > /tmp/ca.crt

Step 9 — Register the managed cluster

$ sveltosctl register cluster-gke \
  --namespace=projectsveltos \
  --cluster=gke-managed \
  --endpoint=https://${ENDPOINT} \
  --project-id=${PROJECT} \
  --gke-cluster-name=${MANAGED_CLUSTER} \
  --location=${ZONE} \
  --ca-file=/tmp/ca.crt

Step 10 — Verify

$ kubectl get sveltoscluster gke-managed -n projectsveltos

READY should become true within a few seconds.

Troubleshooting

"the server has asked for the client to provide credentials": The node pool is not using GKE_METADATA mode. Run step 3 and wait for node rotation to complete, then restart the sc-manager pod.

PROJECT is empty: Shell variables are lost between sessions. Re-export them before running any gcloud commands.

OIDC — Dex

Unlike the cloud examples above, the management and managed clusters don't need to be related in any way. All that's required is that the managed cluster's kube-apiserver trusts Dex as an OIDC issuer, and that Sveltos holds a client_id/client_secret Dex will accept.

Step 1 — Enable the client credentials grant on Dex

The client credentials grant (RFC 6749 §4.4) is what lets Sveltos exchange a client_id/client_secret directly for a token, without a user login. It must be turned on explicitly:

$ export DEX_CLIENT_CREDENTIAL_GRANT_ENABLED_BY_DEFAULT=true
# dex config.yaml
oauth2:
  grantTypes:
    - "client_credentials"
staticClients:
  - id: sveltos
    secret: <a-strong-secret>
    name: Sveltos

Step 2 — Trust Dex from the managed cluster's kube-apiserver

Add these flags to the managed cluster's kube-apiserver. The exact mechanism depends on how the cluster is provisioned: kubeadm's ClusterConfiguration, a Cluster API KubeadmControlPlane/ClusterClass patch, or your distribution's equivalent.

--oidc-issuer-url=https://<dex-host>:<port>/dex
--oidc-client-id=sveltos
--oidc-username-claim=aud
--oidc-username-prefix=-
--oidc-ca-file=/etc/kubernetes/pki/dex-ca.crt   # only if Dex's cert isn't already trusted

--oidc-username-claim=aud reads the token's audience claim, which the client credentials grant sets to the client_id verbatim (sveltos here). Combined with --oidc-username-prefix=- (no prefix), the resulting Kubernetes username is exactly sveltos. That's simpler to reason about than the sub claim, which Dex encodes internally rather than leaving as the plain client_id.

Step 3 — Grant that identity the permissions Sveltos needs

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: sveltos-oidc-workload-identity
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: User
    name: sveltos
    apiGroup: rbac.authorization.k8s.io

Step 4 — Register the cluster

See the OIDC tab under Programmatic Registration for the SveltosCluster and Secrets to apply.

Step 5 — Verify

$ kubectl get sveltoscluster <name> -n <namespace>

READY should become true within a few seconds.

Troubleshooting

x509: certificate signed by unknown authority in sc-manager/addon-controller logs: the token exchange with Dex's own token endpoint is failing TLS verification. This is a different trust boundary from Step 2: set oidc.caSecretRef in the SveltosCluster to a Secret containing Dex's own CA (see Programmatic Registration).

... is forbidden: User "sveltos" cannot get resource ...: the token is being accepted, but no RBAC grants that identity anything. Revisit Step 3.

OIDC — Keycloak

The setup is very similar to the one with DEX. We will provide instructions on how to allow Sveltos to register Kubernetes clusters using Keycloak as a Workload Identity. The full guide is available here.

Step 1 — Realm, Client ID and Configuration Mappers

Realm and Client ID

  1. Create a new Realm with the name sveltos-realm
  2. Create a Client ID test-env-auth
  3. Under Capability config: Enable Client authentication and enable Service account roles in the Authentication flow section
  4. Save the configuration

Mapper Configuration -> Hardcoded claim

  1. Set Name to test-env-user
  2. Set Token Claim Name to test-env-user
  3. Set Claim value to sveltos
  4. Set Claim JSON Type to string
  5. Enable Add to access token
  6. Save the configuration

Mapper Configuration -> Audience

  1. Set Name to test-env-audience
  2. Set Included Custom Audience to test-env-auth
  3. Disable Add to ID token
  4. Enable Add to access token
  5. Save the configuration

Step 2 — Update Managed Cluster Kubernetes API Server Details

Add these flags to the managed cluster's kube-apiserver. The exact mechanism depends on how the cluster is provisioned: kubeadm's ClusterConfiguration, a Cluster API KubeadmControlPlane/ClusterClass patch, or your distribution's equivalent.

--oidc-issuer-url=https://<Your Keycloak Domain>/realms/sveltos-realm
--oidc-client-id=test-env-auth
--oidc-username-claim=test-env-user
--oidc-username-prefix=-
--oidc-ca-file=/etc/kubernetes/pki/keycloak-ca.crt # Only if Keycloak's cert is not trusted

The oidc-username-claim=test-env-user value resolves to sveltos. Remember, this comes from the Hardcoded claim created in a previous step. The oidc-username-prefix=- field means no prefix is added. The Kubernetes username is sveltos.

Step 3 — Grant Indentity the Permissions Sveltos Requires

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: sveltos-oidc-workload-identity
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: User
    name: sveltos
    apiGroup: rbac.authorization.k8s.io

Step 4 — Register the cluster

See the OIDC tab under Programmatic Registration for the SveltosCluster and Secrets to apply. The cluster can be registered in a different namespace instead of projectsveltos. Choose the namespace of your preference.

Step 5 — Verification

$ kubectl get sveltoscluster <name> -n <namespace>

READY should become true within a few seconds.

Troubleshooting

x509: certificate signed by unknown authority in sc-manager/addon-controller logs: The token exchange with Dex's own token endpoint is failing TLS verification. This is a different trust boundary from Step 2: set oidc.caSecretRef in the SveltosCluster to a Secret containing Dex's own CA (see Programmatic Registration).

... is forbidden: User "sveltos" cannot get resource ...: the token is being accepted, but no RBAC grants that identity anything. Revisit Step 3.

Programmatic Registration

To create the resources in a programmatic manner, apply a SveltosCluster with spec.workloadIdentity set.

apiVersion: lib.projectsveltos.io/v1beta1
kind: SveltosCluster
metadata:
  name: eks-managed
  namespace: projectsveltos
spec:
  workloadIdentity:
    provider: AWS
    endpoint: "https://<eks-api-server>"
    caSecretRef:
      name: eks-managed-ca   # Secret with key ca.crt
    aws:
      clusterName: sveltos-managed
      # region: us-east-1    # optional; defaults to AWS_REGION env var
      # roleARN: arn:aws:iam::123456789012:role/my-role  # optional
apiVersion: lib.projectsveltos.io/v1beta1
kind: SveltosCluster
metadata:
  name: gke-managed
  namespace: projectsveltos
spec:
  workloadIdentity:
    provider: GCP
    endpoint: "https://<gke-endpoint>"
    caSecretRef:
      name: gke-managed-ca   # Secret with key ca.crt
    gcp:
      projectID: <project-id>
      clusterName: cluster-managed
      location: us-central1-a
apiVersion: lib.projectsveltos.io/v1beta1
kind: SveltosCluster
metadata:
  name: aks-managed
  namespace: projectsveltos
spec:
  workloadIdentity:
    provider: Azure
    endpoint: "https://<aks-api-server>"
    azure:
      tenantID: <tenant-id>
      clientID: <client-id>
      # subscriptionID, resourceGroup, clusterName are optional
apiVersion: v1
kind: Secret
metadata:
  name: oidc-managed-creds
  namespace: projectsveltos
stringData:
  client_id: sveltos
  client_secret: <a-strong-secret>
---
apiVersion: lib.projectsveltos.io/v1beta1
kind: SveltosCluster
metadata:
  name: oidc-managed
  namespace: projectsveltos
spec:
  workloadIdentity:
    provider: OIDC
    endpoint: "https://<managed-cluster-api-server>"
    caSecretRef:
      name: oidc-managed-ca        # Secret with key ca.crt: the managed cluster's own API server CA
    oidc:
      tokenURL: "https://<idp-host>/token"
      secretRef:
        name: oidc-managed-creds
      # scopes: ["some-scope"]     # optional; leave out if the IdP doesn't require one
      # caSecretRef:
      #   name: oidc-idp-ca        # Secret with key ca.crt: the IdP's own CA, only if it's
      #                            # behind a private CA. Distinct from the caSecretRef
      #                            # above: that one is for the managed cluster's API
      #                            # server, this one is for the IdP's token endpoint.

The CA Secret referenced by caSecretRef must contain a ca.crt key:

apiVersion: v1
kind: Secret
metadata:
  name: eks-managed-ca
  namespace: projectsveltos
data:
  ca.crt: <base64-encoded-CA-certificate>

For OIDC, secretRef under oidc must contain client_id and client_secret keys, as shown above.