Skip to content

Conversation

@hrcastro
Copy link

@hrcastro hrcastro commented Nov 23, 2025

Description

Being able to see which users, either via group assignment or direct user assignment, can access an azure application

Motivation and Context

Resolves 2099

currently there's no way to see which users have access to an azure application

How Has This Been Tested?

i tested and work well, can see the results in the graph

Screenshots (optional):

image

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist:

Summary by CodeRabbit

  • New Features

    • Expanded Azure app role assignment support to include Groups and Users alongside Service Principals.
    • Added explicit mappings to convert Group- and User-based assignments into ingestible relationships.
  • Bug Fixes / Reliability

    • Improved error handling and control flow for Azure app role assignment processing for clearer, more reliable ingestion.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 23, 2025

Walkthrough

The PR adds explicit handling for Group and User principal types in Azure app role assignment conversion, introduces PrincipalTypeGroup constant, refactors control flow to short-circuit on JSON errors and use explicit branch returns, and adds two exported converters mapping Group/User app role assignments to ingestible relationships.

Changes

Cohort / File(s) Summary
App role assignment converter refactoring
cmd/api/src/services/graphify/azure_convertors.go
Added PrincipalTypeGroup constant; on JSON deserialization error the converter now returns early; reorganized conditional logic into distinct branches for ServicePrincipal, Group, and User with explicit returns; app role assignment handling extended to support Group and User principals.
New converter functions (Group/User)
packages/go/ein/azure.go
Added exported functions ConvertAzureGroupAppRoleAssignmentToRel(data models.AppRoleAssignment) IngestibleRelationship and ConvertAzureUserAppRoleAssignmentToRel(data models.AppRoleAssignment) IngestibleRelationship that produce IngestibleRelationship entries linking Group/User principals to Apps with relation type azure.MemberOf and empty relation properties.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to:
    • cmd/api/src/services/graphify/azure_convertors.go — verify JSON error short-circuiting and that branch returns prevent duplicate handling.
    • packages/go/ein/azure.go — confirm ID casing, Kind values, and RelType set to azure.MemberOf match conventions used elsewhere.

Suggested labels

api

Suggested reviewers

  • mvlipka

Poem

🐰 I hopped through code with nimble paws,

Groups and Users join the cause,
Principals now find their place,
Early returns quicken the race,
App roles connected — a joyful pause.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding support for Group and User app role assignments in Azure App, which directly matches the code modifications shown in the summary.
Description check ✅ Passed The pull request description follows the required template with all critical sections completed: description, motivation/context with issue reference, testing information with screenshot, type of change, and checklist marked complete.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/go/ein/azure.go (1)

299-331: Group/User → App AZGrant edges look consistent with existing schema

Using PrincipalId as the source (typed as azure.Group/azure.User) and AppId as the target (typed as azure.App) with azure.Grant aligns with how AZApp nodes are keyed (AppId) elsewhere and matches the PR’s goal of exposing which principals can access an app. Uppercasing IDs and using NewIngestibleRelationship keeps this consistent with the rest of the converters.

If you later need to distinguish specific app roles, you could optionally extend these helpers to incorporate AppRoleId into the RelType (similar to RelationshipKindByAppRoleID for SP→SP), but that’s not required for the current feature.

cmd/api/src/services/graphify/azure_convertors.go (1)

213-236: App role assignment branching by principal type looks correct; consider a constant for "Group"

The new control flow in convertAzureAppRoleAssignment looks solid:

  • Returning immediately on JSON unmarshal error avoids processing a zero-valued AppRoleAssignment.
  • Handling the MS Graph + ServicePrincipal case in its own branch (with an early return) keeps the SP↔MS Graph modeling clean and prevents user/group principals from being treated as service principals.
  • The new Group and User branches correctly delegate to the EIN helpers and only append relationships when IsValid() passes, which matches patterns elsewhere.

