Cloud Security

Service Account Security: Managing Non-Human Identities in Cloud Environments

Non-human identities now outnumber human users 50:1. Learn how to secure service accounts, API keys, and machine identities across AWS, Azure, and GCP to prevent the most common cloud breaches.

By InventiveHQ Team

Service account security means eliminating long-lived static credentials in favor of short-lived, automatically-rotated tokens, scoping every non-human identity to least privilege, storing any remaining secrets in a dedicated vault, and monitoring machine identities for anomalous behavior. In practice that means preferring AWS IAM roles over access keys, Azure managed identities over service principals with client secrets, and GCP Workload Identity over downloaded JSON keys — because a static credential that never expires is the single most reusable thing an attacker can steal. Non-human identities (NHIs) now outnumber human users by roughly 50:1 in typical enterprises, yet they lack the MFA, password policies, and user training that protect human accounts.

That is the summary an AI Overview can give you. What it cannot show you is where the risk actually concentrates — that the danger is not the service account itself but the static, long-lived credential attached to it, and that every cloud provider now offers a keyless path that removes it. The diagram below traces a leaked key through to breach and shows where each control breaks the chain; a decision table maps each cloud to its keyless equivalent; and a symptom-cause-fix table turns the theory into a remediation checklist.

How a leaked static credential becomes a breach, and where controls break the chain A credential leaks from CI/CD or config, an attacker finds it, it never expires and is overprivileged, granting standing access. Keyless auth, least privilege, rotation, and monitoring each break a link. The static-credential kill chain A leaked long-lived key is standing, unmonitored access. Each control below severs one link. Key leaks CI/CD, image, config, chat log Never expires 2020 key still valid in 2026 Overprivileged broad perms from dev days No baseline machine use unmonitored Breach standing access attacker Keyless auth IAM roles / managed identity / federation breaks leak + expiry Least privilege scoped policies, JIT access breaks overprivilege Rotation + vault 90-day cap, no secrets in code breaks leak reuse Baseline + alert GuardDuty, Sentinel, Security Command Ctr breaks silent use
The kill chain is a leaked static key that never expires, is overprivileged, and goes unmonitored. Keyless authentication removes the first two links entirely; the rest are defense in depth.

The statistics are stark: surveys of cloud security teams consistently report that a large majority of organizations experienced a breach involving NHI compromise in the past year. Unlike human identities with MFA, password policies, and user training, non-human identities often have static credentials, excessive permissions, and indefinite lifespans.

This guide covers how to secure non-human identities across cloud environments, from basic hygiene to advanced workload identity federation.

The Non-Human Identity Problem

Scale and Complexity

A typical enterprise has:

  • Thousands of service accounts across cloud providers
  • Tens of thousands of API keys and access tokens
  • Secrets scattered across config files, environment variables, and vaults
  • Complex machine-to-machine authentication relationships

Why NHIs Are Targeted

Long-lived credentials. Unlike session tokens that expire, many API keys and service account passwords never expire. A key leaked in 2020 may still work in 2026.

Overprivileged by default. Service accounts often get broad permissions "to make things work" during development, then keep them in production.

Limited visibility. Organizations track human logins but often miss anomalous service account behavior. NHIs don't have managers to report suspicious activity.

Distributed everywhere. Secrets end up in CI/CD pipelines, container images, config files, developer laptops, and chat logs—any of which can leak.

Types of Non-Human Identities

Service Accounts (Cloud Provider)

Identity objects within cloud providers for machine-to-machine authentication:

ProviderService Account TypeKey Management
AWSIAM Users (legacy), IAM RolesAccess keys, STS tokens
AzureService Principals, Managed IdentitiesClient secrets, certificates
GCPService AccountsJSON keys, workload identity

API Keys

Long-lived tokens for API authentication:

  • Third-party SaaS API keys (Stripe, Twilio, Datadog)
  • Internal API authentication tokens
  • Webhook secrets

OAuth Applications

Applications that authenticate via OAuth/OIDC:

  • GitHub Apps
  • Slack integrations
  • Azure AD enterprise applications

Certificates and Secrets

  • TLS certificates for service authentication
  • Signing keys for tokens and artifacts
  • Encryption keys for data protection

Which Authentication Method Should I Use?

Every static credential you can delete is a breach you can't have. Use this table to pick the keyless equivalent for each workload before you ever generate a downloadable key.

