Playbook

Confused Deputy Hunting Framework

By Justin O'Leary May 20, 2026

This framework distills the methodology behind 15+ confused deputy findings across AWS, Azure, and GCP into a repeatable hunting process. Print it, bookmark it, keep it in a tab while you audit.

Taxonomy of Confused Deputy Patterns

Confused deputy vulnerabilities cluster into five distinct patterns. Understanding which pattern you’re hunting changes where you look.

🔀
Cross-Namespace
K8s controller spans namespaces
👥
Cross-Tenant
Service spans customers
🔗
Cross-Service
Service A invokes Service B
🎭
Federated Identity
OIDC/SAML trust exploited
🌐
Ambient Authority
Broad perms exploited

Cross-Namespace (Kubernetes)

A controller in namespace A processes a resource that references something in namespace B. The controller has cluster-wide permissions; the user creating the resource does not.

Canonical example: A backup operator watches BackupRequest resources. A user creates a BackupRequest in their namespace that targets a Secret in kube-system. The operator has cluster-admin to read secrets everywhere. The user has access to nothing outside their namespace. The operator reads the kube-system secret using its own credentials without checking if the requesting user should see it.

Where to look: Any Kubernetes operator that accepts resource references (ConfigMapRef, SecretRef, namespaceSelector, external references). Flux, ArgoCD, Crossplane resource claims, backup controllers, cert-manager, external-secrets.

Cross-Tenant (Multi-tenant Services)

A managed service acts on resources for customer A but can be tricked into accessing customer B’s resources. The service has cross-tenant authority that individual customers should never exercise.

Canonical example: A backup service stores data in provider-managed storage. Customer A specifies a restore target. The service validates that customer A has permission to invoke restore, but not that the specified target belongs to customer A. Customer A restores data to customer B’s environment.

Where to look: Any SaaS or managed service that operates across customer boundaries. Backup services, monitoring aggregators, shared CI/CD platforms, multi-tenant Kubernetes offerings.

Cross-Service (Service Chains)

Service A calls Service B with Service A’s elevated credentials. An attacker who can invoke Service A indirectly gains Service B access they shouldn’t have.

Canonical example: An API gateway authenticates users, then proxies requests to backend services using a service account. The gateway has broad backend access. A user who can craft requests through the gateway reaches backends they shouldn’t, because the gateway’s credentials unlock more than the user’s should.

Where to look: API gateways, service meshes with delegation, orchestration services that compose multiple backends, CI/CD systems that call cloud APIs.

Federated Identity (OIDC/SAML Trust)

An identity provider asserts claims that a service trusts without sufficient validation. The service grants access based on the assertion without checking if the asserting party should be able to make that claim.

Canonical example: A Kubernetes cluster trusts an OIDC provider for workload identity. Pod A requests a token with claims that grant access to Cloud Resource X. The token is issued based on Pod A’s service account, but no one verified that Pod A’s service account should map to Cloud Resource X. The trust policy is too broad.

Where to look: OIDC federation configs (AWS IRSA, GCP Workload Identity, Azure Workload Identity), SAML trust relationships, Kubernetes service account token projection, Vault JWT auth backends.

Ambient Authority (Broad Permissions Exploited)

A service holds permissions far exceeding what any single operation requires. An attacker finds an invocation path that exercises unintended permissions.

Canonical example: A deployment controller has permissions to create any resource type to handle arbitrary deployments. An attacker who can trigger a deployment creates resources the deployment process wasn’t designed to manage, like RoleBindings or privileged pods. The controller’s broad permissions become a weapon.

Where to look: Any service with wildcard permissions, admin roles, or “break glass” access. Operators with cluster-admin, deployment systems with resource creation rights, automation with owner-level cloud IAM.


Attack Pattern Anatomy

Every confused deputy vulnerability has five components. When you find one, decompose it into these parts.

