Non-human identities and cloud roles
On this page
Many alerts name no person at all. They name a role session, a service principal, a pipeline token or an agent. These identities skip MFA, hold standing privilege, and behave the same way every day, which makes them easy to abuse and, once you know where to look, cheap to check.
Entity types gave the first pass on applications and services. This page goes deeper on the identities behind them. In many cloud tenants, non-human identities Non-Human Identity (NHI) An identity used by software rather than a person: service accounts, cloud roles and workload identities, API keys, OAuth applications, CI/CD tokens, AI agents. Non-human identities often outnumber people, hold standing privilege, skip MFA, and behave predictably, so one doing something interactive or new is a strong Subject signal. They are subjects in their own right. See Non-human identities and cloud roles. outnumber the people, and the depth ladder already depends on telling them apart: the Level 0 eligibility gate fails any automation with deploy, signing, secrets or repository-write capability, because a CI runner can outrank its owner. To apply that gate, and to run the four dimensions on a subject that never types a password, you need four answers: what kind of identity this is, who can become it, who is behind this session, and what its normal looks like.
What counts as a non-human identity
An identity used by software rather than a person. The table lists the kinds triage meets most, how each one authenticates, and where its activity is recorded. Credentials (API keys, client secrets, certificates, access keys) are not identities of their own: each belongs to one of the rows below, and you analyze it as that identity’s credential.
| Type | What it is | How it authenticates | Where to read it |
|---|---|---|---|
| Service accounts Service Account An account used by an application or service rather than a person, usually with a long-lived password or key and standing permissions. Its behavior is predictable by design, so an interactive logon, a new source host, or a new kind of action from a service account is a high-confidence anomaly. Service accounts with SPNs are the targets of Kerberoasting. See Non-Human Identity (NHI). | A directory or cloud account run by software: an AD service account, a GCP service account, an AWS IAM user created for a tool. | Long-lived password or key. | Directory logon events; CloudTrail userIdentity.type IAMUser; GCP authenticationInfo. |
| Cloud roles and assumed-role sessions Assumed-Role Session In AWS, the temporary STS credentials issued when a principal assumes a role. Using one session to assume another role is role chaining, which caps the session at one hour. Trace the chain back through CloudTrail to the original principal. See Non-human identities and cloud roles. | An AWS IAM role, an Azure managed identity Managed Identity In Azure, an Entra service principal whose credentials the platform manages for an Azure resource, so no secret is stored. Its sign-ins go to the AADManagedIdentitySignInLogs table. See Non-human identities and cloud roles. , or a GCP service account that others impersonate. The role holds permissions; a session borrows them for a while. | Short-lived credentials from a token service (AWS keys starting ASIA). | CloudTrail AssumedRole events; Entra managed identity sign-in log; GCP serviceAccountDelegationInfo. |
| Workload identity federation Workload Identity Federation An external workload (a CI job, a Kubernetes pod, another cloud) exchanges its own signed OIDC token for short-lived cloud credentials, accepted only if it matches the role's trust conditions. No stored secret exists, so the trust conditions are what an attacker targets. See Non-human identities and cloud roles. | A workload outside the cloud (a GitHub Actions job, a Kubernetes pod, another cloud) trades its own signed OIDC token for cloud credentials. No stored secret exists. | The external token, accepted only if it matches the role’s trust conditions. | CloudTrail AssumeRoleWithWebIdentity; the Entra app’s federated credentials; GCP workload identity pool. |
| OAuth and consented apps | An app registration and its service principal Service Principal In Microsoft Entra ID, the tenant-local identity of an application. It signs in with a client secret, a certificate or a federated credential and holds delegated or application permissions; disabling it blocks the app's sign-in. See Non-human identities and cloud roles. (Entra ID), or a third-party app granted access to a tenant’s data. Delegated permissions act as a user; application permissions act as the app itself. | Client secret, certificate, or federated credential; refresh tokens for delegated access. | Entra service principal sign-in log and AuditLogs; Google Workspace token audit. |
| CI/CD tokens | Personal access tokens Personal Access Token (PAT) A long-lived bearer token issued to a user or bot account in a source-control or SaaS platform, often broadly scoped and rarely rotated. A password reset does not revoke it. See Non-human identities and cloud roles. , deploy keys, runner registration tokens, the job’s built-in token, and the cloud keys stored as pipeline secrets. | Bearer token or key, often long-lived and broadly scoped. | The source-control audit log; the cloud log of whatever the token reached. |
| Kubernetes service accounts | The identity a pod runs as. Current clusters issue short-lived tokens bound to the pod. | Projected token mounted in the pod. | API server audit log, where the user reads system:serviceaccount:NAMESPACE:NAME. |
| AI agents and MCP servers | An agent AI Agent An AI system, usually built on a large language model, that plans and takes multi-step actions through tools: running queries, reading mailboxes, calling APIs, executing commands. In triage it is both a helper and a subject. As a helper, its tool access makes it attack surface, since text it reads can carry instructions (prompt injection, in the B.A.D. glossary). As a subject, an agent with delegated access is a non-human identity whose actions need the same Subject analysis as any service account. See AI-assisted triage. See Governing automated triage. with an identity of its own (Microsoft Entra Agent ID records owners and sponsors for each), or with tokens delegated by a user; an MCP Model Context Protocol (MCP) An open protocol for connecting AI assistants and agents to tools and data sources through MCP servers. Each server describes its tools to the model and runs as code the host trusts, so a tampered tool description or an over-scoped token becomes the assistant's problem. Inventory MCP servers like extensions; a signed host does not vouch for them. See AI-assisted triage. server holding tokens for the downstream APIs it calls. | Delegated user token, app-only token, or the MCP server’s own credentials. | Agent sign-ins in the Entra sign-in logs; the agent’s tool-call logs; the MCP gateway’s logs. See AI agents as subjects. |
For the Subject handoff, a role, service principal or service account goes in the entity inventory as a service account row, its session or token as a session or token row, and a consented app as an application or OAuth grant row (the handoff schema).
Who can become this identity
For a person, the Authentication dimension asks whether the right human proved who they are. For a non-human identity the question moves one step back: who is allowed to obtain its credentials at all? That list is the identity’s real attack surface, and it is usually longer than its owner thinks.
- AWS roles. The role’s trust policy Trust Policy In AWS, the resource-based policy on a role that names who may assume it and under which conditions. A role that trusts a whole account trusts every principal in it allowed to assume roles. See Non-human identities and cloud roles. names the principals that may call
sts:AssumeRole, plus any conditions. A role that trusts a whole account trusts every principal in it that has permission to assume it. For GitHub Actions federation, the condition ontoken.actions.githubusercontent.com:subis the control: without it, a workflow in any repository can obtain the role’s credentials. - GCP service accounts. Anyone holding Service Account Token Creator on the account can mint tokens for it; Service Account User lets a principal attach it to a workload they control; Service Account Key Admin can create a key that never expires by default.
- Entra apps and service principals. The app’s owners, and anyone holding Application Administrator or Cloud Application Administrator, can add a secret or certificate and then sign in as the app with every permission it holds. A federated identity credential Federated Identity Credential In Microsoft Entra ID, a standing trust on an app registration or managed identity that lets tokens from an external issuer sign in as the app. Adding one is a persistence move worth an alert. See Non-human identities and cloud roles. on the app is a standing trust to an external issuer.
- Kubernetes. Anyone who can create a pod in the namespace can run it as that namespace’s service accounts, unless an admission policy restricts which accounts pods may use.
- CI/CD. Anyone who can change the pipeline definition, or merge to a branch the pipeline trusts, controls what the pipeline’s identity does next.
These are the trust edges the Relationships dimension maps. When an attack-path tool already holds the graph, query the identity’s inbound edges before building anything by hand.
Answering “who is behind this”
A non-human subject still has people behind it. Four facts answer most of the question, and each one is a field in an inventory, not a judgment:
Owner of record
The team or person accountable for it, from the CMDB, the app registration’s owners, or a resource tag. No owner on record is an orphaned Orphaned Credentials Accounts, keys or tokens that outlived their owner or purpose: a leaver's account never disabled, a key for a retired app, an OAuth grant nobody remembers. Attackers prize them because nobody notices their use. Activity from an account whose owner has left, or from a credential with no owner in the inventory, deserves a Subject review. identity: record it as a gap, and it fails the eligibility gate.
Creator and creation date
Who created it, through which pipeline or change, and when. A creation date inside the alert window is a lead: an identity born during the intrusion has no history to flag it.
Last rotation and last use
Credential age and last-used date (AWS access key last used, Entra credential start and end dates, GCP Activity Analyzer). The last rotation is the last known-good point, so it anchors the lookback window.
Permitted scopes
What it may do and on which resources: its policies, Graph permissions, OAuth scopes or repository rights. Deploy, signing, secrets or repository write makes it a privileged identity for the depth ladder.
Those facts describe the identity. The alert is about one session, and the session has to be traced back to whatever started it. The logs that do this differ by platform:
| Platform | Start here | What names the human or pipeline behind it |
|---|---|---|
| AWS | userIdentity.type: AssumedRole for a role session, IAMUser for a long-term key, AWSService when a service acted. | sessionContext.sourceIdentity if your organization enforces it; otherwise join back through each AssumeRole call on the temporary accessKeyId. The role session name is caller-chosen and never proof. Chained role sessions are capped at one hour. For Lambda and ECS, inScopeOf.credentialsIssuedTo names the resource the credentials were issued to. |
| AWS federation | The AssumeRoleWithWebIdentity event, where userIdentity.type is WebIdentityUser. | userName carries the token’s subject, for GitHub Actions repo:ORG/REPO:ref:refs/heads/BRANCH. A repository outside your organization here means the trust policy is too wide. |
| Microsoft Entra ID | AADServicePrincipalSignInLogs and AADManagedIdentitySignInLogs (service principals do not appear in the user sign-in tables). | ServicePrincipalCredentialKeyId, ServicePrincipalCredentialThumbprint or FederatedCredentialId name which credential signed in. Match it to the app’s credential list and to the AuditLogs event that added it, whose InitiatedBy names the person or app. |
| Google Cloud | authenticationInfo.principalEmail names the service account. | serviceAccountDelegationInfo names the principal impersonating it; serviceAccountKeyName names the key; GenerateAccessToken records who minted a short-lived token, but only with IAM Data Access audit logs enabled. |
| Kubernetes | The API server audit log entry for the call. | The pod the token is bound to, then whoever created or changed that pod’s workload. |
Repeat the hop until the chain ends at a human, a workload, or a long-term key. When it ends at a key, the question becomes who holds the key: where it is stored (a vault, a pipeline secret, a developer’s laptop) and who can read that store. Note the confidence of every hop, as with any identifier-to-identity pivot. The field-level walk through a CloudTrail role chain, with the join keys, is in Cloud and identity logs.
Baselines for automation
Automation does the same thing every day. That makes its baseline narrow, and a narrow baseline makes deviation cheap to see: a service account Service Account An account used by an application or service rather than a person, usually with a long-lived password or key and standing permissions. Its behavior is predictable by design, so an interactive logon, a new source host, or a new kind of action from a service account is a high-confidence anomaly. Service accounts with SPNs are the targets of Kerberoasting. See Non-Human Identity (NHI). touching a database it has never touched is a louder signal than the same access from a person. Baseline five things:
- Source: the runner, subnet, VPC endpoint or egress IP it always acts from.
- Client: the SDK or tool in the user agent, corroborating only, since the caller sets it.
- Action set: the API calls it makes. Pipelines rarely enumerate, so a burst of list and describe calls is new behavior.
- Targets: the buckets, mailboxes, repositories and regions it touches.
- Cadence: its schedule and volume, often a fixed interval.
The peers of a non-human identity are the other instances of the same thing: jobs from the same pipeline, pods from the same image, functions that run as the same role (see choosing peer groups).
The deviations worth stopping for:
- Human use. Interactive sign-in, console use, or a call from a laptop IP. Even when a known engineer did it, that is at least a policy violation, and the IAM mini-example shows why it still needs a full read.
- Off-box use. Workload credentials used from somewhere other than the workload (the IMDS pattern).
- A first use of a new credential. Especially a new credential on an identity that has used one credential for years.
- Waking after dormancy. First use after months of silence, from a new source.
- New scope in use. A permission the identity holds but has never exercised.
Two cautions. Deploys legitimately change behavior, so before a deviation is cleared, match it to the change ticket or pipeline run that explains it, and check that the run itself is the expected one. And a compromise older than the baseline window is part of the baseline: static, rarely rotated credentials are where long-dwell access hides (when the baseline lies). A newly created identity has no baseline at all; treat that as unknown, not normal (cold start).
Federation and token abuse signals
Attackers favor non-human identities for persistence because a password reset on a person does not touch them. These are the patterns that recur, with the events that show them. The user-side identity attacks (consent phishing, AiTM, device code, Golden SAML) are on the four dimensions page, and their protocol depth is in Cloud and identity logs.
| Pattern | What it looks like in the logs | ATT&CK |
|---|---|---|
| Credential added to an existing identity | Entra AuditLogs “Update application - Certificates and secrets management” or “Add service principal credentials”; AWS CreateAccessKey; GCP CreateServiceAccountKey. Then a sign-in that uses the new key ID from a new source. | T1098.001 |
| Permissions granted to an app or role | Entra “Add app role assignment to service principal” (an application permission such as full_access_as_app, which reads every mailbox); AWS AttachRolePolicy or PutRolePolicy; GCP SetIamPolicy on a project. | T1098.003 |
| Trust widened | AWS UpdateAssumeRolePolicy; a federated identity credential added to an Entra app; an AssumeRoleWithWebIdentity whose subject is a repository you do not own. | T1098 |
| New identity created | AWS CreateUser or CreateRole, Entra “Add service principal”, GCP CreateServiceAccount, with no matching change or pipeline run. | T1136.003 |
| Workload credentials replayed | A role’s temporary credentials used off-box; a stolen app token replayed from a new ASN. | T1552.005 then T1078.004; T1550.001 for app tokens |
| Leaked secrets | A secret-scanning alert, a key in a public repository or build log, then first use from an unfamiliar source. | T1552.001 |
| Third-party integration tokens | A vendor’s OAuth or API token used to bulk-export data from your tenant: no user password or MFA involved. | T1528, T1550.001 |
| Agent misuse | An agent calling tools or reading data outside its baseline after reading attacker-written content. Its token is legitimate. | See AI agents as subjects |
Three real cases show the shapes. In the Midnight Blizzard intrusion (disclosed January 2024), the actor took over a legacy test OAuth app with elevated access, created more OAuth apps, and used the test app to grant the full_access_as_app role in Exchange Online. In March 2025 the compromised tj-actions/changed-files GitHub Action printed CI runner secrets into workflow logs, public by default for public repositories; CISA’s guidance was to treat every exposed secret as compromised and rotate it. And in August 2025, OAuth tokens stolen from the Salesloft Drift integration Salesloft Drift OAuth-token theft August 2025. An actor tracked by Google as UNC6395 used OAuth tokens stolen from the Salesloft Drift chat integration to export data from hundreds of customers' Salesforce instances, then searched the data for secrets such as cloud access keys and passwords. No victim password or MFA was involved: the trusted SaaS-to-SaaS integration was the way in. were used to export data from hundreds of Salesforce instances, then mined for cloud keys.
The MCP specification forbids token passthrough, an MCP server forwarding a client’s token to a downstream API, partly because the downstream logs then show the wrong identity. When an agent’s actions appear in a downstream audit log, check whether the identity recorded there is the agent, the MCP server, or the user, before you attribute anything.
Example: a new secret on a mail-reading app
A Sentinel rule fires: a credential was added to invoice-sync, a finance integration with the application permission Mail.Read on every mailbox. The initiator is admin-jdoe, who holds Cloud Application Administrator.
Who is behind the identity. Owner of record: the finance-integrations team. Created in 2023 through the change process. One certificate, renewed in March, is its only credential. Scope: read any mailbox in the tenant, which makes it a privileged identity for the gate.
Baseline. Every 15 minutes, a certificate sign-in from the integration server’s fixed egress IP, to Exchange Online only.
The session. Thirty-eight minutes after the change, AADServicePrincipalSignInLogs shows invoice-sync signing in with a ServicePrincipalCredentialKeyId that matches the new secret, from a hosting-provider ASN. Credential, source and cadence all break the baseline at once.
Who is behind the change. Following InitiatedBy back: admin-jdoe signed in interactively from a new device twelve minutes before the change, shortly after a help-desk reset of the account’s MFA. The owner team confirms no rotation was planned, and there is no change ticket. The benign explanations were checked and failed.
What follows. An attacker-added credential, used from attacker infrastructure, on an identity that can read every mailbox: confirmed malicious activity at High confidence, not contained by any control. The escalation tripwire fires from Subject; the case is P1. Before containment, export the app’s credential list, its permissions, the audit events and the sign-ins. Disabling the service principal’s sign-in is reversible and stops new tokens for every credential the app holds (tokens already issued run until they expire), but it also stops invoice processing, so the owner is told. Removing the secret and resetting admin-jdoe wait for IR. The admin account goes on the entity map as the upstream subject.
What it means for depth and containment
- Depth. A non-human identity with deploy, signing, secrets or repository-write capability, or broad data access, is a privileged identity: it fails the Level 0 eligibility gate and routes the case to Level 2, whatever the activity looks like. Unknown fails the gate too, and for non-human identities unknown is common, because ownership records are thin. Record which fact was missing.
- Escalation. An attacker-controlled credential on a working identity is ongoing access. Confirmed at High confidence, it is malicious activity not fully contained by a control, and the E rule makes it P1 from any phase.
- Containment. Preserve first: snapshot the credential list, trust policy, grants and recent sign-ins before anything changes. Reversible actions, such as disabling a service principal’s sign-in or deactivating an access key, can be pre-authorized. Deleting a key, removing a grant, or rotating a secret that production consumes cannot be undone and needs IR or owner approval. Every action on a pipeline identity can break production, so check its dependents first (containment and the entity scope).
Where this maps
The page covers the OWASP Non-Human Identities Top 10 (2025) from the triage side. Owner, creator and last use address NHI1 (Improper Offboarding). The abuse signals cover NHI2 (Secret Leakage), NHI3 (Vulnerable Third-Party NHI) and NHI7 (Long-Lived Secrets). Who can become the identity addresses NHI4 (Insecure Authentication) and NHI6 (Insecure Cloud Deployment Configurations), including over-broad federation trust. Permitted scopes address NHI5 (Overprivileged NHI). Baselines and peers catch NHI9 (NHI Reuse) and NHI10 (Human Use of NHI).
Sources and further reading
- OWASP, Non-Human Identities Top 10, 2025 (checked October 2026).
- AWS, CloudTrail userIdentity element, including source identity and web identity federation, and IAM roles: terms and concepts, including role chaining and trust policies (both checked October 2026).
- Microsoft Learn, AADServicePrincipalSignInLogs table reference (updated August 2026), Microsoft Entra audit log activities, and Microsoft Entra Agent ID logs (checked October 2026).
- Google Cloud, Examples of audit logs for service accounts and View recent usage for service accounts and keys (both checked October 2026).
- GitHub Docs, OpenID Connect reference, and Datadog Security Labs, No keys attached: exploring GitHub-to-AWS keyless authentication flaws (July 2023, updated June 2025).
- Kubernetes, Authenticating: service account tokens (checked October 2026).
- Model Context Protocol, Security best practices, token passthrough (specification version 2025-11-25).
- MITRE ATT&CK, T1098.001 Account Manipulation: Additional Cloud Credentials.
- Microsoft Threat Intelligence, Midnight Blizzard: guidance for responders on nation-state attack (25 January 2024).
- CISA, Supply chain compromise of third-party tj-actions/changed-files (CVE-2025-30066) (18 March 2025).
Key takeaway
A non-human identity is a subject in its own right. Ask who can become it, then trace the session back through the role chain, the credential that signed in, or the impersonating principal until you reach a person, a workload or a key. Its baseline is narrow, so human use, off-box use, a new credential or a new scope in use is a strong lead. Any one with deploy, signing, secrets, repository-write or broad data access is privileged: it never closes at Level 0.
Next up
Behavioral framework
Pattern recognition, baseline development, anomaly detection. The toolkit for separating normal from suspicious at the Subject level.
Read behavioral frameworkTechnical details verified . Product names, defaults and retention change; check your own tenant.