Where the workload runsDo NOT use (static)Use instead (keyless)Token lifetimeWhen a static key is still justified
AWS EC2 / Lambda / ECS / EKSIAM user + access keyIAM role (instance/execution/task/pod role)~1 hour, auto-rotatedNever for AWS-native compute
Azure VM / Function / AKSService principal + client secretManaged identity (system- or user-assigned)Auto-rotated by platformLegacy apps that can't use MSI
GCP GCE / GKE / Cloud RunDownloaded JSON keyWorkload Identity / Workload Identity Federation~1 hourOnly when workload identity is impossible
GitHub Actions / GitLab CI → cloudLong-lived cloud secret in CIOIDC federation (assume role, no stored secret)~1 hourProviders without OIDC support
On-prem / other cloud → cloudCopied service account keyWorkload identity federation (external issuer)~1 hourAir-gapped systems with no OIDC issuer
Third-party SaaS (Stripe, Datadog)API key in env/configScoped key in a secrets vault + rotationVendor-dependentAlmost always — vault + rotate + scope it
Which should I use?Prefer the keyless column in every row; treat any static key as a temporary exception with a 90-day rotation and an owner.

Securing Cloud Service Accounts

Advertisement

AWS: IAM Roles Over Access Keys

Anti-pattern: Creating IAM users with long-lived access keys for applications.

Better: Use IAM Roles wherever possible:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

IAM Roles eliminate static credentials:

  • EC2 instances assume roles via instance metadata
  • Lambda functions have execution roles
  • ECS/EKS use task/pod roles
  • Credentials rotate automatically

When access keys are necessary:

  • Set maximum age (90 days recommended)
  • Automate rotation before expiration
  • Monitor for usage anomalies
  • Scope permissions minimally

Azure: Managed Identities First

Anti-pattern: Creating service principals with client secrets that never rotate.

Better: Use Managed Identities:

  • System-assigned: Tied to resource lifecycle, automatically deleted
  • User-assigned: Reusable across resources, independent lifecycle
# Enable system-assigned managed identity on a VM
az vm identity assign --name myVM --resource-group myRG

When service principals are necessary:

  • Use certificate authentication over client secrets
  • Set short credential expiration (6 months maximum)
  • Implement automated rotation
  • Apply conditional access policies

GCP: Workload Identity Federation

Anti-pattern: Downloading JSON service account keys for applications.

Better: Use Workload Identity:

  • GKE Workload Identity: Pods authenticate as GCP service accounts without keys
  • Workload Identity Federation: External workloads (AWS, Azure, GitHub) authenticate to GCP
# GKE Workload Identity annotation
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-service-account
  annotations:
    iam.gke.io/gcp-service-account: mysa@myproject.iam.gserviceaccount.com

When keys are necessary:

  • Download only when workload identity isn't possible
  • Rotate every 90 days
  • Store in Secret Manager, not code
  • Disable unused keys immediately

Secrets Management

Centralized Secrets Storage

Store all secrets in dedicated vaults:

Cloud-native options:

  • AWS Secrets Manager
  • Azure Key Vault
  • GCP Secret Manager
  • HashiCorp Vault (multi-cloud)

Benefits:

  • Centralized audit logging
  • Access control and policies
  • Automatic rotation support
  • Encryption at rest

Secret Rotation Strategies

Automatic rotation: Configure secrets managers to rotate credentials on schedule:

# AWS Secrets Manager rotation example
import boto3

def rotate_secret():
    client = boto3.client('secretsmanager')
    client.rotate_secret(
        SecretId='my-database-password',
        RotationLambdaARN='arn:aws:lambda:...',
        RotationRules={'AutomaticallyAfterDays': 30}
    )

Dual-token rotation: For zero-downtime rotation:

  1. Create new credential (both old and new work)
  2. Update applications to use new credential
  3. Verify new credential works
  4. Delete old credential

Secret Scanning

Prevent secrets from leaking to code repositories:

Pre-commit scanning:

  • Gitleaks
  • TruffleHog
  • detect-secrets

Repository scanning:

  • GitHub secret scanning (automatic for public repos)
  • GitLab secret detection
  • Snyk Code

CI/CD scanning:

  • Scan environment variables
  • Check container images for embedded secrets
  • Audit deployment configurations

Least Privilege for NHIs

Permission Analysis

Regularly audit NHI permissions:

AWS IAM Access Analyzer:

aws accessanalyzer create-analyzer \
  --analyzer-name my-analyzer \
  --type ACCOUNT

Azure AD Access Reviews:

  • Review service principal permissions
  • Identify unused permissions
  • Recommend permission reduction

GCP IAM Recommender:

  • Suggests permission reduction based on usage
  • Identifies unused service accounts
  • Recommends role downgrades

Just-In-Time Access

Implement dynamic credential provisioning:

  • HashiCorp Vault dynamic secrets
  • AWS STS temporary credentials
  • Azure Managed Identity tokens
  • GCP service account impersonation

Scope Limiting

