The Blind Spot of Machine Identity Security in CI/CD: Hidden Risks in OIDC Trust Policies

OIDC trust policy misconfigurations in CI/CD can silently grant attackers full production access.
Machine identities like service principals and CI/CD federated identities often hold the highest privileges in cloud environments yet escape traditional access reviews. This article reveals how OIDC trust policy misconfigurations — overly broad wildcards, unrestricted branches, and string prefix vulnerabilities — can let attackers silently obtain production credentials without triggering any alerts, and provides actionable strategies for machine identity governance.
Introduction: The Overlooked "Invisible Admins"
In cloud-native architectures, security teams are accustomed to pouring effort into identity governance for human users — multi-factor authentication, periodic access reviews, offboarding procedures, and so on. Yet a more covert and more dangerous problem is being systematically overlooked: the most privileged identity in your system may not have a login at all.
We're talking about Service Principals and CI/CD Federated Identities. Service principals are non-human identity entities created on cloud platforms (such as Azure AD, AWS IAM, and GCP) for applications, services, or automation tools. Unlike human user accounts, service principals authenticate via certificates, keys, or tokens, and are designed specifically for automated machine-to-machine interactions. Federated Identity is an authentication mechanism that operates across trust domains, allowing tokens issued by external identity providers (such as GitHub or GitLab) to be directly trusted by a target cloud platform — eliminating the need to store long-lived credentials in the cloud. The core protocol behind this mechanism is OpenID Connect (OIDC), which adds an identity verification layer on top of OAuth 2.0. It enables a CI/CD platform to prove to the cloud that "I am a specific workflow running in a specific repository," and the cloud then decides whether to grant access based on a pre-configured trust policy.
These identities don't need passwords, won't trigger login alerts, and almost never appear on quarterly access review lists. Yet it is precisely these "faceless" machine identities that often hold the highest-level permissions with direct access to production environments.

