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

Only inline policies are considered, attached policies are ignored #33

Open
morganchristiansson opened this issue Jul 26, 2017 · 14 comments

Comments

@morganchristiansson
Copy link

morganchristiansson commented Jul 26, 2017

So we just tried to run aardvark and repokid on our roles but several of them had no suggested policies.

After debugging repokid for a while it seems like role.policies that is checked only contains inline policies. Attached policies are ignored.

Can attached policies be used as source aswell?

As a workaround we're copying all attached policies to inline policies.

@KorhanOzturk90

@morganchristiansson morganchristiansson changed the title Attached policies not considered - only inline Only inline policies are considered, attached policies are ignored Jul 26, 2017
@mcpeak
Copy link
Contributor

mcpeak commented Jul 31, 2017

Hey @morganchristiansson yeah, definitely. We haven't done it yet but it should be a fairly easy change. I'll mark this as an enhancement.

@laurajauch
Copy link

laurajauch commented May 24, 2018

Can we discuss the scope of this enhancement? This would add definite value to the product for my team and we're considering if we have the capacity to build it out because we're tired of waiting. :)

Here are a few of my initial questions/thoughts:

  1. Does this necessitate changes to Aardvark to collect/return data about managed policies? (By "changes" I mean waiting until the AA API is available.)
  2. CloudAux was recently updated to include functions around managed policies, so it seems that including them would be fairly straight-forward. It looks like we could store them in dynamo alongside inline policies, though with some indication that they are managed (probably add a boolean) and with the number of attached entities.
  3. For initial implementation, I think it's reasonable to alert on all 'repo-able' permissions but only enable repoing on those managed policies that have exactly one attached entity. It gets more complex when a managed policy is shared among roles.

Thoughts? I'm still familiarizing myself with the project, so there may be elements I've missed.

@mcpeak
Copy link
Contributor

mcpeak commented May 24, 2018

Hey, thanks for the interest in taking this up!

  1. I believe Aardvark / AA returns data about any services that are allowed in policy. Whether they are in a managed policy or inline shouldn't matter. This is nice because Aardvark changes are painful :)

  2. We could store them alongside with inline policies (with a flag as you suggest) or we can create another field in Dynamo for managed policies. Either seems fine to me.

  3. Agreed about complexity of repoing a managed policy shared among roles. We probably want to check whether the policy is attached to only one role in get_repoable_permissions. That function takes a list of permissions, maybe we can add some data about whether they're in a managed policy and if so what the name of the policy is (so we can check).

We'll also want to add a flag to enable/disable this feature, probably in update_role_cache. If the flag isn't passed then update_role_cache won't even list the permissions from managed policies.

@premature-optimization
Copy link

So, looks like this is fairly stale, but I'm gonna jump in to add support for non-inline policies as I intend to use Aardvark/RepoKid to clean up an IAM setup at my current position.

So far, I just added a quick print command to the update_role_data definition in repokid/utils/roledata.py and can see all of the non-inline policy data, so RepoKid already has the data in the program, I just need to figure out how to differentiate the two and add a flag as indicated above.

I'll keep updating as I go!

@mcpeak
Copy link
Contributor

mcpeak commented Aug 15, 2019

@premature-optimization thank you! Please let me know if I can help. I'm happy to jump on a call, bounce ideas, or anything else useful.

@premature-optimization
Copy link

@mcpeak That might be super useful! I'm in the networktocode Slack workspace as unironicGUIfan if you want to asynchronously help me out (I work strange hours due to sleep disorders)

Basically, it looks like all of the permissions of non-inline policies still show up in display_role under Policy history, but I can't seem to figure out how it's deciding not to include that policy information in display_role_cache. Once we can figure out that distinction, should be easy enough to add a flag to those permissions

@premature-optimization
Copy link

So all of the policy data (including managed policies) is in the functions up to get_role_data, which pulls directly from the dynamo tables. After seeing the full dict for the roles it returns, only the inline policies are included. So I'm working on hunting down what's in charge of writing to the dynamo table to see if I can include the managed policy information as well.

@premature-optimization
Copy link

@mcpeak @curtis-turner
Added you both as collaborators to my fork, where I'm posting my debugging/code changes in order to collaborate.

ATM, I got as far as including the additional get_role_managed_policies function to update_role_data and should add the policies along with the inline policies to the current_policies dict (to avoid renaming all variable calls), but looks like it's still not getting the managed policy information correctly.

Right now, I'd imagine that the get_role_managed_policies call is unhappy with the format of the request, or the reply is in a different format than the inline function and it doesn't want to merge the two happily.

Feel free to commit/branch whatever you like in that repo, please be sure not to open a PR against master until we've completed troubleshooting and testing :)

I'll look into this in a couple days, but swamped with other work atm so I appreciate any assistance!

@mcpeak
Copy link
Contributor

mcpeak commented Aug 22, 2019 via email

@mfuellbier
Copy link

What's the status on this one? Are you currently working on it? I might have some time end of the month to take a look into it, if there is nobody working on it.

@mcpeak
Copy link
Contributor

mcpeak commented Oct 10, 2019

I don't think anybody is working on it, despite lots of interest.

@steve-heslouin
Copy link

we would be happy to help testing if needed

@chimeworld
Copy link

I’d like to work on this, but I need a little help getting started.

@patricksanders
Copy link
Collaborator

Repokid has gone through some refactoring, so here's some updated info on how this implementation could go.

This is based on the approach of detaching a managed policy from a role iff none of the permissions in the policy were used by the principal in the evaluation window. I've broken this down into two main chunks that could be implemented in serial.

Retrieve and store managed policies

repokid.datasource.iam.IAMDatasource._fetch()

  • Update get_role() call with managed policy flag:
role_info: IAMEntry = get_role(role, flags=FLAGS.INLINE_POLICIES | FLAGS.MANAGED_POLICIES, **conn)

repokid.role.Role.gather_role_data()

  • Pass iam_data['ManagedPolicyList'] to self.add_policy_version() call

repokid.role.Role.add_policy_version()

  • Update to support optional managed_policies kwarg
  • Store as self.managed_policies: List[List[managed_policies]]

Updated schema for self.policies with new ManagedPolicies key:

{
    "Source": "Scan|Repo",
    "Discovered": datetime,
    "Policy": {
        ...
    },
    "ManagedPolicies": [
        managed_policy_1,
        managed_policy_2,
        ...
        managed_policy_n,
    ]
}

Update permissions calculations

repokid.role.Role.get_permissions_for_policy_version()

  • Add a call (or calls) to get permissions allowed by all managed policies in self.policies[selection]["ManagedPolicies"] (Note: make sure this safely accesses ManagedPolicies since it won't be there for roles scanned before this change)
  • You may be able to reuse repokid.utils.permissions.get_permissions_in_policy() for this
  • Combine permissions for inline and managed policies

repokid.role.Role._caculate_no_repo_permissions()

  • Update to also analyze managed policies
  • May require updates to repokid.utils.permissions.find_newly_added_permissions()

repokid.role.Role.get_repoed_policy()

  • Update to determine which managed policies can be detached

repokid.role.Role.repo()

  • Update to detach managed policies that are unused (as determined by Role.get_repoed_policy())

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

No branches or pull requests

8 participants