Two minor follow‑ups:

  • For consistency with PrincipalTypeServicePrincipal / PrincipalTypeUser, you might want a PrincipalTypeGroup constant instead of the string literal "Group".
  • This function still ignores app role assignments where PrincipalType == ServicePrincipal and AppId != azure.MSGraphAppUniversalID; if that’s intentional (same as previous behavior), nothing to change, but it’s worth double‑checking that no desired edges are being dropped.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3944a1c and ecbaa1d.

📒 Files selected for processing (2)
  • cmd/api/src/services/graphify/azure_convertors.go (1 hunks)
  • packages/go/ein/azure.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
cmd/api/src/services/graphify/azure_convertors.go (1)
packages/go/ein/azure.go (4)
  • ConvertAzureAppRoleAssignmentToNodes (241-263)
  • ConvertAzureAppRoleAssignmentToRel (265-297)
  • ConvertAzureGroupAppRoleAssignmentToRel (299-314)
  • ConvertAzureUserAppRoleAssignmentToRel (316-331)
packages/go/ein/azure.go (2)
packages/go/ein/models.go (4)
  • IngestibleRelationship (59-65)
  • NewIngestibleRelationship (22-33)
  • IngestibleEndpoint (45-49)
  • IngestibleRel (51-54)
packages/go/graphschema/azure/azure.go (4)
  • Group (34-34)
  • App (30-30)
  • Grant (67-67)
  • User (41-41)

…ents

Replace hardcoded "Group" string with PrincipalTypeGroup constant for consistency with other principal type checks
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
cmd/api/src/services/graphify/azure_convertors.go (1)

227-237: Consider using else if for mutual exclusivity and adding logging for unhandled types.

The separate if statements for Group and User handling work correctly but using else if would make the mutual exclusivity of principal types more explicit and prevent any theoretical edge case where both conditions could match.

Additionally, consider adding a log warning for unhandled principal types (anything other than ServicePrincipal, Group, or User) to aid debugging and ensure visibility when unexpected data is encountered.

Apply this diff to use else if and add logging for unhandled types:

 	if data.PrincipalType == PrincipalTypeGroup {
 		if rel := ein.ConvertAzureGroupAppRoleAssignmentToRel(data); rel.IsValid() {
 			converted.RelProps = append(converted.RelProps, rel)
 		}
-	}
-
-	if data.PrincipalType == PrincipalTypeUser {
+	} else if data.PrincipalType == PrincipalTypeUser {
 		if rel := ein.ConvertAzureUserAppRoleAssignmentToRel(data); rel.IsValid() {
 			converted.RelProps = append(converted.RelProps, rel)
 		}
+	} else {
+		slog.Warn(fmt.Sprintf("Unhandled principal type in app role assignment: %s", data.PrincipalType))
 	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ecbaa1d and 5982ada.

📒 Files selected for processing (1)
  • cmd/api/src/services/graphify/azure_convertors.go (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
cmd/api/src/services/graphify/azure_convertors.go (1)
packages/go/ein/azure.go (4)
  • ConvertAzureAppRoleAssignmentToNodes (241-263)
  • ConvertAzureAppRoleAssignmentToRel (265-297)
  • ConvertAzureGroupAppRoleAssignmentToRel (299-314)
  • ConvertAzureUserAppRoleAssignmentToRel (316-331)
🔇 Additional comments (3)
cmd/api/src/services/graphify/azure_convertors.go (3)

39-39: LGTM! Constant follows existing pattern.

The new PrincipalTypeGroup constant is consistent with the existing PrincipalTypeServicePrincipal and PrincipalTypeUser constants.


214-217: Good defensive programming with early return.

The early return on JSON deserialization error prevents continued execution with potentially invalid data. This is a solid improvement.


219-225: Explicit return improves control flow clarity.

Adding the explicit return after ServicePrincipal handling makes it clear that this branch is terminal and prevents any unintended fall-through behavior.

@github-actions
Copy link

CLA Assistant Lite bot:
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request

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.

Feature: Map AZUser and AZGroup to AZApp using AZMemberOf relationship

1 participant