Resource-based policies: Limit which resources NHIs can access:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/specific-prefix/*"
    }
  ]
}

Conditional access: Require specific conditions:

  • Source IP ranges
  • Time-based access
  • Resource tags
  • Authentication method

Monitoring and Detection

Baseline Behavior

Establish normal patterns for NHI activity:

  • Typical API call patterns
  • Source IP addresses
  • Access times
  • Target resources

Anomaly Detection

Alert on deviations from baseline:

AWS CloudTrail + GuardDuty:

  • Unusual API calls from service accounts
  • Access from unexpected locations
  • Credential usage after deletion

Azure Sentinel:

  • Service principal anomalous sign-ins
  • Unusual application consent grants
  • Risky workload identities

GCP Security Command Center:

  • Anomalous service account usage
  • Key exposure notifications
  • Unusual resource access

Key Metrics to Track

MetricTargetAlert Threshold
Unused service accounts0>30 days inactive
Keys older than 90 days0Any non-rotated key
Overprivileged accounts<5%>20% with admin
Secrets in code0Any detection

Symptom → Cause → Fix

When an NHI review turns up a red flag, map it to the underlying cause and the concrete remediation instead of reaching for a one-off patch.

Symptom you observeLikely root causeFix
Access key older than 90 days still in useNo rotation automation; app hardcodes the keyMigrate to IAM role / managed identity; if impossible, wire up Secrets Manager rotation and update the consumer
Service account with *:* or admin on everythingBroad perms granted "to make it work" in dev, never trimmedRun IAM Access Analyzer / GCP IAM Recommender, right-size to least privilege, add resource + condition constraints
Credential still working after the account was "deleted"Static key was distributed and cached by consumersRotate the key at the source, invalidate copies, switch to short-lived tokens so deletion actually revokes access
Secret found in a Git repo or container imageNo pre-commit scanning; secret pasted into codeRotate the exposed secret immediately, add Gitleaks/TruffleHog pre-commit hooks, enable repo secret scanning
Service account calling APIs from an unexpected regionCredential theft, or a legitimate but undocumented workloadAlert via GuardDuty/Sentinel/SCC, confirm ownership, revoke and rotate if unowned
Orphaned NHI with no owner listedCreator left; no lifecycle process at creation timeAssign an accountable owner or decommission (disable, verify no breakage, then delete)
CI pipeline holds a long-lived cloud secretPipeline predates OIDC federationReplace the stored secret with OIDC role assumption so nothing long-lived is stored

Governance and Lifecycle

Inventory Management

Maintain comprehensive NHI inventory:

  • Owner/team assignment for each NHI
  • Business justification
  • Expiration/review dates
  • Dependency mapping

Lifecycle Processes

Creation:

  1. Business justification required
  2. Security review for high-privilege accounts
  3. Least-privilege permissions assigned
  4. Expiration date set

Review:

  1. Quarterly access reviews
  2. Permission right-sizing
  3. Usage verification
  4. Owner confirmation

Decommissioning:

  1. Identify dependencies
  2. Rotate consuming applications
  3. Disable (don't delete immediately)
  4. Delete after verification period

Ownership Model

Every NHI needs an accountable human:

  • Application owners for app service accounts
  • Platform teams for infrastructure credentials
  • Security team for break-glass accounts
  • Clear escalation for orphaned identities

Workload Identity Federation

The Future: Keyless Authentication

Workload identity federation eliminates long-lived credentials by federating trust between identity providers.

GitHub Actions to AWS:

- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::ACCOUNT:role/GitHubActionsRole
    aws-region: us-east-1

Azure to GCP:

gcloud iam workload-identity-pools create azure-pool \
  --location="global"

gcloud iam workload-identity-pools providers create-oidc azure \
  --workload-identity-pool="azure-pool" \
  --issuer-uri="https://sts.windows.net/TENANT_ID/"

Benefits of Federation

  • No static credentials to leak
  • Short-lived tokens (typically 1 hour)
  • Leverages existing identity infrastructure
  • Auditable through identity provider logs

Implementation Roadmap

  1. Inventory current NHIs and their authentication methods
  2. Prioritize high-privilege accounts for migration
  3. Implement federation for CI/CD pipelines
  4. Migrate workloads to managed/workload identity
  5. Eliminate static credentials where possible
  6. Monitor for credential usage patterns

Frequently Asked Questions

How do we find all our non-human identities?

Start with cloud provider IAM inventories (AWS IAM, Azure AD, GCP IAM). Add secrets manager contents, CI/CD configuration, and Kubernetes secrets. Use CSPM tools for comprehensive discovery. The initial inventory is always incomplete—plan for ongoing discovery.

Should service accounts have MFA?

Traditional MFA doesn't apply to NHIs since there's no human to provide the second factor. Instead, use: short-lived credentials, workload identity federation, certificate-based authentication, and conditional access based on source network/identity.

How do we handle break-glass service accounts?

Keep privileged accounts for emergency access but: store credentials in secure vault with break-glass procedures, require approval workflow for access, alert on any usage, rotate after each use, review necessity periodically.

What's the difference between service accounts and service principals?

Terminology varies by provider. AWS IAM users/roles, Azure service principals, and GCP service accounts serve similar purposes—providing identity for machines and applications. Managed identities (Azure) and IAM roles (AWS) are preferred over traditional service accounts.

How do we secure secrets in CI/CD pipelines?

Use native secrets management: GitHub Secrets, GitLab CI variables, Azure DevOps secret variables. Better: use OIDC federation to assume cloud roles without static secrets. Scan pipelines for accidental secret exposure.

Conclusion

Non-human identity security is arguably more critical than human identity security today. These identities have privileged access, never sleep, and don't respond to phishing training. Yet most organizations invest far more in human IAM than NHI security.

Start by gaining visibility into your NHI inventory. Migrate to dynamic, short-lived credentials wherever possible. Implement secrets management and rotation. Apply least privilege consistently. Monitor for anomalous behavior.

The ultimate goal is keyless—authentication via workload identity federation that eliminates static credentials entirely. This journey takes time, but every step reduces your attack surface significantly.


Part of the 30 Cloud Security Tips for 2026 series.

Frequently Asked Questions

What is a non-human identity (NHI)?

A non-human identity is any credential or identity object used by software rather than a person: cloud service accounts, IAM roles, API keys, OAuth client secrets, TLS certificates, and machine tokens. NHIs authenticate machine-to-machine, so they have no human to complete MFA, notice a phishing attempt, or report suspicious activity. In most enterprises they outnumber human accounts by 50:1 or more.

What is the difference between a service account and a service principal?

The terms are provider-specific for the same concept. AWS uses IAM users (legacy) and IAM roles; Azure uses service principals and managed identities; GCP uses service accounts. All provide a machine identity for authentication and authorization. The modern, key-free variants — AWS IAM roles, Azure managed identities, and GCP Workload Identity — are preferred over anything that issues a static, downloadable credential.

Should service accounts use MFA?

Traditional MFA does not apply because there is no human present to supply a second factor. The equivalent controls for NHIs are short-lived, auto-rotating credentials, workload identity federation instead of static keys, certificate-based authentication, and conditional access that scopes use by source network, resource tag, or time window.

How long should a service account access key live before rotation?

If you must use a static key at all, cap its age at 90 days and automate rotation before expiry — AWS access keys, GCP JSON keys. For Azure client secrets, use six months maximum and prefer certificates. The better answer is to eliminate static keys entirely with IAM roles, managed identities, or workload identity federation, which issue tokens that expire in about an hour and rotate automatically.

What is workload identity federation?

Workload identity federation lets a workload authenticate to a cloud provider using its existing identity from a trusted issuer — a GitHub Actions OIDC token, a Kubernetes service account, or another cloud's identity — instead of a stored secret. The provider exchanges the verified external token for a short-lived credential (typically one hour). Nothing long-lived is stored, so there is no key to leak.

How do we find all of our service accounts and API keys?

Start with each cloud provider's IAM inventory (AWS IAM, Azure Entra ID, GCP IAM), then add secrets manager contents, CI/CD pipeline variables, and Kubernetes secrets. Use a CSPM or dedicated NHI-discovery tool for cross-account coverage. Treat the first inventory as incomplete — new identities are created continuously, so discovery must be ongoing, not a one-time project.

Where should secrets be stored instead of in code?

Store secrets in a dedicated vault — AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, or HashiCorp Vault for multi-cloud — which gives you centralized audit logging, access policies, encryption at rest, and automatic rotation. Keep secrets out of source control with pre-commit scanners such as Gitleaks, TruffleHog, or detect-secrets, and enable repository-side secret scanning as a backstop.

How do we secure secrets in CI/CD pipelines?

Prefer OIDC federation so the pipeline assumes a cloud role with no stored secret at all — for example GitHub Actions assuming an AWS IAM role. Where a secret is unavoidable, use the platform's native store (GitHub Secrets, GitLab CI variables, Azure DevOps secret variables), scope it to a single environment, and scan pipeline logs and container images for accidental exposure.

What is a break-glass service account and how do you protect it?

A break-glass account is a highly privileged identity reserved for emergencies when normal automation fails. Protect it by storing the credential in a vault behind a documented break-glass procedure, requiring an approval workflow to retrieve it, alerting on any use, rotating it immediately after each use, and reviewing whether it is still needed on a set schedule.

Why are non-human identities the primary cloud attack vector?

NHIs combine broad privilege with weak lifecycle hygiene. Their credentials are often long-lived or never expire, they are overprivileged because permissions were widened during development and never trimmed, their activity is rarely baselined, and their secrets end up scattered across pipelines, images, config files, and chat logs. Any one leaked secret can grant standing, unmonitored access.

Service AccountsNon-Human IdentitiesCloud SecuritySecrets ManagementMachine Identity