Skip to content

fix(azure): AZAddSecret must not target managed identities (#943) - #3254

Open
earbona23 wants to merge 1 commit into
SpecterOps:mainfrom
earbona23:fix/az-addsecret-excludes-managed-identities
Open

earbona23 wants to merge 1 commit into
SpecterOps:mainfrom
earbona23:fix/az-addsecret-excludes-managed-identities

Conversation

@earbona23

@earbona23 earbona23 commented Sep 3, 2026

Copy link
Copy Markdown

Fixes #943.

The problem

postAddSecret (packages/go/analysis/azure/post.go) paired every AddSecret-capable role with every application and service principal in the tenant, with no discrimination. A managed identity is ingested as a plain AZServicePrincipal, so it was swept in and given an inbound AZAddSecret edge. That edge is bogus: a managed identity's credentials are issued and rotated by Azure — there is no addPassword/addKey on it — so an Application Administrator cannot mint one. The path renders as a privilege-escalation route that cannot be walked.

The fix

There is no managed-identity node kind. AZManagedIdentity is a relationship (resource --AZManagedIdentity--> ServicePrincipal), so the only way to recognise a managed identity is an inbound AZManagedIdentity edge — a fix written as a node-kind or property check silently matches nothing. managedIdentityServicePrincipalIDs collects the end nodes of AZManagedIdentity edges, and postAddSecret skips those targets. The exclusion is applied in postAddSecret, not in the shared TenantApplicationsAndServicePrincipals query; AddOwner is left untouched (a separate question).

The managed-identity set is resolved once in AppRoleAssignments and threaded through, rather than re-queried per tenant inside postAddSecret (addresses the reviewer's earlier performance note).

Test

AZAddSecretHarness gains a VM-backed managed identity (a VM, a managed-identity SP, and the AZManagedIdentity edge). RoleAddSecret asserts exactly 4 edges and additionally that no AZAddSecret edge targets the managed-identity SP. go build and go vet pass; the integration test binary compiles with the harness changes.

3 files, +68/-9.


Note: this supersedes #3240, which GitHub auto-locked after a bad force-push corrupted its diff view. This branch is now clean.

Summary by CodeRabbit

  • Bug Fixes
    • Prevented incorrect AZAddSecret relationships from being assigned to service principals backed by Azure-managed identities.
    • Ensured Azure-managed credentials are not treated as user-mintable secrets.
  • Tests
    • Added regression coverage verifying managed-identity service principals are excluded from AZAddSecret relationships.

…s#943)

`postAddSecret` paired every AddSecret-capable role with every application and service
principal in the tenant, with no discrimination. A managed identity is ingested as a plain
`AZServicePrincipal`, so it was swept in and given an inbound `AZAddSecret` edge — a
privilege-escalation path that cannot be walked, because a managed identity's credentials
are issued and rotated by Azure and there is no addPassword/addKey on it.

The fix excludes managed-identity service principals in `postAddSecret`. A managed identity
is distinguished only by an inbound `AZManagedIdentity` edge (it has no dedicated node
kind), so `managedIdentityServicePrincipalIDs` collects the end nodes of those edges and the
loop skips them. The exclusion is applied in `postAddSecret` and not in the shared
`TenantApplicationsAndServicePrincipals` query, which `postAddOwner` also uses — whether
`AZAddOwner` to a managed identity is likewise bogus is a separate question and is left
untouched here (happy to follow up on it).

The `AZAddSecretHarness` gains a VM-backed managed identity, so the regression is
load-bearing: without the exclusion the AddSecret count rises from 4 to 6, and the test also
asserts no `AZAddSecret` edge targets the managed-identity SP.

rvazarkar identified `packages/go/analysis/azure/post.go#addSecret` as the location on the
issue; this is that change.
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Team

Run ID: dfe31e2a-fd70-4b82-b7a6-7a5b3124cc34

📥 Commits

Reviewing files that changed from the base of the PR and between e284049 and dce99c2.

📒 Files selected for processing (3)
  • cmd/api/src/test/integration/harnesses.go
  • packages/go/analysis/azure/azure_integration_test.go
  • packages/go/analysis/azure/post.go

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

Azure analysis now identifies service principals linked to managed identities and excludes them from AZAddSecret edges. The integration harness and RoleAddSecret test cover this behavior with a VM-managed identity fixture.

Changes

Managed identity AddSecret filtering

Layer / File(s) Summary
Managed identity identification and filtering
packages/go/analysis/azure/post.go
The analysis collects managed identity service principal IDs, passes them through app role assignment processing, and skips those targets when creating AZAddSecret edges.
Managed identity regression coverage
cmd/api/src/test/integration/harnesses.go, packages/go/analysis/azure/azure_integration_test.go
The integration harness creates a VM-managed identity relationship. The test verifies that the managed identity service principal does not receive an AZAddSecret edge.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to dce99

This change prevents AddSecret privilege edges from targeting managed-identity service principals while retaining valid application and enterprise-application edges. The scoped regression coverage supports the intended behavior, with no current merge-blocking risk identified.

Suggested reviewers: urangel

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 2 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary fix: preventing AZAddSecret edges from targeting managed identities.
Description check ✅ Passed The description explains the problem, implementation, scope, linked issue, and testing. It is sufficiently complete despite not reproducing every optional template checklist section.
Linked Issues check ✅ Passed The changes satisfy issue #943 by identifying managed-identity service principals through AZManagedIdentity relationships and excluding them from AZAddSecret edges while preserving valid application a…
Out of Scope Changes check ✅ Passed The changes remain within the linked issue scope. They update AZAddSecret generation and regression coverage, while leaving AddOwner behavior unchanged.
Full details: Linked Issues check

Explanation

The changes satisfy issue #943 by identifying managed-identity service principals through AZManagedIdentity relationships and excluding them from AZAddSecret edges while preserving valid application and enterprise application edges.

Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 2 files. (1 skipped: 1 too large.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Bloodhound CE: Edge AZAddSecret to Managed Identities

1 participant