CALLERLow-privilegeinvokesDEPUTYElevated permissions⚠ No authz checkaccessesTARGETUnauthorizedTRUST BOUNDARY
ComponentDefinitionExample
CallerThe low-privilege entity initiating the attackUser with Backup Contributor role
DeputyThe trusted service with elevated permissionsAzure Backup extension
TargetThe resource the attacker shouldn’t accessAKS cluster secrets
Trust BoundaryWhere authorization should happen but doesn’tAzure RBAC to Kubernetes RBAC transition
TriggerHow the attacker invokes the deputyEnable backup on target cluster

The vulnerability exists when the Deputy exercises its own authority to access the Target on behalf of the Caller, without verifying that the Caller is authorized to access the Target directly.


Cloud-Specific Patterns

Each cloud has its own IAM model, which means confused deputies manifest differently.

AWS

Key patterns:

  • IAM Role trust policies that allow AssumeRole from unexpected principals
  • Service-linked roles that can be triggered by users who shouldn’t have that role’s permissions
  • Cross-account resource policies that trust entire accounts rather than specific roles
  • Lambda/Step Functions that execute with function roles but are invokable by less-privileged users

High-value targets:

  • Controllers that use sts:AssumeRole to access customer resources (ACK, Crossplane AWS provider)
  • Services that create IAM resources (trust policies, OIDC providers)
  • Anything with iam:* or sts:* that processes user input

Red flag: A controller creates IAM trust policies based on user-supplied input without validating the user can already access the trusted principal.

Azure

Key patterns:

  • Managed identities with broad RBAC assignments triggered by users with narrow permissions
  • Trusted Access (AKS) granting Kubernetes permissions based on Azure RBAC
  • Resource providers that create resources with their own identity but on user request
  • Entra ID app registrations with delegated permissions beyond what requesting users hold

High-value targets:

  • Backup services (they need admin to function)
  • GitOps extensions (Arc, Flux, anything deploying to clusters)
  • Services bridging Azure RBAC and Kubernetes RBAC

Red flag: Azure RBAC role grants permissions to invoke a service that grants Kubernetes RBAC permissions the Azure role doesn’t imply.

GCP

Key patterns:

  • Service accounts with Owner or broad IAM roles invoked via less-privileged paths
  • Config Connector and other GKE controllers that manage GCP resources
  • Workload Identity bindings that map Kubernetes service accounts to GCP service accounts
  • IAM Conditions that aren’t enforced at every invocation point

High-value targets:

  • Config Connector (translates K8s resources to GCP API calls)
  • GKE Hub/Fleet (manages multiple clusters with elevated permissions)
  • Any controller with resourcemanager.* or iam.* permissions

Red flag: A spec.resourceRef.external field that accepts cross-project resource references without validating the requesting namespace has permission to that project.

Kubernetes (Platform-Agnostic)

Key patterns:

  • Controllers with ClusterRole watching namespaced resources
  • Admission webhooks that run with elevated permissions
  • Service accounts shared across namespaces
  • RBAC aggregation rules that grant unexpected permissions

High-value targets:

  • GitOps controllers (ArgoCD, Flux) that deploy arbitrary manifests
  • Backup operators that read cluster-wide secrets
  • Policy engines that can approve their own exceptions
  • Cert-manager, external-secrets, any controller bridging external systems

Red flag: Controller has ClusterRoleBinding but watches resources that namespace-scoped users can create.


The Hunting Checklist

Ask these ten questions when auditing any managed service, operator, or controller.

1. What identity does this service use?

Find the service account, managed identity, or IAM role. Check its trust policy, role bindings, and permission grants. This is your deputy.

2. What permissions does that identity have?

List explicit grants. Look for wildcards, admin roles, cross-boundary access. The gap between “permissions required for legitimate function” and “permissions actually granted” is attack surface.

3. Who can invoke this service?

What RBAC roles, IAM policies, or namespace access allows creating the triggering resource? This defines your caller population.

4. Can the target be specified by the caller?

If the service acts on targets the caller specifies (resource references, ARNs, paths), the service must validate the caller’s access to those targets. If targets are hardcoded or derived from caller identity, risk is lower.

5. Does invocation require authorization to the target resource?

This is the critical question. When the caller says “operate on X,” does the service check that the caller can access X directly? Or does it only check that the caller can invoke the service?

