-
Notifications
You must be signed in to change notification settings - Fork 431
feat: EntraUser sign on to AWS Identity Center (#1779) #1787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: Alex Chantavy <[email protected]>
Signed-off-by: Alex Chantavy <[email protected]>
Signed-off-by: Alex Chantavy <[email protected]>
Signed-off-by: Alex Chantavy <[email protected]>
@@ -45,119 +32,3 @@ def test_transform_app_role_assignments(): | |||
assert assignment3["principal_display_name"] == "Finance Team" | |||
assert assignment3["resource_display_name"] == "Finance Tracker" | |||
assert assignment3["principal_type"] == "Group" | |||
|
|||
|
|||
@patch("cartography.intel.entra.applications.load") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing these brittle and not very useful unit tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cubic analysis
2 issues found across 9 files • Review in cubic
React with 👍 or 👎 to teach cubic. You can also tag @cubic-dev-ai
to give feedback, ask questions, or re-run the review.
tests/data/entra/applications.py
Outdated
"display_name": "Finance Tracker Service Principal", | ||
"reply_urls": [ | ||
"https://finance.example.com/callback", | ||
"https://d-90663f7df1.awsapps.com/start", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AWS Identity Center instance id in this reply_urls entry is inconsistent with the corresponding login_url and aws_identity_center_instance_id values, which can cause equality assertions in tests to fail (Based on your team's feedback about ensuring mock data is internally consistent).
Prompt for AI agents
Address the following comment on tests/data/entra/applications.py at line 191:
<comment>AWS Identity Center instance id in this reply_urls entry is inconsistent with the corresponding login_url and aws_identity_center_instance_id values, which can cause equality assertions in tests to fail (Based on your team's feedback about ensuring mock data is internally consistent).</comment>
<file context>
@@ -153,3 +154,57 @@
"application_app_id": "ffffffff-eeee-dddd-cccc-bbbbbbbbbbbb",
},
]
+
+MOCK_SERVICE_PRINCIPALS = [
+ ServicePrincipal(
+ id="sp-11111111-1111-1111-1111-111111111111",
+ app_id="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
+ display_name="Finance Tracker Service Principal",
</file context>
"https://d-90663f7df1.awsapps.com/start", | |
"https://d-1234567890.awsapps.com/start", |
✅ Addressed in 4c856f9
target_node_label: str = "AWSSSOUser" | ||
target_node_matcher: TargetNodeMatcher = make_target_node_matcher( | ||
{ | ||
"user_name": PropertyRef("aws_user_name"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Target node matcher relies solely on user_name, which is not guaranteed to be unique across Identity Stores; include identity_store_id in the matcher to avoid incorrect links (Based on your team's feedback about ensuring relationship matchers use stable, unique keys).
Prompt for AI agents
Address the following comment on cartography/models/entra/entra_user_to_aws_sso.py at line 27:
<comment>Target node matcher relies solely on user_name, which is not guaranteed to be unique across Identity Stores; include identity_store_id in the matcher to avoid incorrect links (Based on your team's feedback about ensuring relationship matchers use stable, unique keys).</comment>
<file context>
@@ -0,0 +1,40 @@
+from dataclasses import dataclass
+
+from cartography.models.core.common import PropertyRef
+from cartography.models.core.relationships import CartographyRelProperties
+from cartography.models.core.relationships import CartographyRelSchema
+from cartography.models.core.relationships import LinkDirection
+from cartography.models.core.relationships import make_source_node_matcher
+from cartography.models.core.relationships import make_target_node_matcher
+from cartography.models.core.relationships import SourceNodeMatcher
</file context>
✅ Addressed in 4c856f9
@@ -235,10 +245,48 @@ def transform_app_role_assignments( | |||
return result | |||
|
|||
|
|||
def transform_service_principals( | |||
service_principals: list[ServicePrincipal], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shyammukund this is what I was talking about at lunch: use list[SpecificType]
wherever possible (like here with the Entra SDK because it's available to us. This way we can do things like spn.login_url
instead of getattr(spn, 'login_url', None)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but:
I’m a bit uncomfortable having AWS-specific logic inside an Entra module.
It blurs the module boundaries and could become hard to maintain over time due to cross-dependencies. Especially since we don’t enforce any module execution order.
For example: if Entra runs before AWS, the behavior won’t be what users expect. This could be interpreted as a bug unless the user has deep knowledge of the implementation (i.e., actually read the code to understand the dependency).
I like the idea of:
- standalone modules
- cross-cutting modules (like analysis or ontology)
IMHO, we should eventually move this logic into a dedicated module (e.g., sso-federation
, or another name I’m terrible at naming).
Note: since this is the only case for now, I’m fine merging it but we should open an issue right away to track this and clean it up later.
from typing import Any | ||
from typing import Dict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<3
@@ -313,14 +377,100 @@ def cleanup_app_role_assignments( | |||
).run(neo4j_session) | |||
|
|||
|
|||
@timeit | |||
def cleanup_service_principals( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpicking: I think all the cleanup logic can be in a single function as they have the same purpose and same parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
neo4j_session, transformed_assignments, update_tag, tenant_id | ||
) | ||
# Attach sign-on relationships | ||
sync_entra_to_aws_identity_center(neo4j_session, update_tag, tenant_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like that multiple sync_*
functions have different behaviors:
sync_entra_applications
: performs cleanup and orchestrates other syncssync_entra_apps_roles_spns
andsync_entra_to_aws_identity_center
: don't perform cleanup
For consistency, we should either:
- move the cleanup logic into each sub-function
- or (my preferred option) make the sub-functions private (
_sync_*
) to highlight the difference in responsibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did the first option
Signed-off-by: Alex Chantavy <[email protected]>
Signed-off-by: Alex Chantavy <[email protected]>
Signed-off-by: Alex Chantavy <[email protected]>
Signed-off-by: Alex Chantavy <[email protected]>
I've got this working on my local setup, going to test it e2e soon and then merge when that works |
Signed-off-by: Alex Chantavy <[email protected]>
Looks good, going to merge this in. It's also possible to link to additional federated apps via the entra service principal's login url. The code can be extended there through the federation folder |
Created a federation/ folder to help keep these cross-cuts more organized |
Signed-off-by: Alex Chantavy <[email protected]>
Summary
Related issues or links
Checklist
Provide proof that this works (this makes reviews move faster). Please perform one or more of the following:
If you are changing a node or relationship:
If you are implementing a new intel module: