Configure Workload Identity at the Environment, Application, or Cluster Level
Enable secure communication and access control between different resources or external services by configuring a workload identity. A workload identity is a set of credentials or identifiers that uniquely authenticate and authorize environments, applications, or services running within a computing environment, such as a Kubernetes cluster.
You can configure workload identities at the cluster, environment, and application levels in the C3 Agentic AI Platform. Each configuration level offers varying degrees of control over access permissions for workloads:
- Application level: Each application or service receives its own unique workload identity.
- Environment level: Multiple applications or services share the same workload identity if they operate within the same boundary, such as an environment or virtual network.
- Cluster level: All workloads within a cluster share a single workload identity. Configure a cluster-level workload identity to manage access to cluster-specific cloud services such as the following:
- Cloud storage: AWS S3, GCP Cloud Storage, or Azure Blob storage
- Databases: such as BigQuery, Redshift, ADX
- AI or ML services: Vertex AI, SageMaker, Azure ML
- Messaging or streaming services: Kinesis, Kafka, Event Hubs
To configure a workload identity, first update your provider cloud infrastructure. Then apply the workload identity to an environment, application, or cluster.
Prerequisites
Complete the following prerequisites:
- Obtain access to update your cloud provider infrastructure.
- Obtain the
C3.ClusterAdminrole to configure a workload identity.
Update cloud infrastructure
Update your cloud provider infrastructure to have service accounts with necessary permissions, and update the role binding with the service account. See the following sections for guidance for your service provider.
Google Kubernetes Engine (GKE)
If your organization uses GKE, set the following fields to the following values:
| Field | Value |
|---|---|
<GCP_PROJECT_ID> | Google Cloud Platform (GCP) project ID for this cloud security profile. |
<K8S_NAMESPACE_NAME> | Kubernetes namespace where you created the Kubernetes service account. |
<K8S_SERVICE_ACCOUNT_NAME> | Name of your Kubernetes service account. Run bash kubectl create serviceaccount <K8S_SERVICE_ACCOUNT_NAME> --namespace=<K8S_NAMESPACE_NAME> to set a name for your Kubernetes service account. |
<GCP_IAM_SERVICE_ACCOUNT_NAME> | Name of your IAM service account. Run bash gcloud iam service-accounts create <GCP_IAM_SERVICE_ACCOUNT_NAME> --project=<GCP_PROJECT_ID> to set a name for your IAM service account. |
Complete the following steps:
Grant the Kubernetes service account access to impersonate the IAM service account.
Patch the annotation on the Kubernetes service account:
Command Linekubectl patch serviceaccount <K8S_SERVICE_ACCOUNT_NAME> --namespace <K8S_NAMESPACE_NAME> -p '{ "metadata": { "annotations": { "iam.gke.io/gcp-service-account":"<GCP_IAM_SERVICE_ACCOUNT_NAME>@<GCP_PROJECT_ID>.iam.gserviceaccount.com" } }, "imagePullSecrets": [{"name":"docker-registry-secret"}] }'Create the
RoleBinding:Command Linekubectl create rolebinding <K8S_SERVICE_ACCOUNT_NAME> \ --role=c3 \ --serviceaccount=<K8S_NAMESPACE_NAME>:<K8S_SERVICE_ACCOUNT_NAME> \ --namespace=<K8S_NAMESPACE_NAME>If necessary, create the
ClusterRoleBinding:Command Linekubectl create clusterrolebinding c3-token-review-<K8S_SERVICE_ACCOUNT_NAME> \ --clusterrole=c3-token-review \ --serviceaccount=<K8S_NAMESPACE_NAME>:<K8S_SERVICE_ACCOUNT_NAME> \ --namespace=<K8S_NAMESPACE_NAME>
Azure Kubernetes Service (AKS)
If your organization uses AKS, set the following fields to the following values:
| Field | Value |
|---|---|
<AZURE_RESOURCE_GROUP> | Name of the Azure resource group. |
<AZURE_MANAGED_IDENTITY_NAME> | Name of the Azure managed identity. |
<AZURE_MANAGED_IDENTITY_CLIENT_ID> | Client ID of the Azure managed identity. |
<AKS_OIDC_ISSUER> | OIDC issuer URL. Run bash az aks show --name "<CLUSTER_NAME>" --resource-group "<RESOURCE_GROUP>" --query "oidcIssuerProfile.issuerUrl" --output tsv to retrieve the OIDC issuer URL. |
<K8S_NAMESPACE_NAME> | Kubernetes namespace where you created the Kubernetes service account. |
<K8S_SERVICE_ACCOUNT_NAME> | Name of your Kubernetes service account. Run bash kubectl create serviceaccount <K8S_SERVICE_ACCOUNT_NAME> --namespace=<K8S_NAMESPACE_NAME> to set a name for your Kubernetes service account. |
Complete the following steps:
Create managed identity and store the client ID:
Command Lineaz identity create --name <AZURE_MANAGED_IDENTITY_NAME> --resource-group <AZURE_RESOURCE_GROUP>Patch the annotation on the Kubernetes service account:
Command Linekubectl patch serviceaccount <K8S_SERVICE_ACCOUNT_NAME> --namespace <K8S_NAMESPACE_NAME> -p '{ "metadata": { "annotations": { "azure.workload.identity/client-id":"<AZURE_MANAGED_IDENTITY_CLIENT_ID>" } }, "imagePullSecrets": [{"name":"docker-registry-secret"}] }'Create the
federated-credentialidentity:Command Lineaz identity federated-credential create \ --name <AZURE_FEDERATED_IDENTITY_CREDENTIAL_NAME> \ --identity-name <AZURE_MANAGED_IDENTITY_NAME> \ --resource-group <AZURE_RESOURCE_GROUP> \ --issuer <AKS_OIDC_ISSUER> \ --subject system:serviceaccount:<K8S_NAMESPACE_NAME>:<K8S_SERVICE_ACCOUNT_NAME> \ --audience api://AzureADTokenExchangeCreate the
RoleBinding:Command Linekubectl create rolebinding <K8S_SERVICE_ACCOUNT_NAME> --role=c3 --serviceaccount=<K8S_NAMESPACE_NAME>:<K8S_SERVICE_ACCOUNT_NAME> --namespace=<K8S_NAMESPACE_NAME>If necessary, create the
ClusterRoleBinding:Command Linekubectl create clusterrolebinding c3-token-review-<K8S_SERVICE_ACCOUNT_NAME> \ --clusterrole=c3-token-review \ --serviceaccount=<K8S_NAMESPACE_NAME>:<K8S_SERVICE_ACCOUNT_NAME> \ --namespace=<K8S_NAMESPACE_NAME>
Amazon Elastic Kubernetes Service (EKS)
If your organization uses EKS, set the following fields to the following values:
| Field | Value |
|---|---|
<OIDC_PROVIDER> | Unique ID for the cluster OIDC provider. |
<AWS_ACCOUNT_ID> | Amazon Web Services (AWS) account ID. |
<K8S_NAMESPACE_NAME> | Kubernetes namespace where you created the Kubernetes service account. |
<K8S_SERVICE_ACCOUNT_NAME> | Name of your Kubernetes service account. Run bash kubectl create serviceaccount <K8S_SERVICE_ACCOUNT_NAME> --namespace=<K8S_NAMESPACE_NAME> to set a name for your Kubernetes service account. |
<AWS_IAM_ROLE_NAME> | Name of your AWS IAM role. |
Complete the following steps:
Create trust policy file, trust-relationship.json:
JSON{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/<OIDC_PROVIDER>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "<OIDC_PROVIDER>:aud": "sts.amazonaws.com", "<OIDC_PROVIDER>:sub": "system:serviceaccount:<K8S_NAMESPACE_NAME>:<K8S_SERVICE_ACCOUNT_NAME>" } } } ] }Create the IAM role:
Command Lineaws iam create-role --role-name <AWS_IAM_ROLE_NAME> --assume-role-policy-document file://trust-relationship.jsonPatch the annotation on the Kubernetes service account:
Command Linekubectl patch serviceaccount <K8S_SERVICE_ACCOUNT_NAME> --namespace <K8S_NAMESPACE_NAME> -p '{ "metadata": { "annotations": { "eks.amazonaws.com/role-arn":"arn:aws:iam::<AWS_ACCOUNT_ID>:role/<AWS_IAM_ROLE_NAME>" } }, "imagePullSecrets": [{"name":"docker-registry-secret"}] }'Create the
RoleBinding:Command Linekubectl create rolebinding <K8S_SERVICE_ACCOUNT_NAME> --role=c3 --serviceaccount=<K8S_NAMESPACE_NAME>:<K8S_SERVICE_ACCOUNT_NAME> --namespace=<K8S_NAMESPACE_NAME>If necessary, create the
ClusterRoleBinding:Command Linekubectl create clusterrolebinding c3-token-review-<K8S_SERVICE_ACCOUNT_NAME> \ --clusterrole=c3-token-review \ --serviceaccount=<K8S_NAMESPACE_NAME>:<K8S_SERVICE_ACCOUNT_NAME> \ --namespace=<K8S_NAMESPACE_NAME>
Configure a workload identity
Apply the workload identity to a cluster, environment, or application. Depending on where you are configuring a workload identity, run the following code snippets in the respective C3 AI Console.
Cluster level
Run the following code snippet to configure a workload identity at the cluster level:
CloudSecurityProfile.inst().withProjectId(<YOUR-PROJECTID>)
.withK8sServiceAccount(<YOUR-SERVICE-ACCOUNT-NAME>)
.withIamServiceAccount(<YOUR-IAM-SERVICE-ACCOUNT-NAME>)
.ensureSecurityProfileForCluster(<YOUR-CLUSTER-ID>)
applicationIdsList = CloudSecurityProfile.fetchAppsToBeReconfiguredForCluster(<YOUR-CLUSTER-ID>)
CloudSecurityProfile.reconfigureApps(applicationIdsList)Environment level
Run the following code snippet to configure a workload identity at the environment level:
CloudSecurityProfile.inst().withProjectId(<YOUR-PROJECTID>)
.withK8sServiceAccount(<YOUR-SERVICE-ACCOUNT-NAME>)
.withIamServiceAccount(<YOUR-IAM-SERVICE-ACCOUNT-NAME>)
.ensureSecurityProfileForEnv(<YOUR-ENVIRONMENT-ID>)
applicationIdsList = CloudSecurityProfile.fetchAppsToBeReconfiguredForEnv(<YOUR-ENVIRONMENT-ID>)
CloudSecurityProfile.reconfigureApps(applicationIdsList)Application level
Run the following code snippet to configure a workload identity at the application level:
CloudSecurityProfile.inst().withProjectId(<YOUR-PROJECTID>)
.withK8sServiceAccount(<YOUR-SERVICE-ACCOUNT-NAME>)
.withIamServiceAccount(<YOUR-IAM-SERVICE-ACCOUNT-NAME>)
.ensureSecurityProfileForApp(<YOUR-APPLICATION-ID>)
CloudSecurityProfile.reconfigureApps([<YOUR-APPLICATION-ID>])Remove a workload identity
You can remove a workload identity from a cluster, environment, or application. Depending on where you are removing a workload identity, run the following code snippets in the respective C3 AI Console.
Cluster level
Run the following code snippet to configure a workload identity at the cluster level:
CloudSecurityProfile.removeSecurityProfileForCluster(<YOUR-CLUSTER-ID>, true)
applicationIdsList = CloudSecurityProfile.fetchAppsToBeReconfiguredForCluster(<YOUR-CLUSTER-ID>)
CloudSecurityProfile.reconfigureApps(applicationIdsList)Environment level
Run the following code snippet to configure a workload identity at the environment level:
CloudSecurityProfile.removeSecurityProfileForEnv(<YOUR-ENVIRONMENT-ID>, true)
applicationIdsList = CloudSecurityProfile.fetchAppsToBeReconfiguredForEnv(<YOUR-ENVIRONMENT-ID>)
CloudSecurityProfile.reconfigureApps(applicationIdsList)Application level
Run the following code snippet to configure a workload identity at the application level:
CloudSecurityProfile.removeSecurityProfileForApp(<YOUR-APPLICATION-ID>, true)
CloudSecurityProfile.reconfigureApps([<YOUR-APPLICATION-ID>])