Use Workload Identity
Zuletzt aktualisiert am
Managing credentials for workloads is a critical security challenge. STACKIT Workload Identity eliminates the need for long-lived, static secrets (like API keys or OAuth client secrets) by federating Kubernetes workload identities via OIDC federation, securing access with short-lived, auto-rotated tokens.
For SKE clusters, this feature is natively integrated. A managed stackit-pod-identity-webhook intercepts pod creation to automatically inject Kubernetes projected service account tokens into your workloads. The workload then utilizes this OIDC token to perform a token exchange with an external Identity Provider (IdP) for short-lived access tokens. For example, if the workload application uses the functions of a STACKIT SDK, it accesses the STACKIT IdP via the STACKIT API.
Prerequisites
Section titled “Prerequisites”- A STACKIT project.
- A STACKIT Service Account with the appropriate permissions for your application.
- An SKE cluster.
How it works
Section titled “How it works”This flow shows how Kubernetes workload identity is exchanged for a short-lived STACKIT access token:
-
The
stackit-pod-identity-webhookintercepts the Pod’s creation request and, based onServiceAccountannotations, injects aprojectedvolume containing a signed JWT (theServiceAccounttoken) and corresponding environment variables into the Pod spec. -
The application’s SDK reads this injected token volume and sends the K8s
ServiceAccounttoken to the STACKIT IdP. -
The STACKIT IdP validates the token signature using the cluster’s Public OIDC Discovery endpoint (JWKS) and checks the configured assertions (for example, if the cluster identity is allowed to federate the requested IdP identity).
-
If the validation is successful the IdP returns a temporary scoped STACKIT access token.
-
The application uses the returned temporary access token to call the STACKIT API.
In practice, this keeps credentials short-lived and avoids static secrets in your workloads.
Step 1: Establish a trust relationship
Section titled “Step 1: Establish a trust relationship”To use Workload Identity, you must establish a trust relationship between your SKE cluster and the STACKIT Identity Provider (IdP).
-
Navigate to the STACKIT Portal to configure Service Account Federation. Refer to the STACKIT IdP documentation Create, manage and delete federated identity providers.
-
Provide your clusters
serviceAccountIssuerURL. You can obtain the URL from your cluster status via the SKE API, the STACKIT CLI or by inspecting your clusters status in the STACKIT Portal. -
Create an assertion mapping using the
sub(subject) claim to limit the usage of the STACKIT Service Account to a specific KubernetesServiceAccount. -
Format the
subclaim exactly assystem:serviceaccount:<namespace>:<k8s-serviceaccount>.
For more details about the claims of the cluster’s JWT see the Kubernetes docs about Schema for service account private claims.
Step 2: Configure your workloads
Section titled “Step 2: Configure your workloads”Once the trust relationship is established, you can enable Workload Identity for specific Pods by annotating their associated Kubernetes ServiceAccount.
- Set the
workload-identity.stackit.cloud/service-account-emailannotation on your KubernetesServiceAccount. - Ensure the annotation matches the STACKIT Service Account email configured in the Portal.
- The webhook automatically injects the necessary environment variables (like
STACKIT_SERVICE_ACCOUNT_EMAIL) and projected volume mounts for the STACKIT SDK to use.
For details, see the example workload provided in the stackitcloud/stackit-pod-identity-webhook GitHub repo.
Configuration reference
Section titled “Configuration reference”The following annotations can be applied to a Kubernetes ServiceAccount to configure the identity injection:
| Annotation | Purpose | Default value | Notes |
|---|---|---|---|
| Specifies the STACKIT Service Account email to assume the identity of. | None | Required. |
| The intended audience for the external token. | sts.accounts.stackit.cloud | Change this to federate with a different IdP. |
| How long the projected Service Account token is valid. | 600 (10 min) | Setting a short TTL (5—10 minutes) is recommended for security. |
| The custom IdP endpoint for token exchange. | https://accounts.stackit.cloud/oauth/v2/token | Use this to point to a non-default IdP environment (for example, your internal IdP). |
You can also skip token injection for specific resources using labels:
- Add the label
workload-identity.stackit.cloud/skip-pod-identity-webhook: "true"to a Pod to skip mutation. - Add the label
workload-identity.stackit.cloud/skip-pod-identity-webhook: "true"to a namespace to ignore all Pods within it.
Step 3: Consider security aspects and follow best practices
Section titled “Step 3: Consider security aspects and follow best practices”When operating workloads using Workload Identity in SKE, keep the following behaviors and security best practices in mind.
If a ServiceAccount is used only for Workload Identity, set automountServiceAccountToken: false in the Pod spec.
This prevents the ServiceAccount token from being mounted for generic API server communication, reducing the impact radius of a potential compromise.
Secure the VM metadata service with a network policy
Section titled “Secure the VM metadata service with a network policy”By default, IaaS virtual machines can obtain their own ServiceAccount tokens, and Pods running on these VMs can also retrieve these tokens by reaching the underlying VM’s metadata service. This behavior is intentional and aligns with how other major cloud providers operate.
However, if you want to strictly isolate your cluster workloads and prevent them from assuming the VM’s infrastructure identity, you can deploy a Kubernetes NetworkPolicy to block egress traffic to the metadata server.
Block access to the metadata IP
Section titled “Block access to the metadata IP”The standard IP address for the cloud instance metadata service is 169.254.169.254. You can restrict access to this IP by applying a default deny policy for that specific egress destination.
Here is an example NetworkPolicy that blocks egress traffic to the metadata service for all Pods in a namespace:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: deny-metadata-access namespace: defaultspec: podSelector: {} policyTypes: - Egress egress: - to: - ipBlock: cidr: 0.0.0.0/0 except: - 169.254.169.254/32Implementation details
Section titled “Implementation details”podSelector: {}: This empty selector applies the policy to all Pods in the namespace where the policy is deployed.cidr: 0.0.0.0/0: This allows egress traffic to all destinations globally.except: [169.254.169.254/32]: This explicitly carves out the metadata IP address, dropping any outgoing requests from your Pods attempting to reach it.
Credential rotation
Section titled “Credential rotation”The process of rotating the cluster’s signing key is automated by the SKE API.
- The IdP caches the JWKS response per URI for 1 hour. As long as the
kid(key ID) used to sign the token is present on the cached keys, the IdP accepts the token. - After a successful key rotation, old tokens signed by the previous key remain valid for up to 1 hour.
STACKIT SDK integration example
Section titled “STACKIT SDK integration example”When using the STACKIT SDK for Go, the SDK automatically detects the injected environment variables and handles the token exchange with the STACKIT IdP behind the scenes.
For details, see the example workload provided in the stackitcloud/stackit-pod-identity-webhook GitHub repo.