Skip to content
Stackship documentation Svenska

Managed identitiesUsers

Use a managed identity in code

Get a token for a workload's managed identity from inside its pod, with the .NET client or a plain HTTP call.

Code running in a workload's pod can get a short-lived access token for the workload's managed identity. The token lets the code call platform services as the workload, with the rights of the identity's roles — nothing more.

Important

Another workload's pods cannot get this token, but people can. Anyone who can run commands in the workload's pods (Kubernetes pods/exec: Owner, Contributor, Apps Operator, Blueprints Operator, Platform Owner and Platform Contributor, assigned on the resource group or above) can read the pod's proof and fetch the token. Anyone who can create pods in the resource group's namespace (Owner, Contributor, Platform Owner, Platform Contributor, with direct cluster access) can get a token for any identity in the resource group. Giving an identity a role therefore gives it, in effect, to them as well — see How workload tokens are issued.

What the pod is given

Variable Value
STACKSHIP_IDENTITY_RESOURCE_UID Which identity to ask for
STACKSHIP_IDENTITY_TOKEN_ENDPOINT Where to ask, inside the cluster
STACKSHIP_IDENTITY_POD_TOKEN_PATH The file holding the pod's proof of who it is

Container instances are also given STACKSHIP_IDENTITY_PRINCIPAL_ID and STACKSHIP_IDENTITY_CLIENT_ID when the instance's spec.identity records them.

Which containers get them:

Workload Containers
App The app's container, in every slot
Function The function's container; the identity is its function namespace's
Container instance Every container and init container of a component that references a vault secret, or that asks for the identity with identityInjection: true in the API or a blueprint template. Other components get none

The platform's secret-init container, which fetches vault secrets when a pod starts, gets them as well. The file-agent sidecar of a workload with a persistent volume gets none.

With .NET

The Stackship.Identity.Client package targets .NET 10. ManagedIdentityCredential reads the variables above and fetches and caches tokens; DefaultStackshipCredential uses it when the variables are present, and otherwise falls back to a service account's credentials from STACKSHIP_CLIENT_ID, STACKSHIP_CLIENT_SECRET and STACKSHIP_TOKEN_ENDPOINT — handy on a developer machine.

csharp
using Stackship.Identity.Client;

var credential = new DefaultStackshipCredential();
var token = await credential.GetTokenAsync();

token.Token is the bearer token and token.ExpiresOn when it expires.

To put the token on every outgoing request, give an HttpClient the handler:

csharp
var http = new HttpClient(new StackshipTokenCredentialHandler(credential));

services.AddDefaultStackshipCredential() registers the credential for dependency injection as StackshipTokenCredential.

The Secrets client takes the same credential — see The .NET client.

With plain HTTP

Send a POST to the token endpoint with the identity's UID in the path and the pod's proof in the header X-Stackship-Pod-Token:

bash
curl -s -X POST \
  -H "X-Stackship-Pod-Token: $(cat "$STACKSHIP_IDENTITY_POD_TOKEN_PATH")" \
  "$STACKSHIP_IDENTITY_TOKEN_ENDPOINT/$STACKSHIP_IDENTITY_RESOURCE_UID/token"

The answer is JSON with access_token, token_type (Bearer), expires_in in seconds, client_id and principal_id. Ask again when the token expires, and read the proof file again each time: it is replaced regularly.

When it answers 404

The endpoint answers 404 Not Found alike for every refusal — no such identity, no or an invalid proof, a proof from another workload's pod, or a call from outside the cluster — so that it does not reveal which identities exist. Check that the call runs inside the workload's own pod, that the three variables are set, and that the proof file exists.

A token only proves who the workload is. What it may do comes from the identity's roles — see Give a managed identity a role.