Why Service Identities Slip Through Access Reviews
The Governance Gap Between Human and Machine Identities
Traditional identity governance frameworks are designed around people. When employees join or leave a team, there are clear onboarding and offboarding procedures. When permissions are excessive, quarterly access reviews catch them. This system has been refined over years and is quite mature.
However, service principals and the federated identities used by CI/CD pipelines inherently bypass these checkpoints. They aren't "people," which means:
- They are not included in human-centric access review processes
- They have no interactive logins, so they don't trigger login-behavior-based anomaly detection
- Their lifecycles are decoupled from human accounts, and they often persist long after a project has ended
The result: an identity created to enable automated pipeline deployments may hold write or even administrative permissions to production environments, yet go unquestioned for months or even years. It's worth noting that according to industry reports, machine identities already outnumber human identities at ratios of 10:1 or higher, while most organizations' identity governance tools and processes are still designed around human users. This asymmetry between volume and governance capability is becoming one of the biggest blind spots in cloud security.
Permission Creep: The "Boiling Frog" Problem of Machine Identities
What makes this even trickier is that machine identity permissions tend to only grow, never shrink. Whenever a new deployment requirement comes up, engineers are inclined to "add one more permission" to an existing service principal rather than performing a fine-grained split. Over time, an identity originally responsible for deploying a single microservice accumulates superuser-level permissions spanning multiple production systems. Without a review mechanism, this permission creep is nearly invisible.
This phenomenon is especially prevalent in DevOps culture. When engineering teams pursue deployment speed and automation efficiency, the "just make it work" principle takes priority, while permission tightening is treated as a "we'll do it later" optimization. But "later" almost never comes — because there is no mechanism to remind anyone to circle back and clean up. Unlike human users, whose permissions may be re-evaluated when they change roles, machine identities tend to exist in a "set and forget" state once created and granted permissions.
The Real Access Control Lives in the OIDC Trust Policy
The Configuration String That Defines the Security Boundary
The central argument of this article is this: for CI/CD federated identities, the thing that actually determines who can reach production is the configuration string in the OIDC Trust Policy, not traditional credential management.
Take the example of GitHub Actions federating into AWS via OIDC. The workflow is as follows: when a GitHub Actions workflow runs, GitHub, acting as the OIDC Identity Provider (IdP), issues a short-lived JWT (JSON Web Token) for that workflow. This token contains a rich set of claims, such as the repository name (repository), branch name (ref), trigger event type (event_name), workflow name (workflow), environment (environment), and more. The workflow sends this token to the AWS STS AssumeRoleWithWebIdentity endpoint. After verifying the token signature, AWS compares the claims in the token against the conditions defined in the role's trust policy one by one. Only when all conditions are satisfied does it issue temporary cloud credentials.
This mechanism eliminates the need to store long-lived keys in CI/CD systems, significantly reducing the risk of credential leakage — but the security boundary shifts entirely to the condition configuration in the trust policy. In AWS, for example, an IAM role's trust policy is a JSON document where the Principal field specifies the OIDC provider's ARN, the Action field is set to sts:AssumeRoleWithWebIdentity, and the Condition field is the core of the security boundary, using StringEquals or StringLike operators to match claims in the JWT. Azure and GCP have similar mechanisms, implemented through Federated Credentials and Workload Identity Federation respectively. This condition string is the last — and only — line of defense for the entire security boundary.
The Catastrophic Consequences of OIDC Trust Policy Misconfigurations
The problem is that these trust policies are extremely easy to get wrong, and errors are often hard to detect. Common configuration pitfalls include:
- Overly broad wildcards: Using
repo:org/*instead of specifying the exact repository, allowing workflows from any repository in the organization to obtain elevated permissions - Unrestricted branches or environments: Failing to constrain the
refcondition, so that any branch — including a PR branch submitted by an attacker — can trigger a deployment - String prefix vulnerabilities in subject matching: Improper anchoring in condition matching that can be exploited by similarly named resources
The string prefix vulnerability deserves a deeper technical explanation. In AWS IAM conditions, if the StringLike operator is used with a wildcard pattern like repo:my-org/my-repo*, an attacker could create a repository named my-org/my-repo-malicious to match that condition. More subtly, the sub claim format in a GitHub OIDC token is repo:org/repo:ref:refs/heads/main. If the condition only matches up to repo:org/repo without including the full ref qualifier, then any branch — including workflows triggered by pull_request_target events from forks — could satisfy the condition. The industry has already seen multiple supply chain attack cases caused by this type of misconfiguration, where attackers obtained production cloud credentials in the CI environment by submitting PRs containing malicious code.
Once that configuration string is too loose, an attacker doesn't need to crack any password. They simply need to run a piece of code in a context that satisfies the conditions to "legitimately" obtain the highest level of production access. And none of this triggers a login alert, because from the cloud platform's perspective, it's a perfectly normal token exchange that complies with the trust policy — it won't even be flagged as anomalous in traditional Security Information and Event Management (SIEM) systems.
Strategies for Security Teams
Bring Machine Identities Into the Review Scope
The first order of business is to break the mindset that "access reviews are only for humans." Security teams should:
- Build a complete inventory of machine identities, clearly documenting the purpose, permission scope, and owner of every service principal and federated identity
- Include these identities in periodic reviews, identifying and revoking identities that are long unused or over-privileged
- Assign a clear owner for each identity to prevent "orphan identities" from going unmanaged indefinitely
On the implementation side, the major cloud platforms already provide supporting tools: AWS IAM Access Analyzer can analyze actual role usage and generate least-privilege policy recommendations; Azure AD's Workload Identities feature supports conditional access policies and access reviews for service principals; and GCP's Policy Analyzer can audit Workload Identity Federation configurations. However, tools are just the foundation — the real challenge lies in embedding machine identity governance into an organization's operational processes and culture.
Treat OIDC Trust Policies as Code
Since OIDC trust policies are the real access control point, they should be managed with the same rigor applied to critical code:
- Be precise with conditions: Avoid wildcards and narrow trust conditions down to specific repositories, branches, and environments
- Policy as Code: Place trust policies under version control with automated review, and require peer review for any changes
- Continuous validation: Use tools to periodically scan trust policies, detecting overly permissive configurations and potential matching vulnerabilities
Policy as Code is the practice of managing security policies, compliance rules, and access control configurations in a versionable, testable, and auditable code format. In OIDC trust policy governance, commonly used toolchains include: HashiCorp Sentinel or Open Policy Agent (OPA) for defining and enforcing policy rules — you can write automated checks such as "no trust policy may contain a wildcard repository match"; Terraform or Pulumi and other Infrastructure as Code tools for declaratively managing trust policy configurations, ensuring all changes go through a code repository rather than manual console operations; GitHub/GitLab Code Review mechanisms to ensure any policy change is approved by at least one security team member; and tools like Bridgecrew/Checkov to automatically scan trust policies in the CI pipeline, intercepting potential risks before configuration changes reach production.
Applying Least Privilege to Machine Identities
The principle of Least Privilege applies equally to machine identities, and in practice, it may even be easier to achieve fine-grained control than with human identities. Creating purpose-specific identities for different deployment tasks, rather than one all-powerful super-role, can drastically reduce the blast radius of any single misconfiguration.
Specifically, a "one pipeline, one identity" strategy can be adopted: create separate service principals for build, test, staging deployment, and production deployment, each holding only the minimum set of permissions needed to complete its specific task. For example, the build-stage identity only needs permissions to read the source code repository and push container images, with no access to the production environment at all. The production deployment identity only needs permissions to update a specific Kubernetes namespace or specific cloud resources, rather than administrator access to the entire AWS account. Combined with short-lived tokens (AWS STS temporary credentials expire after 1 hour by default) and GitHub Actions environment protection rules (requiring manual approval before triggering production deployments), you can build a defense-in-depth security posture.
Conclusion
As automation and CI/CD become ubiquitous, machine identities are growing at a pace that far outstrips human accounts. They have no face, they never log in, yet they often hold the most critical permissions in the system. Ignoring this layer is like leaving an unguarded back door in an otherwise carefully fortified security wall.
The next time you conduct a security assessment, ask yourself this question: Is the most privileged identity in my system the one that never logs in? And that OIDC trust policy string behind it — have you actually reviewed it?
Related articles

NVIDIA and Hugging Face Deepen Partnership: New Opportunities for the Open-Source AI Ecosystem
NVIDIA and Hugging Face deepen their partnership to boost open-source AI through performance optimization, better toolchains, and ecosystem expansion for developers and enterprises.

7900XTX Local Deployment of Qwen3 in Practice: 53 TPS Inference Speed Optimization Guide
Complete guide to deploying Qwen3 27B model on AMD RX 7900XTX 24GB: achieve 53 TPS inference through KV Cache Q4 quantization, 262K ultra-long context, and MTP speculative sampling, with installation tutorial and quantization precision comparison.

AI Daily Briefing: Alibaba Open-Sources Qwen3.8 Vision Flagship, Zhipu's GLM-5.3 Tops Coding Benchmarks, SpaceX Acquires Cursor
Alibaba open-sources Qwen3.8-27B vision model surpassing its closed-source predecessor; Zhipu GLM-5.3 tops open-source coding with 50% gains; SpaceX acquires Cursor; Google Gemini 3.7 Flash debuts.