When the same service account, API key or cloud role works in both a test environment and production, an attacker who gets into the weaker environment inherits a path into the stronger one. OWASP lists this as NHI8:2025 Environment Isolation in the Non-Human Identities Top 10. This guide explains what the risk covers, how OWASP rates it, what isolation means for each kind of non-human identity, and how to find and remove cross-environment identities without breaking deployments. It is written for cloud platform engineers, IAM and NHI programme owners, and the auditors who have to evidence that production is really separate.
Key takeaways
- NHI8 is about identities, not networks. Separate VPCs or clusters do not help if one credential is trusted on both sides of the boundary.
- OWASP rates it uncommon but hard to detect. Exploitability is Average, prevalence Uncommon, detectability Hard and technical impact Moderate, because the exposed identity by definition reaches production.
- The account, subscription or project is the real boundary. AWS describes the account as an identity and access management isolation boundary, and Microsoft recommends one subscription per application environment.
- Pipelines are the usual bridge. A single deploy identity used for every stage is the most common NHI8 pattern; scope federated trust to a named environment instead.
- Prevent with guardrails, detect with inventory. Organisation-level deny policies stop new cross-environment grants; an inventory tagged by environment finds the ones that already exist.
What it is and who it applies to
The OWASP Non-Human Identities Top 10 2025 was published in December 2024 (the NHI8 page went up on 20 December and the project went live on 24 December). NHI8 describes the reuse of the same NHIs across multiple environments, with test and production as the case OWASP singles out. OWASP's reasoning is simple: development, test and staging environments usually have weaker controls, more people with access and less monitoring than production. If an NHI that lives in one of those environments also holds permissions on production resources, compromising the test environment is enough.
The risk applies to any organisation that runs more than one lifecycle environment and uses machine credentials to deploy or operate software. In practice that means:
- Cloud platform teams: AWS accounts, Azure subscriptions and Google Cloud projects where roles, managed identities or service accounts are granted access across the prod and non-prod split.
- DevOps and CI/CD owners: deploy identities, runner credentials and OIDC trust policies shared by every pipeline stage.
- Application teams: API keys for third-party services (payments, email, messaging, AI) copied from the production configuration into test.
- SaaS and identity administrators: test tenants, sandboxes and OAuth applications that have been granted rights in the production tenant.
NHI8 overlaps with two neighbouring risks. NHI9 NHI Reuse covers one identity shared between different workloads; NHI8 is the special case where the sharing crosses an environment boundary. NHI5 Overprivileged NHI decides how bad the outcome is. See the OWASP NHI Top 10 NHI9 NHI Reuse Guide and the OWASP NHI Top 10 NHI5 Overprivileged NHI Guide.
Structure and key requirements
Each OWASP NHI Top 10 entry follows the same structure: a rating table (threat agents, security weakness, impacts), a description, example attack scenarios, "How To Prevent", references and data points. The ratings use the OWASP Risk Rating Methodology on a three-point scale and assume a worst-case impact and an organisation that is already exposed.
| Factor | NHI8 rating | OWASP's reasoning (paraphrased) |
|---|---|---|
| Exploitability | Average | The attacker must first get into the test environment, but test environments tend to have far fewer protections. |
| Prevalence | Uncommon | NHIs are not commonly reused between non-prod and prod. |
| Detectability | Hard | Many workload and environment combinations can use the same NHI, so spotting the shared one is difficult. |
| Technical impact | Moderate | Depends on the NHI's privilege, but the identity is by nature in production, so impact is non-negligible. |
| Business impact | Specific | Varies with the data and services the production side exposes. |
OWASP's "How To Prevent" section has four requirements, which this guide uses as the backbone:
- Strict environment isolation for NHIs: unique NHIs for development, testing, staging and production, so a credential from one cannot be used in another.
- Principle of least privilege: each NHI gets only the permissions it needs inside its own environment.
- Environment-specific access controls: policies that stop non-production NHIs from interacting with production resources.
- Segregated infrastructure: separate resource groups, subscriptions or accounts so that a compromise is contained to one environment.
The two OWASP scenarios are an AWS access key used by test and production to reach S3 buckets, where the test copy can read real customer data, and an Azure managed identity holding role assignments in both a test and a production subscription. The data point attached to the entry is the Cloud Security Alliance finding that configuration errors caused 32% of NHI-related incidents.
Identity and NHI requirements
Isolation looks different for each identity type. The table below translates the OWASP requirements into concrete controls on the main platforms.
| Identity type | Typical NHI8 pattern | Isolation control |
|---|---|---|
| AWS IAM roles and access keys | One role or IAM user key used by test and prod; a role in a dev account trusted by a prod role | Separate accounts per environment under a Workloads OU split by stage; SCPs and resource control policies on the prod OU that block access by principals from outside it; IAM Access Analyzer external access findings to list cross-account trust |
| Azure managed identities and service principals | A user-assigned managed identity attached to resources in a test and a prod subscription, or a pipeline service principal with Contributor on both | One subscription per environment; a separate user-assigned identity per environment; pipeline service connections scoped to one subscription; Azure Policy at the management group to audit role assignments whose principal is tagged for another environment |
| Google Cloud service accounts | A service account in a dev project granted roles in a prod project, or impersonation across projects | Separate projects (ideally folders) per environment; the "Disable Automatic IAM Grants for Default Service Accounts" constraint; lateral movement insights to list cross-project impersonation paths |
| CI/CD federated identities | An OIDC trust policy that accepts any branch or any environment from a repository | Trust conditions on the environment subject, for example repo:ORG/REPO:environment:prod in GitHub Actions, plus environment protection rules on the prod environment |
| Kubernetes service accounts | Dev and prod namespaces in one cluster, or a shared cluster-wide service account | Separate clusters for prod; Kubernetes documentation itself says boundaries within a namespace should be considered weak. See the Kubernetes Service Account Token Guide. |
| Third-party API keys and OAuth apps | The production payments or messaging key reused in staging; a test OAuth app granted rights in the production tenant | Vendor sandbox or test-mode keys for non-prod; separate tenants; no consent grants from test apps into the production directory |
| SPIFFE workload identities | One trust domain for every environment | Separate trust domains, which the SPIFFE project suggests for staging or lab versus production |
Three identity rules apply across platforms:
- Environment is an attribute of every NHI: record it in the inventory and as a tag or label on the identity itself, so policy and detection can use it. See the Service Account Inventory Template.
- Prefer federation over keys: a federated identity can be bound to one environment by its trust conditions; a static key works wherever it is pasted. See the Workload Identity Federation Guide.
- Non-production uses non-production data: an isolated identity that reads a copy of production data in test still exposes that data. NIST SP 800-53 SA-3(2) Use of Live or Operational Data addresses this directly.
Implementation steps
Removing cross-environment identities touches deployment pipelines, so treat it as a change programme rather than a single clean-up.
- Define the boundaries. Write down which accounts, subscriptions, projects, clusters and tenants belong to each environment. If production and test share a container, record that as the first finding.
- Inventory NHIs with their environment. List every role, service account, managed identity, service principal, API key and OAuth app, with the environment it was created in and every environment where it holds a permission. Cloud-native tools help: AWS IAM Access Analyzer for cross-account access, Google lateral movement insights, Azure role assignment exports.
- Flag the crossings. Any NHI whose home environment differs from a resource it can access is an NHI8 finding. Rank by the privilege held in production.
- Set preventive guardrails in audit mode. Write the organisation-level policies (SCPs, Azure Policy, Google organisation policies) that would deny non-prod principals in prod, and run them as audit or detective rules first to see what would break.
- Create replacement identities per environment. One identity per workload per environment, created from infrastructure as code so the environment tag is always set. For pipelines, create one deploy identity per stage and bind each to its environment subject.
- Cut over in rings. Move development first, then test and staging, then production, so the production identity is the last thing touched. Keep the old shared identity disabled, not deleted, for a defined rollback window.
- Enforce. Switch the guardrails from audit to deny once the findings list is empty, and add a pipeline check that fails any IaC change granting a non-prod principal access to prod.
- Retire the old identity. After the rollback window, revoke keys, remove role assignments (Azure does not delete role assignments automatically when an identity is deleted) and record the closure. See the NHI Offboarding and Decommissioning Guide.
Rollback: if a deployment breaks after cut-over, re-enable the old identity for that one pipeline, log the exception with an expiry date, and fix the missing permission on the new identity rather than widening the guardrail.
Small and large organisations
- Small teams: start with two accounts or subscriptions (prod and everything else), one deploy identity per side, and vendor test-mode keys. That removes most NHI8 exposure with little overhead.
- Large estates: use an organisation structure with a Workloads OU or management group split by stage, policy inherited from the top, and a central identity team that owns the guardrails while application teams own their per-environment identities.
Evidence and assessment
Auditors and internal assessors should be able to answer one question: can any identity created for a non-production environment act on production? The evidence below answers it.
| Evidence | Source | What good looks like |
|---|---|---|
| Environment map | Organisation structure export (OUs, management groups, folders) | Prod in its own accounts, subscriptions or projects with inherited policy |
| NHI inventory with environment tag | NHI inventory or CMDB | Every NHI has exactly one environment; no blanks |
| Cross-environment access report | IAM Access Analyzer, role assignment exports, lateral movement insights | Zero non-prod principals with prod permissions, or each one has an approved, expiring exception |
| Guardrail policies | SCPs, Azure Policy assignments, organisation policies | Deny effect active on prod scopes, change history reviewed |
| Pipeline trust policies | OIDC trust configuration | Prod roles trust only the prod environment subject |
| Sign-in and API logs | CloudTrail, Entra sign-in logs (service principal sign-ins), Cloud Audit Logs | No prod activity by identities tagged non-prod |
Detection and metrics
- Detect: alert when a principal tagged non-prod authenticates to or calls an API in a prod account, subscription or project; when a new cross-account trust or role assignment crosses environments; and when a known test API key appears in production traffic.
- Metric 1: number of NHIs with permissions in more than one environment (target zero).
- Metric 2: percentage of NHIs with an environment tag (target 100%).
- Metric 3: percentage of prod deploy roles whose trust is scoped to a prod environment subject.
- Metric 4: open cross-environment exceptions past their expiry date.
- Metric 5: time from a cross-environment grant being created to it being detected.
Mapping to other frameworks
NHI8 maps cleanly to established control sets. IDs below were checked against NIST SP 800-53 Rev. 5, NIST CSF 2.0 and MITRE ATT&CK v20.
| Framework | Control or technique | Relevance to NHI8 |
|---|---|---|
| NIST SP 800-53 Rev. 5 | CM-4(1) Separate Test Environments | Test changes in an environment separate from operations |
| NIST SP 800-53 Rev. 5 | SA-3(2) Use of Live or Operational Data | Controls on production data used in non-prod |
| NIST SP 800-53 Rev. 5 | AC-6 Least Privilege; IA-9 Service Identification and Authentication | Per-environment, minimally privileged service identities |
| NIST SP 800-53 Rev. 5 | SC-7 Boundary Protection | Environment boundaries enforced, including identity paths across them |
| NIST CSF 2.0 | PR.AA-01, PR.AA-05, PR.IR-01 | Identities managed, permissions with least privilege, environments protected from unauthorised logical access |
| CIS Controls v8.1 | 16.8 Separate Production and Non-Production Systems; 5.5 Establish and Maintain an Inventory of Service Accounts | Separation plus the inventory that proves it |
| ISO/IEC 27001:2022 Annex A | 8.31 Separation of development, test and production environments; 8.33 Test information; 5.16 Identity management | Environment separation, test data and identity lifecycle |
| MITRE ATT&CK v20 | T1078.004 Cloud Accounts; T1550.001 Application Access Token; TA0008 Lateral Movement | How attackers use a shared cloud identity or token to move from test into prod |
Common pitfalls
- Test tenants with production reach: in the Microsoft Midnight Blizzard Breach, the attacker password-sprayed a legacy non-production test tenant account without MFA, then used a legacy test OAuth application that had elevated access to Microsoft's corporate environment to reach executive mailboxes. Test tenants and their apps need the same review as production.
- One deploy identity for every stage: a pipeline role that deploys to dev, test and prod means anyone who can push to a dev branch can influence what reaches prod. See the CI/CD Pipeline Identity Security Guide.
- Wildcard OIDC subjects: trusting
repo:ORG/REPO:*instead of the prod environment subject lets any branch or pull request workflow assume the production role. - Copied configuration files: a staging
.envor Helm values file cloned from production carries production API keys into a less protected place. See the OWASP NHI Top 10 NHI2 Secret Leakage Guide. - Shared cluster, separate namespaces: treating namespaces as an environment boundary when Kubernetes documentation itself calls boundaries within a namespace weak and cluster-wide service accounts span them all.
- Different policies per environment: Microsoft's landing zone guidance warns that looser policy in development lets problems surface only at production; keep the same baseline policy and isolate by subscription instead.
Practitioner checklist
- Production runs in its own accounts, subscriptions, projects, clusters and tenants.
- Every NHI carries one environment tag in the inventory and on the identity itself.
- A report of NHIs with permissions in more than one environment exists and is reviewed monthly.
- Organisation-level policies deny non-prod principals on prod scopes, tested in audit mode first.
- Each pipeline stage has its own deploy identity, and prod trust is bound to the prod environment subject with protection rules.
- Non-production uses vendor test-mode keys and masked or synthetic data, never production keys or live data.
- Test tenants and sandbox OAuth apps have no consent grants or role assignments in production.
- Alerts fire when a non-prod identity acts in prod or a new cross-environment grant appears.
- Retired shared identities are disabled, then removed with their role assignments after the rollback window.
Standards and references
- OWASP: NHI8:2025 Environment Isolation
- OWASP: Non-Human Identities Top 10
- NIST: SP 800-53 Rev. 5
- AWS: Guidance for Workload Isolation on AWS
- AWS: Benefits of using multiple AWS accounts
- Microsoft Learn: Management application environments
- GitHub Docs: About security hardening with OpenID Connect
- SPIFFE: SPIFFE Concepts
Related NHI Mgmt Group resources: OWASP NHI Top 10 NHI9 NHI Reuse Guide · Cloud Workload Identity Guide · Service Account Security Guide · Segregation of Duties Guide · Non-Human Identity (NHI) Guide