6. What trust boundaries does this service span?

Azure RBAC to K8s RBAC. AWS IAM to S3 bucket policy. GCP project A to project B. Every boundary crossing is a potential gap.

7. Can cross-boundary references be specified?

Can a resource in namespace A reference something in namespace B? Can a config in Account A point to a resource in Account B? Cross-boundary references are confused deputy breeding grounds.

8. What happens if the target doesn’t exist?

Some services create missing targets using their elevated permissions. An attacker who specifies a non-existent target gets the service to create it with attacker-specified properties.

9. Is there audit logging for the deputy’s actions?

If the deputy’s actions aren’t logged with the original caller’s identity, confused deputy exploitation is harder to detect and attribute. This is a finding multiplier, not a vulnerability itself.

10. What’s the blast radius?

If exploited, what’s the worst outcome? Cluster-admin? Org-level IAM? Cross-tenant data access? This determines severity and whether the finding is worth developing.


Decision Tree

Use this flowchart to quickly assess if a service is worth deeper investigation.

Acts on behalf of callers?SkipNoYesElevated permissions?Low riskNoYesCaller specifies targets?Lower riskNoYesValidates caller access to target?Not vulnerableYesNo⚠ CONFUSED DEPUTYInvestigate thoroughly

Red Flags Checklist

These signals indicate high confused deputy risk. The more boxes checked, the harder you should look.

Permission signals:

  • Service has admin, owner, or cluster-admin role
  • Wildcard permissions (*) in any scope
  • Cross-account, cross-project, or cross-tenant grants
  • Service-linked or managed identity with inherited permissions

Architecture signals:

  • Cross-namespace resource references allowed
  • External resource ARNs/URLs accepted in specs
  • Service creates resources that didn’t exist
  • Trust boundaries span multiple systems (cloud IAM ↔ K8s RBAC)

Authorization signals:

  • No admission webhook validating references
  • Authorization checks only at invocation, not at target access
  • Shared service accounts across namespaces or tenants
  • Trust policy allows broad principal set

Documentation signals:

  • Docs emphasize convenience over security model
  • No discussion of multi-tenant isolation
  • “Just grant admin” in setup instructions
  • Security model not documented at all

Hunt Execution

When you start a hunt, follow this sequence.

Phase 1: Target Selection (1 hour)

Pick services with high deputy potential: backup, GitOps, identity federation, resource provisioning. Prioritize services that span trust boundaries (cloud IAM to K8s RBAC, cross-project, cross-tenant).

Phase 2: Permission Mapping (2-4 hours)

Document the service’s identity and its permissions exhaustively. For K8s operators, dump the ClusterRole. For cloud services, enumerate IAM role policies. Create a table: “Permission | Why Needed | Exploitable Alone?”

Phase 3: Invocation Path Analysis (2-4 hours)

How do callers trigger this service? What resource types? What fields are caller-controlled? Map every input that could specify a target.

Phase 4: Authorization Gap Hunting (4-8 hours)

For each caller-specified target, trace whether the service validates the caller’s access to that target. Read the code if open source. Test with cross-boundary references if closed source. This is where vulnerabilities hide.

Phase 5: Exploitation and Documentation (4-8 hours)

Build a proof of concept. Document the attack chain. Calculate CVSS. Write the report.


Getting Started: Apply This Today

Before hunting in the wild, audit your own infrastructure.

Step 1: Inventory Services with Elevated Permissions

Questions to ask your platform team:

  • Which service accounts have cluster-admin or equivalent?
  • Which managed identities have Owner, Contributor, or broad write access?
  • Which IAM roles can be assumed by services (not humans)?
  • What controllers/operators are installed cluster-wide?

Step 2: Prioritize by Risk

PriorityCharacteristicsExamples
P1Admin perms + user-controlled targets + spans trust boundariesBackup controllers, GitOps operators, identity federation
P2Admin perms + user-controlled targetsResource provisioners, secret syncing
P3Elevated perms + limited user controlMonitoring agents, log collectors

Step 3: Map Permission → Invocation → Target

