When service A needs to call service B, the traditional method is to share a secret: password, token, API key. This secret gets copied, leaks and lasts too long. Machine identity, or workload identity, offers something else: the service proves who it is with a short-lived cryptographic document, issued by an authority the recipient knows how to verify. This lesson is for the DevOps engineer who wants to know when this approach replaces a secret, and when it cannot.
The mechanisms were measured. On SPIRE 1.15.3, an X509-SVID lasts 1 hour
and a JWT-SVID 5 minutes. On a kind cluster (Kubernetes 1.37), a
projected ServiceAccount token carries the sts.amazonaws.com audience, lasts
one hour, and is invalidated as soon as its pod disappears. On the cloud
side, the GKE documentation no longer requires the ServiceAccount
annotation, and AKS demands a pod label that many tutorials forget.
What you will learn
- Distinguish a machine identity from a shared secret
- Separate the two families: internal identity (SPIFFE/SPIRE) and cloud federation (OIDC)
- Decode a projected ServiceAccount token and what the cloud checks in it
- Configure federation on GKE, EKS and AKS with each cloud's real prerequisites
- Choose between machine identity, dynamic secret and static secret depending on the target system
- Link this approach to requirement SOCLE-SEC-GEN-5 (in French) on short-lived identities
The shared secret problem
Before looking at solutions, you need to see what breaks in the usual model. The shared secret is not only a confidentiality problem: it also makes traceability impossible and rotation costly. These three flaws go together, and it is together that they justify changing approach.
Classic scenario
The payment-api service needs to call user-api to validate a user. The
traditional approach puts a common API key in the configuration on both
sides. The table after the file sums up what this shared key costs in
security and operations.
# ❌ payment-api/config.yamluser_api: url: https://user-api.internal api_key: "shared-secret-between-services"| Problem | Consequence |
|---|---|
| Shared secret | If one service is compromised, so is the other |
| Copied everywhere | Configurations, environment variables, backups |
| No attribution | Impossible to know which service made which request |
| Painful rotation | Changing the secret means redeploying every service |
The alternative: proving your identity
Instead of sharing a secret, each service proves who it is with a cryptographic document, an X.509 certificate or a signed JWT. The target service checks three things, in this order. The third one is about authorisation, distinct from identity, as a later section shows.
- The document is valid: signed by a trusted authority, not expired.
- The identity matches the expected service.
- The service has the right to call this API.
There is no longer a long-lived shared application secret. Each service has its own identity, short-lived and verifiable. It is not "impossible to copy": a stolen token remains usable until its expiry, hence the importance of durations in minutes or hours.
What is a machine identity
The term covers a precise reality, not to be confused with a simple service account with a password. A machine identity is defined by what it contains, by what sets it apart from a secret, and by the mechanism that issues it.
Definition
A machine identity (or workload identity) is a cryptographic document that identifies a workload (pod, VM, service, function) in a verifiable way. It is not a password: it is the result of an attestation, "this workload really is who it claims to be, and here is the signed proof".
Components of a machine identity
Four elements are always present, whatever the technology. The most often neglected is the last one: without attestation, a workload could simply claim an identity that does not belong to it, and the whole edifice collapses.
| Component | Role |
|---|---|
| Unique identifier | Name of the workload (for instance spiffe://example.org/payment-api) |
| Cryptographic document | X.509 certificate or signed JWT |
| Short lifetime | Minutes or hours, not months |
| Attestation | Proof that the workload really runs where it claims to |
Difference from a secret
The distinction is fundamental. A shared secret is a value that anyone who holds it can present, anywhere, for months. A machine identity is issued for an attested workload, carries its name and expires quickly.
| Aspect | Shared secret | Machine identity |
|---|---|---|
| Nature | Sensitive value to protect | Signed, verifiable document |
| Issuance | Created once, copied by hand | Issued for an attested workload |
| Duration | Often long | Short (1 h for an X509-SVID by default) |
| Attribution | Difficult | Direct, one identity per workload |
| End of life | Manual revocation, often incomplete | Automatic expiry, renewal |
Two families of workload identity
When talking about machine identity, you need to distinguish two sub-models that share the same principle but meet different needs. The diagram puts them side by side: on the right, services that authenticate with each other; on the left, a pod that accesses a cloud API, with the cloud IAM in red at the centre of the decision.
Internal identity (M2M)
The identity is used to authenticate services with each other, inside an infrastructure, what is called M2M (machine to machine). This is the domain of SPIFFE/SPIRE and service meshes (Istio, Linkerd, Cilium). X.509 certificates or JWTs are signed by an authority specific to the organisation, and are used for mTLS (mutual TLS, where both sides present a certificate).
This family is independent of the cloud provider. On the other hand, it requires a local agent (SPIRE Agent) or a sidecar proxy (Envoy) to deliver and use the identity.
Identity federation to the cloud
The identity is used to access cloud services (S3, GCS, Azure Key Vault) from a workload, without a static key. This is the domain of Workload Identity Federation for GKE, IRSA and EKS Pod Identity at AWS, and Microsoft Entra Workload ID on AKS.
The most widespread principle relies on the cluster's OIDC issuer: the cloud checks the pod's token and returns temporary credentials. Each cloud has its own prerequisites, and AWS offers a variant, EKS Pod Identity, that does without an OIDC provider.
Identity and authorisation: two separate questions
Identity answers "who is this workload?", never "what can it do?". They are two separate mechanisms, configured in two places. The table puts them side by side with their usual tools.
| Question | Mechanism | Examples |
|---|---|---|
| Who am I? | Identity (attestation) | SPIFFE SVID, OIDC token |
| What can I do? | Authorisation (policy) | IAM policies, Istio AuthorizationPolicy, Vault policies |
A workload can have a valid identity and be refused access if the policy does not allow it. The reverse is more dangerous: an overly broad policy, of the "any authenticated workload" kind, makes the identity useless. Each layer therefore carries its own policy:
- Service mesh:
AuthorizationPolicy(Istio) or identity-based network policy (Cilium) - Vault or OpenBao: policies tied to the SPIFFE ID or the Kubernetes role
- Cloud IAM: role associated with the ServiceAccount (GKE, IRSA, EKS Pod Identity, AKS)
- Application: check of the JWT's
subor the certificate's SAN
How attestation works
The attestation mechanism varies by family. SPIRE itself attests the node and then the workload; cloud federation relies on the token that Kubernetes has already signed. Both flows are detailed below, with what the measurement shows.
Attestation with SPIRE
SPIRE works in two phases: it first attests the node, then the workload running on it. The diagram follows the exchange between the workload, the agent and the server, up to the delivery of an automatically renewed SVID.
-
Node attestation
The SPIRE Agent proves its node's identity to the SPIRE Server. Depending on the environment, the proof is a cloud instance identity document, a TPM certificate, a Kubernetes ServiceAccount token, or a single-use join token.
-
Workload attestation
When a process calls the Workload API (a Unix socket), the agent identifies the caller by its PID and derives selectors from it:
unix:uid, Kubernetes namespace and ServiceAccount, labels. These selectors are matched against the server's registration entries. -
SVID issuance
If an entry matches, the workload receives an SVID. Measured on SPIRE 1.15.3, with a
unix:uid:0entry: an X509-SVID valid for 1 hour (default_x509_svid_ttl) and a JWT-SVID of 5 minutes (default_jwt_svid_ttl), renewed automatically.
$ spire-agent api fetch x509 -socketPath /tmp/agent.sockSPIFFE ID: spiffe://example.org/payment-apiSVID Valid After: 2026-10-01 13:44:19 +0000 UTCSVID Valid Until: 2026-10-01 14:44:29 +0000 UTCCA #1 Valid Until: 2026-10-02 13:44:21 +0000 UTCThe server's intermediate CA lasts 24 hours by default (ca_ttl): even the
signing authority turns over quickly. It is this chain of short durations,
more than the encryption, that limits the value of a stolen SVID.
Cloud flow: OIDC federation
Cloud solutions follow a different flow, based on the cluster's OIDC issuer. The diagram shows the four steps: the kubelet projects a token into the pod, the pod exchanges it with the cloud IAM, which checks the signature with the issuer's public keys, then returns temporary credentials.
What the projected token contains: measured
The projected token is a JWT signed by the cluster API. To see it, a
payment-api pod mounts a projected volume serviceAccountToken with a
dedicated audience, sts.amazonaws.com, and a duration of 3600 seconds.
Measured on kind 0.33 with Kubernetes 1.37, by decoding the middle part of the
token:
# Pod excerpt: projected volume with audience and durationvolumes: - name: cloud-token projected: sources: - serviceAccountToken: path: token audience: sts.amazonaws.com expirationSeconds: 3600{ "aud": ["sts.amazonaws.com"], "iss": "https://kubernetes.default.svc.cluster.local", "sub": "system:serviceaccount:payment:payment-api", "exp": 1790865974, "iat": 1790862374, "kubernetes.io": { "namespace": "payment", "pod": { "name": "payment-api", "uid": "22baa468-7e25-4636-9220-51caa006d630" }, "serviceaccount": { "name": "payment-api", "uid": "960d1fb7-2b94-4d0f-bdee-fa36a5f4ff50" } }}Three fields make federation secure. The audience (aud) prevents the
token from being replayed against another service, the subject (sub)
designates the namespace and the ServiceAccount precisely, and the gap
exp - iat is 3600 seconds. The cloud checks the signature with the keys
published at /.well-known/openid-configuration then /openid/v1/jwks.
Two measurements complete the picture. A duration under 10 minutes is
rejected by the API: expirationSeconds: 300 gives
may not specify a duration less than 10 minutes. And the default token mounted
in the same pod (Kubernetes API audience) showed one year of validity, an
effect of the API server's --service-account-extend-token-expiration option,
enabled by default for compatibility. Hence the value of a dedicated token,
short-lived and with a precise audience, for any federation.
SPIFFE: a standard for workload identity
SPIFFE (Secure Production Identity Framework For Everyone) is a CNCF standard, where the project and its SPIRE implementation have reached graduated status. It defines the format of identities and how they are delivered, independently of the cloud and the orchestrator.
SPIFFE ID
The SPIFFE ID is a unique identifier per workload, written as a URI. Its first part, the trust domain, designates the authority that guarantees the identity; the path that follows describes the workload according to a convention you choose, often modelled on the Kubernetes namespace and ServiceAccount.
spiffe://trust-domain/path/to/workload
# Examplesspiffe://example.org/payment-apispiffe://example.org/ns/production/sa/frontendspiffe://mycompany.com/region/eu-west-3/service/checkoutSVID (SPIFFE Verifiable Identity Document)
The SVID is the cryptographic document that carries the SPIFFE ID and proves it belongs to this workload. It comes in two formats, and this is no detail: the format determines what the target system must be able to verify.
| Format | Use |
|---|---|
| X.509-SVID | Certificate for mTLS between services |
| JWT-SVID | Token for APIs and proxies that do not handle mTLS |
SPIRE
SPIRE (SPIFFE Runtime Environment) is the reference implementation of the SPIFFE APIs. It consists of three elements, the first of which becomes a critical infrastructure component: without it, no SVID is issued or renewed any more.
| Component | Role |
|---|---|
| SPIRE Server | Central authority, signs SVIDs, checks attestations |
| SPIRE Agent | Runs on each node, attests workloads, delivers SVIDs |
| Workload API | Unix socket through which workloads retrieve their SVIDs |
The SPIRE Server is operated with the requirements of a central service: high availability, shared database, monitoring of attestation failures. An outage does not cut everything immediately, the agents keep their SVIDs in cache; but without renewal, these one-hour SVIDs expire one after another.
Cloud Workload Identity
The three major clouds offer their own identity federation between Kubernetes and their IAM. The principle is common, but the prerequisites differ, and that is where deployments fail: an annotation alone, without the configuration on the cluster and IAM side, has no effect.
Workload Identity Federation for GKE
On GKE, federation is enabled at cluster level with an identity pool, then IAM roles are granted directly to the Kubernetes ServiceAccount through a principal identifier. This is the best practice stated by the Google documentation, which then requires no annotation.
# Enable federation on the clustergcloud container clusters update CLUSTER_NAME \ --location=LOCATION \ --workload-pool=PROJECT_ID.svc.id.goog
# Grant a role directly to the Kubernetes ServiceAccount payment/payment-apigcloud projects add-iam-policy-binding projects/PROJECT_ID \ --role=roles/storage.objectViewer \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/payment/sa/payment-apiThe older method remains possible when a Google API cannot yet recognise this
principal: you link the Kubernetes ServiceAccount to an IAM service account,
which requires both a policy granting roles/iam.workloadIdentityUser
and the iam.gke.io/gcp-service-account annotation on the ServiceAccount.
AWS: IRSA or EKS Pod Identity
AWS offers two mechanisms. IRSA (IAM Roles for Service Accounts) requires
an IAM OIDC provider for the cluster, a trust relationship on the role
with a StringEquals condition on the token's sub, and the ServiceAccount
annotation. The AWS account has 12 digits:
apiVersion: v1kind: ServiceAccountmetadata: name: payment-api namespace: payment annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/payment-apiEKS Pod Identity is the alternative the AWS documentation presents as
simpler: no OIDC provider, an association declared in EKS between a role
and a ServiceAccount, an agent (EKS Pod Identity Agent) as a DaemonSet, and a
single trusted principal, pods.eks.amazonaws.com, for all clusters. It only
works on EKS, with Linux EC2 nodes: neither Fargate nor EKS Anywhere.
Microsoft Entra Workload ID on AKS
On AKS Standard, you need to enable the OIDC issuer and Workload ID on the cluster, then create a federated identity credential that links the ServiceAccount to the managed identity. On the Kubernetes side, two elements are needed, and the second is the one people forget:
apiVersion: v1kind: ServiceAccountmetadata: name: payment-api namespace: payment annotations: azure.workload.identity/client-id: 00000000-0000-0000-0000-000000000000---# In the pod template: without this label, the webhook injects nothingmetadata: labels: azure.workload.identity/use: "true"The Microsoft documentation is explicit: only pods carrying the
azure.workload.identity/use: "true" label are modified by the webhook,
which injects the projected token and the AZURE_FEDERATED_TOKEN_FILE variable.
The Kubernetes token lasts 3600 seconds by default, adjustable from 3600 to
86,400. On AKS Automatic, the OIDC issuer and Workload ID are preconfigured.
Identity is not enough: you need an integration point
Having an identity is useless if the workload does not know how to use it. The identity must be consumed by an integration layer, and the choice of this layer often decides the effort: changing the code, or entrusting the identity to the infrastructure.
| Integration point | How it works |
|---|---|
| Envoy sidecar proxy | The proxy handles mTLS and presents the certificate |
| Service mesh (Istio, Linkerd, Cilium) | Identity injected through a sidecar proxy or eBPF |
| Cloud SDK (AWS SDK, Google Cloud, Azure Identity) | The SDK detects the federated credentials |
| Vault agent or CSI driver | Exchanges the identity for a dynamic secret |
| Application library | The application loads the certificate or JWT itself |
If your applications do not handle mTLS, start with a proxy or a service mesh: the identity is managed without changing the code. Recent cloud SDKs read federated credentials on their own; an SDK that is too old keeps looking for a static key.
You do not remove all initial trust
Machine identity removes the long-lived shared application secret. It does not remove all initial trust: a chain of elements remains necessary, and each becomes an attack surface to protect, audit and maintain.
| Element of trust | Role |
|---|---|
| Trust anchor (root CA) | Signs the SPIFFE certificates |
| Trust bundle | Distributed to workloads to verify SVIDs |
| OIDC issuer | Publishes the keys the cloud uses to verify tokens |
| Federation configuration | Links the ServiceAccount to the cloud role or identity |
| Attestation plugin | Verifies the node's identity at startup |
You therefore replace a long-lived shared secret with a more robust cryptographic trust infrastructure. The lesson on secret zero explains why this root, and not a password, becomes the critical point.
Use cases
The following four situations cover most of what you meet in production. Two are pure: identity is enough from start to finish. The other two are hybrid: identity is used to obtain something else, a dynamic secret or temporary cloud credentials.
Service to service (mTLS)
Two microservices communicate with SPIFFE certificates: each checks the other's identity, without a shared secret. In practice, mTLS goes through a proxy (Envoy, managed by a mesh) or a library that loads the X.509-SVIDs from the Workload API.
Pod to database
PostgreSQL, MySQL and most relational databases cannot verify an SVID: they expect a username and a password. Machine identity therefore does not replace the credential, it is used to obtain it from a vault, instead of a static password.
- The pod has an identity (SPIFFE or Kubernetes token).
- It presents it to Vault or OpenBao.
- The vault checks it and generates dynamic database credentials.
- The pod connects with these temporary credentials.
This is a hybrid use, and the best tooled today: the lesson on the lifecycle measures these dynamic credentials, a distinct PostgreSQL user lasting one hour per read.
CI/CD to cloud
This is the quickest case to set up: GitHub Actions issues an OIDC token that describes the repository and the branch, and AWS as well as GCP can verify it. Instead of keys stored in the repository secrets, the job obtains temporary credentials. The following workflow passes actionlint, zizmor 1.30.0 and poutine 1.1.6 with no findings.
name: deploy
on: push: branches: [main]
permissions: {}
jobs: deploy: runs-on: ubuntu-24.04 environment: production permissions: id-token: write # issuance of the job's OIDC token contents: read steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false
- name: Obtenir des identifiants AWS temporaires uses: aws-actions/configure-aws-credentials@e1253824e5c10ff9df46874f81ed3ec929e19cfd # v6.3.0 with: role-to-assume: arn:aws:iam::123456789012:role/github-deploy aws-region: eu-west-3 role-duration-seconds: 900
- name: Vérifier l'identité obtenue run: aws sts get-caller-identityWithout role-duration-seconds, the action requests one hour, the default
in its action.yml. The
lesson on secrets in CI/CD
details the trust relationship on the AWS side, which must constrain the
token's sub to the repository and the environment.
Proxy or service mesh
This is the path to favour when you cannot modify the applications: identity is managed outside the code, by the infrastructure. Each pod receives a sidecar proxy or an eBPF agent that carries the identity, traffic between pods is encrypted with mTLS, and authorisation is based on identity, not on secrets.
Identity, dynamic secret or static secret?
To choose, only one question matters: can the target system verify a certificate or a JWT, or does it expect a password? The table spells out the answer per situation; the detailed comparison of the other two models is in static or dynamic secrets (in French).
| Need | Recommended approach | Why |
|---|---|---|
| Kubernetes pod to cloud API (S3, GCS) | Native federation (GKE, IRSA or EKS Pod Identity, AKS) | No secret, token verified by the cloud |
| Internal service to internal service | SPIFFE/SPIRE or service mesh | mTLS with identity, no M2M secret |
| Service to classic database | Dynamic secret (Vault, OpenBao) | The database does not understand SPIFFE certificates |
| Third-party API with a fixed key | Static secret in a vault | The API imposes a key |
| Short SSH access | Signed SSH certificate (Vault SSH) | No permanent SSH key |
| CI/CD to cloud | OIDC federation (GitHub to AWS or GCP) | No stored access key |
| Legacy application without mTLS | Dynamic secret or static in a vault | The application cannot consume a certificate |
The decision rule fits in three cases. Machine identity when the target verifies a certificate or a JWT; dynamic secret when it expects a password but tolerates rotation; static secret in a vault when no alternative exists.
When not to use machine identity
Machine identity is not always the right starting point. It can be the right answer in the long run without being the immediate priority, and a SPIRE project launched too early ties up a team while secrets remain in the code.
| Situation | Why postpone | Start with |
|---|---|---|
| Legacy application that cannot be modified | Cannot reload a certificate | Dynamic secret or static in a vault |
| External API with a fixed key | The API imposes its model | Key stored in a vault |
| Team without PKI or OIDC culture | Learning curve | Vault and automatic rotation |
| Secrets still in the code | The priority is to get them out | Detection and vault |
| Infrastructure outside Kubernetes | Less native attestation | Vault with a suitable auth method |
If the team has not yet moved its secrets out of the source code, deploying SPIFFE/SPIRE is premature. Secret detection (in French) and migration to a vault are prior steps.
Technical prerequisites
Before deploying a machine identity solution, check that your infrastructure is ready. The two families do not cost the same: SPIRE amounts to running an internal PKI, cloud federation delegates most of it to the provider.
For SPIFFE/SPIRE
Deploying SPIRE amounts to running an internal public key infrastructure. The two most underestimated rows are trust bundle distribution, without which workloads cannot verify their peers, and time synchronisation, which silently invalidates one-hour certificates when it drifts.
| Prerequisite | Detail |
|---|---|
| Trust anchor | Root CA or upstream authority to sign SVIDs |
| Highly available SPIRE Server | Replication, shared database (PostgreSQL, MySQL) |
| SPIRE Agent on each node | Kubernetes DaemonSet or system agent |
| Attestation plugin | Suited to the environment (Kubernetes, AWS, GCP, TPM) |
| Observability | Metrics and logs of attestation failures |
| Trust bundle distribution | Mechanism to deliver and renew the bundle |
| Time synchronisation | NTP monitored on all nodes |
For cloud federation
The list is shorter, because the cloud runs most of it. Your work is limited to exposing the OIDC issuer (except with EKS Pod Identity), creating the role and describing the trust relationship. Mind the last row of the table: an old SDK cannot read federated credentials.
| Prerequisite | Detail |
|---|---|
| Cluster OIDC issuer | Configuration specific to each cloud |
| IAM role or managed identity | Created with minimal permissions |
| Federation link | Principal identifier (GKE), OIDC trust (IRSA), association (EKS Pod Identity), federated credential (AKS) |
| Compatible SDK | Version that detects federated credentials |
Common pitfalls
These six mistakes come up in first deployments. The first two are the most costly, because they give a false sense of security: the workload authenticates, the logs are clean, and protection is nil because authorisation is too broad or the cluster-side configuration was never enabled.
| Pitfall | Consequence | How to avoid it |
|---|---|---|
| Believing identity replaces authorisation | Workloads authenticated but over-authorised | Fine-grained authorisation policies |
| Thinking an annotation is enough | Without cluster and IAM configuration, no effect | Check the prerequisites (OIDC issuer, pool, AKS label) |
| Assuming every application handles mTLS | The application ignores the certificate | Sidecar proxy or service mesh |
| Ignoring renewal | The certificate expires, the application goes down | Monitor TTLs, test renewals |
| Multiplying identities without governance | Explosion of SPIFFE IDs and policies | Naming convention, policies as code |
| Not monitoring the SPIRE Server | No SVID renewed any more | Alerts on SPIRE metrics |
Limits and challenges
Where pitfalls are configuration mistakes, the limits below are structural: they have to be budgeted for. Two often decide the schedule: the applications' real ability to use a certificate, and the identity control plane becoming one more critical service.
| Limit | Real effect | Mitigation |
|---|---|---|
| Application integration | The application cannot use a certificate or a JWT | Proxy, service mesh or SDK |
| Critical control plane | SPIRE outage: renewals fail | High availability, local cache, monitoring |
| Harder debugging | Authentication, authorisation or transport failure hard to isolate | Structured logs per layer |
| Partial compatibility | Some systems speak neither mTLS nor OIDC | Dynamic or static secret in a vault |
| Identity governance | Explosion of identities and policies | Naming convention, policies as code |
| Clock drift | Short certificates rejected | Monitored NTP |
| Hybrid cases | The whole information system does not speak SPIFFE or OIDC | Progressive approach |
Progressive migration
A big-bang switch is not realistic: the six steps below describe a path where each flow migrates independently and remains reversible. The order matters, especially the last step: as long as the old secrets exist, they remain usable and the attack surface has not shrunk.
-
Inventory the M2M flows
List the communications between services that use shared secrets, and spot the most sensitive ones.
-
Prioritise by criticality and feasibility
Start with sensitive flows (payment, personal data) and compatible ones (services already in Kubernetes, mTLS possible through the mesh).
-
Deploy the identity infrastructure
SPIRE for internal M2M, native federation for cloud access. The two coexist.
-
Migrate service by service
Replace each shared secret with identity-based mTLS or OIDC federation, and validate each migration on its own.
-
Keep the dynamic secret for the existing estate
Systems that speak neither mTLS nor OIDC stay on Vault or OpenBao, with dynamic credentials.
-
Revoke the old secrets
Once the migration has been observed in production, revoke then delete the secrets that are no longer needed.
Decision table
This summary condenses the page into one entry per situation, to keep at hand when deciding. The criterion is always the same: can the target system verify a certificate or a JWT, or does it expect a password?
| Situation | Recommended approach |
|---|---|
| Internal Kubernetes communication | SPIFFE/SPIRE or service mesh |
| Pod to cloud (AWS, GCP, Azure) | Native federation (GKE, IRSA or EKS Pod Identity, AKS) |
| CI/CD to cloud | OIDC federation |
| Service to classic database | Dynamic secret (Vault, OpenBao) |
| Third-party API with a fixed key | Static secret in a vault |
| Legacy application without mTLS or OIDC | Dynamic secret |
| Short SSH access | Signed SSH certificate |
Resources
These official documentations were used to verify the prerequisites in this lesson. They change quickly, especially on the cloud side: reread them before a deployment, in particular for the required annotations and labels.
- SPIFFE: workload identity standard (CNCF)
- SPIRE concepts: attestation, SVIDs, trust bundles
- Workload Identity Federation for GKE: Google Cloud documentation
- EKS Pod Identity and IRSA: AWS documentation
- Microsoft Entra Workload ID on AKS: Microsoft documentation
- Envoy with X.509-SVIDs: integration through a proxy
Key points
- A machine identity is a signed document, issued for an attested workload, and short-lived: 1 hour for an X509-SVID, 5 minutes for a JWT-SVID (SPIRE 1.15.3).
- Two families: internal identity (SPIFFE/SPIRE, mTLS) and cloud federation (OIDC), complementary.
- Identity does not replace authorisation: an overly broad policy makes the identity useless.
- A projected token carries an audience, a subject and a duration; measured, it is invalidated when its pod is deleted.
- The real prerequisites: pool and principal on GKE (no annotation), OIDC provider or EKS Pod Identity on AWS,
azure.workload.identity/uselabel on AKS. - Identity needs an integration point: proxy, mesh, SDK or vault agent.
- It is not always the priority: getting secrets out of the code and adopting a vault come first.
- The evidence expected by SOCLE-SEC-GEN-5 is the use of short-lived or ephemeral identities (OIDC) rather than long-lived secrets.
Knowledge check
Check that you have the essentials of this lesson. The questions only cover what has just been explained here.
Knowledge check
Check what you have learned with this interactive quiz
How it works
- The timer starts when you click Start
- Multiple choice, true/false and short answer questions
- You can move between questions
- Detailed results are shown at the end
Starts the quiz and the timer
Review
(0/0)Score by domain
A domain groups several guides and gets several questions, so its score is more reliable than a per-topic score, which often rests on a single question.
Summary
Strengths
No topic passed at 80% on at least two questions yet.
Weak areas
No topic below the pass mark.
Recommended next
Hints before you try again?
Continue the course: Responding to a compromised secret: revoke, rotate, analyse
Continue the course: Secrets in code and Git history
A new full quiz with random questions
Work again only on the questions you missed