Your deploy pipeline shouldn't hold a cloud key that works forever.
An access key pasted into a CI variable years ago is still one of the easiest ways into a cloud account. We move pipelines, containers and servers to workload identity federation, where each job gets a short-lived token tied to what it is, and then we delete the old key.
Machine and workload identity gives software its own verifiable identity.
Pipelines, containers and servers can then authenticate without stored passwords or keys. Cohash replaces static cloud credentials with federation. We use GitHub Actions OIDC for AWS, Azure and Google Cloud, and Microsoft Entra Workload ID for Kubernetes. SPIFFE and SPIRE cover services that span clouds, and AWS IAM Roles Anywhere covers servers outside AWS.
you probably need this if
Deploy pipelines hold cloud access keys that never expire.
Kubernetes workloads in one namespace share a single service account.
Entra app registrations still authenticate with client secrets.
terms on this pageActionsdefinitionThe replacement for both. Each one is a small JavaScript function you attach to a trigger such as post-login. It carries its own secrets, and other Actions can't read them.explained in a field note →Workload identity federationdefinitionA trust set up so a pipeline outside Azure, such as GitHub Actions, can swap its own short-lived token for an Azure token without storing any secret.explained in a field note →federationdefinitionMirroring the Hive metastore as a foreign catalog in Unity Catalog, so Unity Catalog permissions apply to old tables before they move.explained in a field note →workload identitydefinitionAn identity for software rather than a person. The Entra provisioning service uses one to prove who it is with a short-lived token, so nobody has to store a password for it.explained in a field note →
From the first call to a setup your own team can run.
Here's what usually prompts a call about your Machine & Workload Identity, what we do about it and in which order, and where you end up.
01 · where it hurts02 · what we change03 · how it runs04 · where you end up
incident board · machine & workload identity3 open
openDeploy pipelines hold cloud access keys that never expire.
recurringKubernetes workloads in one namespace share a single service account.
blockedEntra app registrations still authenticate with client secrets.
exposure
CI/CD federationKubernetes workload identitySPIFFE and SPIREServers outside the cloudStatic credential retirementLeast-privilege role design
startrehearsehandover
Inventory static credentials
Pick a pattern per workload
Migrate and verify
Add guardrails
we are here
ready to hand over
Production deploys get short-lived credentials only from the protected environment, the…
Pods get tokens tied to their own service account, no client secret sits in the cluster…
The servers now get temporary AWS credentials based on their machine certificate.
Static credential inventory mapped to workloads
chapter 01 · where it hurts
Why teams reach out
Deploy pipelines hold cloud access keys that never expire.
Kubernetes workloads in one namespace share a single service account.
Entra app registrations still authenticate with client secrets.
chapter 02 · what we change
How we solve it
CI/CD federation
Kubernetes workload identity
SPIFFE and SPIRE
Servers outside the cloud
Static credential retirement
Least-privilege role design
chapter 03 · how it runs
Our approach
Inventory static credentials
Pick a pattern per workload
Migrate and verify
Add guardrails
chapter 04 · where you end up
What changes
Production deploys get short-lived credentials only from the protected environment, the admin IAM user is gone, and a fork or feature branch can't assume the prod role.
Pods get tokens tied to their own service account, no client secret sits in the cluster, and the subscription-wide grant is gone.
The servers now get temporary AWS credentials based on their machine certificate.
Static credential inventory mapped to workloads
what we do
Where we spend the hours
6 areas of work, each one done by an engineer who has run it in production.
Pipelines trade their OIDC token for cloud credentials scoped to one repository, branch or environment. We write the trust conditions tightly enough that a fork or a feature branch can't deploy to production.
Pods on AKS use Microsoft Entra Workload ID through projected service account tokens, and we apply the equivalent native pattern on other clusters. One Kubernetes service account per workload, never one shared per namespace.
Services that talk mTLS across clusters and clouds get SPIFFE identities from SPIRE, which attests both the node and the workload first. Both projects graduated from the CNCF in 2022. Entra can federate with SPIFFE identities.
IAM Roles Anywhere trades an X.509 certificate from your own CA for temporary AWS credentials. Entra federated identity credentials do the same thing for tokens from an outside issuer. No long-lived key either way.
Entra app registrations with client secrets. AWS access keys nobody uses. Google service account keys. We find them, match each to its workload, and retire them once federation is working.
Roles shaped from the API calls each workload actually makes in cloud audit logs, with permission boundaries or deny policies that stop privileges creeping back.
capability 01 / 06in production
CI/CD federation
Pipelines trade their OIDC token for cloud credentials scoped to one repository, branch or environment. We write the trust conditions tightly enough that a fork or a feature branch can't deploy to production.
Pods on AKS use Microsoft Entra Workload ID through projected service account tokens, and we apply the equivalent native pattern on other clusters. One Kubernetes service account per workload, never one shared per namespace.
Services that talk mTLS across clusters and clouds get SPIFFE identities from SPIRE, which attests both the node and the workload first. Both projects graduated from the CNCF in 2022. Entra can federate with SPIFFE identities.
IAM Roles Anywhere trades an X.509 certificate from your own CA for temporary AWS credentials. Entra federated identity credentials do the same thing for tokens from an outside issuer. No long-lived key either way.
Entra app registrations with client secrets. AWS access keys nobody uses. Google service account keys. We find them, match each to its workload, and retire them once federation is working.
Roles shaped from the API calls each workload actually makes in cloud audit logs, with permission boundaries or deny policies that stop privileges creeping back.
We pieced these together from Machine & Workload Identity situations that come up a lot. They're patterns. You won't find a specific client in them.
case file 01
GitHub Actions deploying to AWS with an admin access key per environment
composite · not a client story
Beforethe situation
Every repository keeps AWS access keys for dev, staging and prod as secrets. The prod key belongs to an IAM user with AdministratorAccess that someone created years ago. Any workflow on any branch can read it.
What we dothe work
Add GitHub as an IAM OIDC identity provider, then create one role per repository and environment whose trust policy matches the sub claim on both. Switch workflows to configure-aws-credentials with role-to-assume, check CloudTrail for the old key's last use, then deactivate it.
Afterwhere you end up
Production deploys get short-lived credentials only from the protected environment, the admin IAM user is gone, and a fork or feature branch can't assume the prod role.
case file 02
AKS pods sharing one service principal secret with subscription Contributor
composite · not a client story
Beforethe situation
Every pod in an AKS namespace mounts the same client secret from a Kubernetes secret. The service principal behind it has Contributor on the whole subscription, and rotation happens when someone remembers.
What we dothe work
Turn on the cluster's OIDC issuer and workload identity, create a user-assigned managed identity per workload with a federated credential bound to its Kubernetes service account, and grant each only the Key Vault or storage scope it uses. Delete the shared secret after the last pod moves.
Afterwhere you end up
Pods get tokens tied to their own service account, no client secret sits in the cluster, and the subscription-wide grant is gone.
case file 03
Data center servers uploading to S3 with a key in a config file
composite · not a client story
Beforethe situation
Linux servers in a colocation facility push files to S3 with an IAM user's access key sitting in a config file. Meanwhile the internal PKI already issues machine certificates to those same servers.
What we dothe work
Register the internal CA as an IAM Roles Anywhere trust anchor, create a profile and role scoped to the bucket prefix each server writes, and wire the credential helper into the SDK's credential process. Retire the IAM user once CloudTrail shows no further use.
Afterwhere you end up
The servers now get temporary AWS credentials based on their machine certificate. When one is decommissioned, you revoke the certificate. No one goes looking for an access key in a config file.
How a workload trades its own identity for a short-lived cloud token
Each CI job, pod and server gets a token or certificate saying what it is. It trades that for short-lived cloud credentials through a federated trust. Where workloads span clouds, SPIRE handles service-to-service mTLS.
We don't start a step until the last one has produced something you can check.
step 01
Inventory static credentials
Cloud access keys, client secrets and service account keys, each matched to the workload that uses it.
step 02
Pick a pattern per workload
Federation for CI and cloud-native workloads, SPIFFE for mesh traffic, and vault-issued credentials for the rest.
step 03
Migrate and verify
New trust configured, workload switched, old key disabled and watched before it's deleted.
step 04
Add guardrails
New long-lived keys are blocked by policy. If you need an exception, it's tracked and gets an end date.
you keep
What you're left with
We write these for your Machine & Workload Identity setup, and they're working documents. Your team should be able to keep things running from them long after we've gone.
Some clients want a project team, some want a couple of engineers on theirs. Either works. Onsite, nearshore or offshore, with handovers across time zones that keep things moving.
Onsite
Engineers at your sites in the US
Nearshore
Overlapping hours with US teams
Offshore
Overnight progress on your backlog
All time zones
Coverage handed over across time zones
24-hour coverage · US Central time
OnsiteUS business hours
Nearshoreoverlapping US hours
Offshoreovernight progress
Combinedhandover, not hand-off
00:0006:0012:0018:0000:00
certifications our engineers hold
Vault Associate (003)HashiCorp
roles we staff
Workload identity engineer
Kubernetes platform engineer
Vault engineer
Cloud IAM engineer
PKI engineer
due diligence · machine & workload identity
Questions to ask any partner, including us.
Put these to anyone bidding on your Machine & Workload Identity work. The ones who've done it answer differently from the ones who've read about it.
Q1
Which exact claims will our federated trust policies match on?
A trust scoped to an entire GitHub organization, or to a wildcard subject, lets any repository or branch assume the role. So ask to see each trust condition before it goes live.
Q2
How will you find which workload uses each static key before you disable it?
Keys get copied into scripts, pipelines and people's laptops. CloudTrail, Entra sign-in logs and Google Cloud audit logs show where each key is actually called from. That list decides the migration order.
Q3
Which workloads will stay on vaulted secrets, and why?
SaaS APIs and older databases often can't federate. A partner should name those and plan rotation for them instead of promising every credential disappears.
Q4
How will you stop new long-lived keys after the migration?
Leave out the guardrail and the next project creates an access key on day one. You can block or flag new keys with organization policies, SCPs or Azure Policy, and track the exceptions.
01Can we get rid of every static credential?
Not every one. Many SaaS APIs and older databases only accept API keys or passwords. Those move into a vault with rotation, which our secrets and certificate page covers. CI-to-cloud and cloud-to-cloud access can almost always use federation.
02Do we need SPIRE if we're on a single cloud?
Usually not. The cloud's own workload identity handles single-cloud estates well. SPIRE earns its operating cost when you need one identity scheme across several clouds, on-premises clusters, or a service mesh with mTLS everywhere.
03What breaks when we turn off an old access key?
Whatever still uses it, which is why we disable before we delete. We check cloud audit logs for the key's last use, disable it, wait through at least one full business cycle including month-end jobs, then delete it.
04How do we stop a pull request from a fork deploying to production?
With narrow trust conditions on the federated credential. Match the repository, the branch or environment, and ideally the workflow, rather than the organization alone. We review every trust policy for wildcards before go-live.
05How long does a move to workload identity federation take?
It depends on how many static credentials you have and how many workloads share each one. A single pipeline can move in a day. A key shared by many consumers takes longer, because every one has to switch before the key is disabled. We size it after the credential inventory.
related
Often paired with
Projects on Machine & Workload Identity usually end up touching one of these, so they're worth a look.