Skip to content
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

Opal Intel module #1411

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Opal Intel module #1411

wants to merge 2 commits into from

Conversation

SecPrez
Copy link
Contributor

@SecPrez SecPrez commented Dec 17, 2024

Intel module to map in Opal Resource, what those resources grant access, and map who can automatically and manually approve themselves to those resources.

Summary

Describe your changes.

image

Related issues or links

Include links to relevant issues or other pages.

Checklist

Provide proof that this works (this makes reviews move faster). Please perform one or more of the following:

  • [ x] Update/add unit or integration tests.
  • Include a screenshot showing what the graph looked like before and after your changes.
  • Include console log trace showing what happened before and after your changes.

If you are changing a node or relationship:

If you are implementing a new intel module:

= and others added 2 commits December 17, 2024 09:51
…ss to and who can automatically and manually approve themselves to those resources.
Copy link
Contributor

@achantavy achantavy left a comment

Choose a reason for hiding this comment

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

Thanks for putting this together, I'm excited. Left some comments about using the data model to represent some of the OpalResource relationships, and how we'd need to add some read_transaction() functions to grab lists of IDs from the graph to make that possible.

I think it's also worth adding in a "fake tenant" node for the OpalResource so that we can automatically clean up the OpalResources -- this is done with the LastPass sync here: #1083.

Happy to get on a call if there's things that don't make sense, also happy to help with making these changes too, just let me know.

UNWIND $auto_approved_access AS access
MATCH (opal_resource:OpalResource {id: access.resource_id})
MATCH (okta_group:OktaGroup {id: access.okta_group_id})
MERGE (okta_group)-[r:CAN_AUTO_APPROVE_ACCESS]->(opal_resource)
Copy link
Contributor

Choose a reason for hiding this comment

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

Same idea like with (:OpalResource)-[:PROVIDES_ACCESS_TO]->(:AWSRole): let's refactor to use a rel schema with make_target_node_matcher so that the OpalResource looks for an OktaGroup with the group id we need. We should use read_transaction() to get those OktaGroups.

It's a bit of a performance hit to do it this way because of the data moving back and forth, but I think it's worth it to get the automatic cleanups and data model benefits.

(aws_role:AWSRole)<-[:ASSIGNED_TO_ROLE]-
(aws_permset:AWSPermissionSet {arn: resource.remote_id})
MATCH (opal_resource:OpalResource {id: resource.resource_id})
MERGE (opal_resource)-[r:PROVIDES_ACCESS_TO]->(aws_role)
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use the OpalResource model that you created.

We can refactor to use rel schema with make_target_node_matcher. To do this, have a separate function query for the AWS role names that we need to grab from the given permission set. That separate function should use read_transaction for auto retries like in

def get_awssso_okta_groups(neo4j_session: neo4j.Session, okta_org_id: str) -> list[OktaGroup]:
"""
Return list of all Okta group ids in the current Okta organization tied to Okta Applications with name
"amazon_aws_sso".
"""
query = """
MATCH (g:OktaGroup)-[:APPLICATION]->(a:OktaApplication{name:"amazon_aws_sso"})
<-[:RESOURCE]-(:OktaOrganization{id: $okta_org_id})
RETURN g.id as group_id, g.name as group_name
"""
result = neo4j_session.read_transaction(read_list_of_dicts_tx, query, okta_org_id=okta_org_id)
return [OktaGroup(group_name=og['group_name'], group_id=og['group_id']) for og in result]
.

return opal_to_okta_map


def get_owner_ids_to_okta_groups_map(
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to move this and get_opal_groups_to_okta_groups_map to opal_okta.py?

return group


def get_all_groups(client: opal.api.GroupsApi) -> List[Dict[str, Any]]:
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we move this to opal_common.py? I'm thinking this file should pretty much only have the start_* and other orchestration functions.

return owner_ids_to_okta_groups_map


def cleanup(neo4j_session: neo4j.Session, common_job_parameters: Dict[str, Any]) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we move this to opal_aws.py?

{
"statements": [
{
"query": "MATCH (n:OpalResource) WHERE n.lastupdated <> $UPDATE_TAG WITH n LIMIT $LIMIT_SIZE DETACH DELETE n",
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use the OpalResource model that you created so that we can remove this manual cleanup job. To do this we can introduce a fake "tenant" like in this LastPass PR: https://github.com/cartography-cncf/cartography/pull/1083/files#diff-3b2215e87b2aaf55796fc63a223403d163b97d5bcbb6931d5886802a1f554cd8.

UNWIND $manual_approved_access AS access
MATCH (g:OktaGroup {id: access.okta_group_id})
MATCH (r:OpalResource {id: access.resource_id})
MERGE (g)-[rel:CAN_MANUALLY_APPROVE_ACCESS]->(r)
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment here about making this a rel schema defined on the OpalResource model and then using a read_transaction function to get a list of the IDs you need.

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.

2 participants