For each P1/P2 service, document:

  1. Identity: What SA/managed identity/role does it use?
  2. Permissions: What can that identity do?
  3. Invocation: How do users trigger it?
  4. Targets: Can users specify what it acts on?
  5. Validation: Does it check user access to targets?

If #4 is “yes” and #5 is “no” — you have a finding.


Inventory Commands

AWS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# List IAM roles and their trust policies
for role in $(aws iam list-roles --query 'Roles[*].RoleName' --output text); do
  echo "=== $role ===" && aws iam get-role --role-name "$role" \
    --query 'Role.AssumeRolePolicyDocument' --output json
done

# Find service-linked roles
aws iam list-roles --query 'Roles[?starts_with(Path, `/aws-service-role/`)].[RoleName]' --output table

# Check for confused deputy protections (should return SourceArn/SourceAccount)
aws iam get-role --role-name ROLE_NAME --query 'Role.AssumeRolePolicyDocument' | \
  grep -E 'SourceArn|SourceAccount|ExternalId'

Azure

1
2
3
4
5
6
7
8
9
# List managed identities with role assignments
az identity list -o table

# Find identities with Owner/Contributor
az role assignment list --all \
  --query '[?roleDefinitionName==`Owner` || roleDefinitionName==`Contributor`].{principal:principalName, role:roleDefinitionName, scope:scope}' -o table

# List AKS extensions
az k8s-extension list --cluster-name CLUSTER --resource-group RG --cluster-type managedClusters -o table

GCP

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# List service accounts
gcloud iam service-accounts list

# Find service accounts with Owner/Editor
gcloud projects get-iam-policy PROJECT_ID \
  --flatten="bindings[].members" \
  --filter="bindings.role:(roles/owner OR roles/editor) AND bindings.members:serviceAccount:" \
  --format='table(bindings.members, bindings.role)'

# List workload identity bindings
gcloud iam service-accounts get-iam-policy SA_EMAIL \
  --format='json(bindings)' | jq '.bindings[] | select(.role=="roles/iam.workloadIdentityUser")'

Kubernetes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Find service accounts with cluster-admin
kubectl get clusterrolebindings -o json | \
  jq -r '.items[] | select(.roleRef.name=="cluster-admin") | .subjects[]? | select(.kind=="ServiceAccount") | "\(.namespace)/\(.name)"'

# Find CRDs that could trigger deputies
kubectl get crd -o name | grep -iE 'backup|restore|deploy|sync|secret|config'

# Who can create secrets cluster-wide?
kubectl auth can-i create secrets --all-namespaces --list

# Install rbac-tool for deeper analysis
kubectl krew install rbac-tool && kubectl rbac-tool analysis

Walkthrough: Auditing a Backup Controller

Why Backup Controllers?

They need read access everywhere, accept user input specifying targets, and cross trust boundaries.

The Hunt

1. Identify the deputy:

1
2
3
kubectl get crd | grep -i backup
kubectl get pods -A | grep -i backup
kubectl get deployment -n NAMESPACE DEPLOYMENT -o jsonpath='{.spec.template.spec.serviceAccountName}'

2. Map permissions:

1
2
3
kubectl get clusterrolebindings -o json | \
  jq -r ".items[] | select(.subjects[]? | .name==\"SA_NAME\") | .roleRef.name"
kubectl get clusterrole ROLE_NAME -o yaml

3. Test cross-boundary access:

1
2
3
4
5
6
7
8
apiVersion: backup.example.io/v1
kind: BackupRequest
metadata:
  name: test-cross-namespace
  namespace: attacker-ns   # Your namespace
spec:
  includeNamespaces:
    - kube-system          # Target you shouldn't access

4. Confirm the gap:

  • ✅ You can create BackupRequest in attacker-ns
  • ✅ You cannot read secrets in kube-system directly
  • ✅ Controller reads kube-system using its own credentials
  • ❌ Controller does NOT verify you can access kube-system

If all true except the last — confused deputy confirmed.


References

Foundational:

Cloud Provider Documentation:

Case Studies: