Giter Club home page Giter Club logo

repokid's Introduction

Repokid

NetflixOSS Lifecycle Build Status PyPI version Coverage Status Discord chat

Repokid Logo

Repokid uses Access Advisor provided by Aardvark to remove permissions granting access to unused services from the inline policies of IAM roles in an AWS account.

Getting Started

Install

mkvirtualenv repokid
git clone [email protected]:Netflix/repokid.git
cd repokid
pip install -e .
repokid config config.json

DynamoDB

You will need a DynamoDB table called repokid_roles (specify account and endpoint in dynamo_db in config file).

The table should have the following properties:

  • RoleId (string) as a primary partition key, no primary sort key
  • A global secondary index named Account with a primary partition key of Account and RoleId and Account as projected attributes
  • A global secondary index named RoleName with a primary partition key of RoleName and RoleId and RoleName as projected attributes

For development, you can run dynamo locally.

To run locally:

docker-compose up

The endpoint for DynamoDB will be http://localhost:8000. A DynamoDB admin panel can be found at http://localhost:8001.

If you run the development version the table and index will be created for you automatically.

IAM Permissions

Repokid needs an IAM Role in each account that will be queried. Additionally, Repokid needs to be launched with a role or user which can sts:AssumeRole into the different account roles.

RepokidInstanceProfile:

  • Only create one.
  • Needs the ability to call sts:AssumeRole into all of the RepokidRoles.
  • DynamoDB permissions for the repokid_roles table and all indexes (specified in assume_role subsection of dynamo_db in config) and the ability to run dynamodb:ListTables

RepokidRole:

  • Must exist in every account to be managed by repokid.
  • Must have a trust policy allowing RepokidInstanceProfile.
  • Name must be specified in connection_iam in config file.
  • Has these permissions:
{
 "Version": "2012-10-17",
 "Statement": [
   {
     "Action": [
       "iam:DeleteInstanceProfile",
       "iam:DeleteRole",
       "iam:DeleteRolePolicy",
       "iam:GetAccountAuthorizationDetails",
       "iam:GetInstanceProfile",
       "iam:GetRole",
       "iam:GetRolePolicy",
       "iam:ListInstanceProfiles",
       "iam:ListInstanceProfilesForRole",
       "iam:ListRolePolicies",
       "iam:PutRolePolicy",
       "iam:UpdateRoleDescription"
     ],
     "Effect": "Allow",
     "Resource": "*"
   }
 ]
}

So if you are monitoring n accounts, you will always need n+1 roles. (n RepokidRoles and 1 RepokidInstanceProfile).

Editing config.json

Running repokid config config.json creates a file that you will need to edit. Find and update these fields:

  • dynamodb: If using dynamo locally, set the endpoint to http://localhost:8010. If using AWS hosted dynamo, set the region, assume_role, and account_number.
  • aardvark_api_location: The location to your Aardvark REST API. Something like https://aardvark.yourcompany.net/api/1/advisors
  • connection_iam: Set assume_role to RepokidRole, or whatever you have called it.

Optional Config

Repokid uses filters to decide which roles are candidates to be repoed. Filters may be configured to suit your environment as described below.

Blocklist Filter

Roles may be excluded by adding them to the Blocklist filter. One common reason to exclude a role is if the corresponding workload performs occasional actions that may not have been observed but are known to be required. There are two ways to exclude a role:

  • Exclude role name for all accounts: add it to a list in the config filter_config.BlocklistFilter.all
  • Exclude role name for specific account: add it to a list in the config filter_config.BlocklistFilter.<ACCOUNT_NUMBER>

Blocklists can also be maintained in an S3 blocklist file. They should be in the following form:

{
  "arns": ["arn1", "arn2"],
  "names": {"role_name_1": ["all", "account_number_1"], "role_name_2": ["account_number_2", "account_number_3"]}
}

Exclusive Filter

If you prefer to repo only certain roles you can use the Exclusive Filter. Maybe you want to consider only roles used in production or by certain teams. To select roles for repo-ing you may list their names in the configuration files. Shell style glob patterns are also supported. Role selection can be specified per individual account or globally. To activate this filter put "repokid.filters.exclusive:ExclusiveFilter"in the section active_filters of the config file. To configure it you can start with the autogenerated config file, which has an example config in the "filter_config" section:

"ExclusiveFilter": {
                   "all": [
                     "<GLOB_PATTERN>"
                     ],
                   "<ACCOUNT_NUMBER>": [
                     "<GLOB_PATTERN>"
                    ]
                   }

Age Filter

By default the age filter excludes roles that are younger than 90 days. To change this edit the config setting: filter_config.AgeFilter.minimum_age.

Active Filters

New filters can be created to support internal logic. At Netflix we have several that are specific to our use cases. To make them active make sure they are in the Python path and add them in the config to the list in the section active_filters.

Extending Repokid

Hooks

Repokid is extensible via hooks that are called before, during, and after various operations as listed below.

Hook name Context
AFTER_REPO role, errors
AFTER_REPO_ROLES roles, errors
BEFORE_REPO_ROLES account_number, roles
AFTER_SCHEDULE_REPO roles
DURING_REPOABLE_CALCULATION role_id, arn, account_number, role_name, potentially_repoable_permissions, minimum_age
DURING_REPOABLE_CALCULATION_BATCH role_batch, potentially_repoable_permissions, minimum_age

Hooks must adhere to the following interface:

from repokid.hooks import implements_hook
from repokid.types import RepokidHookInput, RepokidHookOutput

@implements_hook("TARGET_HOOK_NAME", 1)
def custom_hook(input_dict: RepokidHookInput) -> RepokidHookOutput:
    """Hook functions are called with a dict containing the keys listed above based on the target hook.
    Any mutations made to the input and returned in the output will be passed on to subsequent hook funtions.
    """
    ...

Examples of hook implementations can be found in repokid.hooks.loggers.

Filters

Custom filters can be written to exclude roles from being repoed. Filters must adhere to the following interface:

from repokid.filters import Filter
from repokid.types import RepokidFilterConfig
from repokid.role import RoleList


class CustomFilterName(Filter):
    def __init__(self, config: RepokidFilterConfig = None) -> None:
        """Filters are initialized with a dict containing the contents of `filter_config.FilterName`
        from the config file. This example would be initialized with `filter_config.CustomFilterName`.
        The configuration can be accessed via `self.config`

        If you don't need any custom initialization logic, you can leave this function out of your
        filter class.
        """
        super().__init__(config=config)
        # custom initialization logic goes here
        ...

    def apply(self, input_list: RoleList) -> RoleList:
        """Determine roles to be excluded and return them as a RoleList"""
        ...

A simple filter implementation can be found in repokid.filters.age. A more complex example is in repokid.blocklist.age.

How to Use

Once Repokid is configured, use it as follows:

Standard flow

  • Update role cache: repokid update_role_cache <ACCOUNT_NUMBER>
  • Display role cache: repokid display_role_cache <ACCOUNT_NUMBER>
  • Display information about a specific role: repokid display_role <ACCOUNT_NUMBER> <ROLE_NAME>
  • Repo a specific role: repokid repo_role <ACCOUNT_NUMBER> <ROLE_NAME>
  • Repo all roles in an account: repokid repo_all_roles <ACCOUNT_NUMBER> -c

Scheduling

Rather than running a repo right now you can schedule one (schedule_repo command). The duration between scheduling and eligibility is configurable, but by default roles can be repoed 7 days after scheduling. You can then run a command repo_scheduled_roles to only repo roles which have already been scheduled.

Targeting a specific permission

Say that you find a given permission especially dangerous in your environment. Here I'll use s3:PutObjectACL as an example. You can use Repokid to find all roles that have this permission (even those hidden in a wildcard), and then remove just that single permission.

Find & Remove:

  • Ensure the role cache is updated before beginning.
  • Find roles with a given permission: repokid find_roles_with_permissions <permission>... [--output=ROLE_FILE]
  • Remove permission from roles: repokid remove_permissions_from_roles --role-file=ROLE_FILE <permission>... [-c]

Example:

$ repokid find_roles_with_permissions "s3:putobjectacl" "sts:assumerole" --output=myroles.json
...
$ repokid remove_permissions_from_roles --role-file=myroles.json "s3:putobjectacl" "sts:assumerole" -c

Rolling back

Repokid stores a copy of each version of inline policies it knows about. These are added when a different version of a policy is found during update_role_cache and any time a repo action occurs. To restore a previous version run:

See all versions of roles: repokid rollback_role <ACCOUNT_NUMBER> <ROLE_NAME> Restore a specific version: repokid rollback_role <ACCOUNT_NUMBER> <ROLE_NAME> --selection=<NUMBER> -c

Stats

Repokid keeps counts of the total permissions for each role. Stats are added any time an update_role_cache or repo_role action occur. To output all stats to a CSV file run: repokid repo_stats <OUTPUT_FILENAME>. An optional account number can be specified to output stats for a specific account only.

Library

New in v0.14.2

Repokid can be called as a library using the repokid.lib module:

from repokid.lib import display_role, repo_role, update_role_cache

account_number = "123456789012"

display_role(account_number, "superCoolRoleName")
update_role_cache(account_number)
repo_role(account_number, "superCoolRoleName", commit=True)

Dispatcher

Repokid Dispatcher is designed to listen for messages on a queue and perform actions. So far the actions are:

  • List repoable services from a role
  • Set or remove an opt-out
  • List and perform rollbacks for a role

Repokid will respond on a configurable SNS topic with information about any success or failures. The Dispatcher component exists to help with operationalization of the repo lifecycle across your organization. You may choose to expose the queue directly to developers, but more likely this should be guarded because rolling back can be a destructive action if not done carefully.

Development

Releasing

Versioning is handled by setupmeta. To create a new release:

python setup.py version --bump patch --push

# Inspect output and make sure it's what you expect
# If all is well, commit and push the new tag:
python setup.py version --bump patch --push --commit

repokid's People

Contributors

adamdecaf avatar castrapel avatar dependabot[bot] avatar doppins-bot avatar guilhermesenazuza avatar johnvonneumann avatar mbaciu-gpsw avatar mcpeak avatar mikegrima avatar patricksanders avatar rmtzcx avatar scriptsrc avatar sghill avatar sid77 avatar suprithcs avatar tomdev avatar willbengtson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

repokid's Issues

ARN not found in Access Advisor

Hi
I've deployed Aardvark and Repokid to a single EC2 instance.
Aaardvark updates ok from a target account and I can see the expected data in two tables in the Aardvark DB.
Repokid updates and displays its cache successfully from the Aardvarl api.

However when I try and display a single role or repo a role (any role) I get "WARNING: ARN not found in Access Advisor"

[root@ip-10-0-10-244 bin]#
[root@ip-10-0-10-244 bin]# ./repokid update_role_cache 123456789000
Loaded config from /usr/local/bin/config.json
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): sts.amazonaws.com
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): dynamodb.eu-west-1.amazonaws.com
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): sts.amazonaws.com
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): iam.amazonaws.com
2018-02-15 09:31:56,558 INFO: Updating role data for account 123456789000 [in /root/gitrepo/repokid/repokid/cli/repokid_cli.py:403]
INFO:repokid:Updating role data for account 123456789000
38%|¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦? | 27/72 [00:07<00:12, 3.66it/s]INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (2): iam.amazonaws.com
100%|¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦| 72/72 [00:20<00:00, 3.47it/s]
2018-02-15 09:32:17,303 INFO: Finding inactive accounts [in /root/gitrepo/repokid/repokid/cli/repokid_cli.py:410]
INFO:repokid:Finding inactive accounts
2018-02-15 09:32:17,328 INFO: Filtering roles [in /root/gitrepo/repokid/repokid/cli/repokid_cli.py:413]
INFO:repokid:Filtering roles
2018-02-15 09:32:17,331 INFO: Loaded plugin repokid.filters.age:AgeFilter [in /root/gitrepo/repokid/repokid/cli/repokid_cli.py:360]
INFO:repokid:Loaded plugin repokid.filters.age:AgeFilter
2018-02-15 09:32:17,332 INFO: Loaded plugin repokid.filters.lambda:LambdaFilter [in /root/gitrepo/repokid/repokid/cli/repokid_cli.py:360]
INFO:repokid:Loaded plugin repokid.filters.lambda:LambdaFilter
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): sts.amazonaws.com
2018-02-15 09:32:17,729 ERROR: S3 blacklist config was set but unable to connect retrieve object, quitting [in /root/gitrepo/repokid/repokid/filters/blacklist/init.py:24]
ERROR:repokid:S3 blacklist config was set but unable to connect retrieve object, quitting

[root@ip-10-0-10-244 bin]# ./repokid display_role_cache 123456789000
Loaded config from /usr/local/bin/config.json
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): sts.amazonaws.com
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): dynamodb.eu-west-1.amazonaws.com
100%|¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦| 73/73 [00:00<00:00, 203.17it/s]

[root@ip-10-0-10-244 bin]# ./repokid display_role 123456789000 RepokidTest
Loaded config from /usr/local/bin/config.json
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): sts.amazonaws.com
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): dynamodb.eu-west-1.amazonaws.com

Role repo data:
Name Refreshed Disqualified By Can be repoed Permissions Repoable Repoed Services


RepokidTest 2018-02-15T09:40:33.653533 [] True 0 0 Never 0

Policy history:
Number Source Discovered Permissions Services


   0  Scan      2018-02-14T15:59:56.471492              2  [u's3']

Stats:
Date Event Type Permissions Count Disqualified By


2018-02-15 09:41:39,767 WARNING: ARN not found in Access Advisor: arn:aws:iam::123456789000:role/RepokidTest [in /root/gitrepo/repokid/repokid/cli/repokid_cli.py:576]
WARNING:repokid:ARN not found in Access Advisor: arn:aws:iam::123456789000:role/RepokidTest

[root@ip-10-0-10-244 bin]# ./repokid repo_role 123456789000 RepokidTest
Loaded config from /usr/local/bin/config.json
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): 169.254.169.254
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): sts.amazonaws.com
INFO:botocore.vendored.requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): dynamodb.eu-west-1.amazonaws.com
2018-02-15 09:42:16,874 WARNING: ARN not found in Access Advisor: None [in /root/gitrepo/repokid/repokid/cli/repokid_cli.py:668]
WARNING:repokid:ARN not found in Access Advisor: None
[root@ip-10-0-10-244 bin]#

I deployed Repokid to an alternative instance and connected back to the Aardvark api successfully but still have the same issue with role display and repo.

Any ideas?

Thanks

The table does not have the specified index: RoleName

Environment

(venv) ubuntu@***************:/usr/local/src/repokid$ python --version
Python 2.7.12
(venv) ubuntu@***************:/usr/local/src/repokid$ cat /etc/issue
Ubuntu 16.04.2 LTS \n \l

(venv) ubuntu@***************:/usr/local/src/repokid$ git show
commit 9dc9403b6659f97ba24adaf44413bb1d92e01a30
Author: Travis McPeak <[email protected]>
Date:   Mon Nov 20 10:40:44 2017 -0800

    Change Dispatcher to show perm count

diff --git a/repokid/dispatcher/__init__.py b/repokid/dispatcher/__init__.py
index 89459f9..6321dce 100644
--- a/repokid/dispatcher/__init__.py
+++ b/repokid/dispatcher/__init__.py
@@ -5,6 +5,7 @@ import time
 from repokid import CONFIG
 import repokid.cli.repokid_cli as cli
 import repokid.utils.dynamo as dynamo
+import repokid.utils.roledata as roledata

 ResponderReturn = namedtuple('ResponderReturn', 'successful, return_message')

@@ -45,7 +46,8 @@ def list_role_rollbacks(dynamo_table, message):
         role_data = dynamo.get_role_data(dynamo_table, role_id, fields=['Policies'])
         return_val = 'Restorable versions for role {} in account {}\n'.format(message.role_name, message.account)
         for index, policy_version in enumerate(role_data['Policies']):
-            return_val += '({:>3}):  {:<5}     {:<15}  {}\n'.format(index, len(str(policy_version['Policy'])),
+            policy_permissions = roledata._get_permissions_in_policy(policy_version['Policy'])
+            return_val += '({:>3}):  {:<5}     {:<15}  {}\n'.format(index, len(policy_permissions),
                                                                     policy_version['Discovered'],
                                                                     policy_version['Source'])
         return ResponderReturn(successful=True, return_message=return_val)

When running repokid display_role, I always get the following error message:

ubuntu@***************:/usr/local/src/repokid$ repokid display_role <account_id> <role_name>
Loaded config from /usr/local/src/repokid/config.json
Traceback (most recent call last):
  File "/usr/local/src/repokid/venv/bin/repokid", line 11, in <module>
    load_entry_point('repokid', 'console_scripts', 'repokid')()
  File "/usr/local/src/repokid/repokid/cli/repokid_cli.py", line 964, in main
    return display_role(account_number, role_name, dynamo_table, config, hooks)
  File "/usr/local/src/repokid/repokid/cli/repokid_cli.py", line 533, in display_role
    role_id = find_role_in_cache(dynamo_table, account_number, role_name)
  File "/usr/local/src/repokid/repokid/utils/dynamo.py", line 143, in find_role_in_cache
    ExpressionAttributeValues={':rn': role_name})
  File "/usr/local/src/repokid/venv/lib/python2.7/site-packages/boto3-1.4.4-py2.7.egg/boto3/resources/factory.py", line 520, in do_action
    response = action(self, *args, **kwargs)
  File "/usr/local/src/repokid/venv/lib/python2.7/site-packages/boto3-1.4.4-py2.7.egg/boto3/resources/action.py", line 83, in __call__
    response = getattr(parent.meta.client, operation_name)(**params)
  File "/usr/local/src/repokid/venv/lib/python2.7/site-packages/botocore-1.5.92-py2.7.egg/botocore/client.py", line 310, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/usr/local/src/repokid/venv/lib/python2.7/site-packages/botocore-1.5.92-py2.7.egg/botocore/client.py", line 599, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the Query operation: The table does not have the specified index: RoleName

Unfortunately, I can't find the index RoleName in the documentation. Does the index still have to be added to the documentation?

Validate all docstrings

The docstrings for functions may have drifted. Would be nice to read through all the function docstrings and make sure the arguments are correct and the descriptions are clear.

Not showing permissions for most roles

When I do

repokid display_role_cache 1234567890

I have several roles but most are showing 0 permissions including AardvarkRepokid (two roles show some permissions one has 5 and another OrganizationAccountAccessRole has 5110)

When I do

repokid find_roles_with_permissions "sts:assumerole" --output=myroles.json
Loaded config from /srv/dev/repokid-master/config.json
2019-07-04 08:34:24,931 INFO: ARN arn:aws:iam::01234567890:role/OrganizationAccountAccessRole has ['sts:assumerole'] [in /srv/dev/repokid-master/repokid/cli/repokid_cli.py:518]
INFO:repokid:ARN arn:aws:iam::01234567890:role/OrganizationAccountAccessRole has ['sts:assumerole']

It only shows one role OrganizationAccountAccessRole with sts:assumerole

When I do
curl localhost:5000/api/1/advisors?phrase=AardvarkRepokid

It returns

{"lastAuthenticated":1562226360000,"lastAuthenticatedEntity":"arn:aws:iam::01234567890:role/AardvarkRepokid","lastUpdated":"Thu, 04 Jul 2019 08:31:17 GMT","serviceName":"AWS Security Token Service","serviceNamespace":"sts","totalAuthenticatedEntities":1}],"arn:aws:iam::01234567890:role/AardvarkRepokid":

And when I do it via AWS Access Advisor API

aws iam generate-service-last-accessed-details --arn arn:aws:iam::1234567890:role/AardvarkRepoKid

aws iam get-service-last-accessed-details --job-id 20b5dded-9aaa-0a64-038b-8f35b330fdf6 >> Aardvark.json

{
"LastAuthenticated": "2019-07-03T07:21:00Z",
"LastAuthenticatedEntity": "arn:aws:iam::01234567890:role/AardvarkRepokid",
"ServiceNamespace": "sts",
"ServiceName": "AWS Security Token Service",
"TotalAuthenticatedEntities": 1
}

Why is repokid not processing the information correctly from aardvark?

ARN not found issue

(repokid)[ec2-user@ip-172-31-42-155 repokid]$ repokid repo_role [HiddenAccount] AwsSecurityAudit
Loaded config from /home/ec2-user/repokid/config.json
2017-06-19 11:45:12,079 WARNING: ARN not found in Access Advisor: arn:aws:iam::[HiddenAccount]:role/AwsSecurityAudit [in /home/ec2-user/repokid/repokid/repokid.py:571]

Repo-ing a role "would not" repo

I have the correct permissions in place, but when I repo a role I have an information that repokid would do it, but in fact it would not :)

(repokid)[ec2-user@ip-172-31-42-155 repokid]$ repokid repo_role 840221307699 GatedGardenAudit Loaded config from /home/ec2-user/repokid/config.json 2017-06-23 09:00:08,024 INFO: Would delete policy from GatedGardenAudit with name GatedGardenPolicy [in /home/ec2-user/repokid/repokid/repokid.py:595]

Logs of repokid show no information, nor in cloudtrail logs.

"LoggerAdapter" object has no attribute "warn"

Hello,

after installing repokid as described in the README.md, I encounter the following error when invoking repokid update_role_cache xxxx where xxxx is an Account Number:

2019-09-11 09:17:54,039 INFO: Calculating repoable permissions and services for account xxxx [in /home/ec2-user/repokid/repokid/cli/repokid_cli.py:482]
Calculating repoable permissions and services for account xxxx
Traceback (most recent call last):
  File "/home/ec2-user/repokid/venv/bin/repokid", line 11, in <module>
    load_entry_point('repokid', 'console_scripts', 'repokid')()
  File "/home/ec2-user/repokid/repokid/cli/repokid_cli.py", line 1594, in main
    return update_role_cache(account_number, dynamo_table, config, hooks)
  File "/home/ec2-user/repokid/repokid/cli/repokid_cli.py", line 493, in update_role_cache
    batch_size,
  File "/home/ec2-user/repokid/repokid/utils/roledata.py", line 353, in _calculate_repo_scores
    hooks,
  File "/home/ec2-user/repokid/repokid/utils/roledata.py", line 581, in _get_repoable_permissions
    minimum_age,
  File "/home/ec2-user/repokid/repokid/utils/roledata.py", line 534, in _get_potentially_repoable_permissions
    LOGGER.warn("skipping {}".format(permission_name))
AttributeError: 'LoggerAdapter' object has no attribute 'warn'

I "fixed" this issue by replacing LOGGER.warn by LOGGER.error in repokid/utils/roledata.py in lines 528 and 534.

Support Sid based exclusion

We could use Sid's with a certain prefix (something like RKIGNORE) to exclude statements from repoing. This would allow us to preserve some parts of an inline policy without excluding the entire role from repo.

In order to support this we need to:

  • create a new option in config: something like sid_ignore_prefix
  • add the sid_ignore_prefix check in the right places. We still want to see these statements and store them for rolling back and searching perms but we want to exclude permissions that are included in these statements when making policy suggestions and performing repo.

Some functions that are going to need to change:

  • _get_repoed_policy, _get_role_permissions, _get_permissions_in_policy

This is a decent amount of work so we're going to want to make sure we're rock solid here by adding tests, etc. Finally we'll need to update the documentation to describe this new option.

docutils version issue

I installed repokid on AWS Linux2 with python 3.7.5 (also tried 3.6.6), but got below error when ran python setup.py develop


Installed /home/ec2-user/virtualenvs/repokid/lib/python3.7/site-packages/python_dateutil-2.8.1-py3.7.egg
error: docutils 0.16rc1 is installed but docutils<0.16,>=0.10 is required by {'botocore'}


I revert the commit back to 7f67f55, and the problem went away. Any idea?

repokid not finding modules attributes on release 0.14.0

Summary

Repokid is not running on version 0.14.0

it is failing with the following output:

Loaded config from /tmp/repokid/config.json
Traceback (most recent call last):
  File "/usr/lib64/python3.8/logging/config.py", line 93, in _resolve
    found = getattr(found, n)
AttributeError: module 'repokid.utils' has no attribute 'logging'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib64/python3.8/logging/config.py", line 542, in configure
    formatters[name] = self.configure_formatter(
  File "/usr/lib64/python3.8/logging/config.py", line 674, in configure_formatter
    c = _resolve(cname)
  File "/usr/lib64/python3.8/logging/config.py", line 95, in _resolve
    __import__(used)
  File "/tmp/repokid/repokid/utils/logging.py", line 20, in <module>
    from repokid import LOGGER
ImportError: cannot import name 'LOGGER' from partially initialized module 'repokid' (most likely due to a circular import) (/tmp/repokid/repokid/__init__.py)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/tmp/repokid/venv/bin/repokid", line 11, in <module>
    load_entry_point('repokid', 'console_scripts', 'repokid')()
  File "/tmp/repokid/venv/lib64/python3.8/site-packages/pkg_resources/__init__.py", line 489, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/tmp/repokid/venv/lib64/python3.8/site-packages/pkg_resources/__init__.py", line 2852, in load_entry_point
    return ep.load()
  File "/tmp/repokid/venv/lib64/python3.8/site-packages/pkg_resources/__init__.py", line 2443, in load
    return self.resolve()
  File "/tmp/repokid/venv/lib64/python3.8/site-packages/pkg_resources/__init__.py", line 2449, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/tmp/repokid/repokid/__init__.py", line 119, in <module>
    LOGGER = init_logging()
  File "/tmp/repokid/repokid/__init__.py", line 66, in init_logging
    logging.config.dictConfig(CONFIG["logging"])
  File "/usr/lib64/python3.8/logging/config.py", line 808, in dictConfig
    dictConfigClass(config).configure()
  File "/usr/lib64/python3.8/logging/config.py", line 545, in configure
    raise ValueError('Unable to configure '
ValueError: Unable to configure formatter 'json'

How to reproduce

I followed the instructions below in Fedora 32/Python 3.8.3 and AmazonLinux2/Python 3.7.6

Clone code

git clone https://github.com/Netflix/repokid.git

Create virtual environment and activate it

cd repokid
python3 -m venv venv
source venv/bin/activate

Install and configure repokid

pip install -e .
repokid config config.json

Repokid is not even able to show the version

repokid --version

Confirm previous release is working

Previous version is 0.13.0 and just one commit back

git log --oneline

Output from command above:

4ba6d54 (HEAD -> master, tag: 0.14.0, origin/master, origin/HEAD) Refactor CLI calls into repokid.commands module (#255)
7852827 (tag: 0.13.0) Unpin Marshmallow requirement (#254)

Checkout former commit

git checkout 0.14.0~

Downgrade repokid

pip install -e .

Confirm it is able to run

repokid --version

Output from command above:

Loaded config from /tmp/repokid/config.json
Repokid 0.13.0

permission shown for all roles

I installed and configured aardvark and repokid on the same VM and they ran successfully without error. However when I ran 'repokid display_role_cache 1234567', it came back with 0 permission for all roles.

I just pick a specific role pei-test for exam and below are some troubleshooting steps I did:

  1. curl localhost:5000/api/1/advisors?arn=arn:aws:iam::12344567:role/pei-test
    {"arn:aws:iam::1234567:role/pei-test":[{"lastAuthenticated":0,"lastAuthenticatedEntity":null,"lastUpdated":"Sat, 11 Jan 2020 21:28:22 GMT","serviceName":"Amazon Elastic Container Service for Kubernetes","serviceNamespace":"eks","totalAuthenticatedEntities":0}],"count":1,"page":1,"total":1}

  2. repokid find_roles_with_permissions "eks:ListFargateProfiles"
    Loaded config from /opt/src/repokid/config.json
    2020-01-11 21:34:35,252 INFO: ARN arn:aws:iam::1234567:role/pei-test has ['eks:listfargateprofiles'] [in /opt/src/repokid/repokid/cli/repokid_cli.py:604]
    ARN arn:aws:iam::1234567:role/pei-test has ['eks:listfargateprofiles']

It seems the permission of eks:listfargateprofiles is in the role pei-test, I don't understand why it does not show up in repokid display_role_cache?

best,

pei

Repokid should provide the ability to remove a specified permission.

Similar to the repokid find_roles_with_permission <permission> call, repokid should support a new command line function to repo a certain permission across all roles.

repokid remove_unused_permission <permission>

This would be dependent on #1 as it would require CloudTrail data.

Suggestion: Continue to cut releases instead of pulling from master branch

It would be great if Repokid and Aardvark continued to have regular releases. Recently ran into an issue where my Terraform module for Repokid and Aardvark broke because of the updates to Python3 from Python2.7 (not production, so all good). If I could have pulled from a release tag instead of the master branch, that situation could have been avoided. Just a suggestion.

FYI - @mcpeak

KeyError: 'DisqualifiedBy'

When running repokid update_role_cache , we get the following error:

Traceback (most recent call last):
File "/home/ec2-user/.virtualenvs/repokid/bin/repokid", line 11, in
load_entry_point('repokid', 'console_scripts', 'repokid')()
File "/home/ec2-user/repokid/repokid/cli/repokid_cli.py", line 953, in main
return update_role_cache(account_number, dynamo_table, config, hooks)
File "/home/ec2-user/repokid/repokid/cli/repokid_cli.py", line 408, in update_role_cache
roledata.update_role_data(dynamo_table, account_number, role, current_policies)
File "/home/ec2-user/repokid/repokid/utils/roledata.py", line 197, in update_role_data
current_role_data.pop('DisqualifiedBy')
KeyError: 'DisqualifiedBy'

Where should we look to start troubleshooting?

TypeError: 'NoneType' object does not support item assignment

Hi

I get the following error when trying to update role cache

repokid update_role_cache 1234567890

Loaded config from /srv/dev/repokid-master/config.json
2019-07-01 14:11:18,169 INFO: Getting current role data for account 1234567890 (this may take a while for large accounts) [in /srv/dev/repokid-master/repokid/cli/repokid_cli.py:380]
INFO:repokid:Getting current role data for account 1234567890 (this may take a while for large accounts)
2019-07-01 14:11:19,554 INFO: Updating role data for account 1234567890 [in /srv/dev/repokid-master/repokid/cli/repokid_cli.py:392]
INFO:repokid:Updating role data for account 1234567890
100%|████████████████████████████████████████████████████████████| 28/28 [00:01<00:00, 23.74it/s]
2019-07-01 14:11:20,735 INFO: Finding inactive roles in account 1234567890 [in /srv/dev/repokid-master/repokid/cli/repokid_cli.py:399]
INFO:repokid:Finding inactive roles in account 1234567890
2019-07-01 14:11:20,748 INFO: Filtering roles [in /srv/dev/repokid-master/repokid/cli/repokid_cli.py:402]
INFO:repokid:Filtering roles
Traceback (most recent call last):
File "/bin/repokid", line 9, in
load_entry_point('repokid==0.9.5', 'console_scripts', 'repokid')()
File "/srv/dev/repokid-master/repokid/cli/repokid_cli.py", line 1229, in main
return update_role_cache(account_number, dynamo_table, config, hooks)
File "/srv/dev/repokid-master/repokid/cli/repokid_cli.py", line 408, in update_role_cache
blocklist_filter_config['current_account'] = account_number
TypeError: 'NoneType' object does not support item assignment

Running on Python 2.7 as could not get it run on Python 3.6

Deploy Repokid from scratch and make sure instructions are clear

Repokid has been under heavy development the last several months and we should make sure the instructions are still clear. I'd like somebody unfamiliar with the project to run through the instructions in README.md to clear up any inconsistencies or enhance the documentation where appropriate.

Only inline policies are considered, attached policies are ignored

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

When running update_role_cache - cannot import name 'TableExistsWaiter' from 'mypy_boto3_dynamodb.paginator'

Loaded config from /root/aardvark/repokid/config.json
Traceback (most recent call last):
File "/root/aardvark/env/bin/repokid", line 11, in
load_entry_point('repokid', 'console_scripts', 'repokid')()
File "/root/aardvark/env/lib64/python3.7/site-packages/pkg_resources/init.py", line 490, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/root/aardvark/env/lib64/python3.7/site-packages/pkg_resources/init.py", line 2862, in load_entry_point
return ep.load()
File "/root/aardvark/env/lib64/python3.7/site-packages/pkg_resources/init.py", line 2462, in load
return self.resolve()
File "/root/aardvark/env/lib64/python3.7/site-packages/pkg_resources/init.py", line 2468, in resolve
module = import(self.module_name, fromlist=['name'], level=0)
File "/root/aardvark/repokid/repokid/cli/repokid_cli.py", line 24, in
from repokid.commands.repo import _repo_all_roles
File "/root/aardvark/repokid/repokid/commands/repo.py", line 31, in
from repokid.role import Role
File "/root/aardvark/repokid/repokid/role.py", line 55, in
from repokid.utils.dynamo import get_role_by_arn
File "/root/aardvark/repokid/repokid/utils/dynamo.py", line 15, in
from mypy_boto3_dynamodb.service_resource import Table
File "/root/aardvark/env/lib64/python3.7/site-packages/mypy_boto3_dynamodb/init.py", line 40, in
from .client import DynamoDBClient
File "/root/aardvark/env/lib64/python3.7/site-packages/mypy_boto3_dynamodb/client.py", line 34, in
from .paginator import (
ImportError: cannot import name 'TableExistsWaiter' from 'mypy_boto3_dynamodb.paginator' (/root/aardvark/env/lib64/python3.7/site-packages/mypy_boto3_dynamodb/paginator.py)

repokid.filters.optout.OptOutFilter cause IndexError: list index out of range

Environment:

(venv) ubuntu@********:/usr/local/src/repokid$ python --version
Python 2.7.12
(venv) ubuntu@********:/usr/local/src/repokid$ cat /etc/issue
Ubuntu 16.04.2 LTS \n \l
(venv) ubuntu@********:/usr/local/src/repokid$ git show
commit 40992a0e623ad13c883b171feace68476cd8ec5e
Author: Travis McPeak <[email protected]>
Date:   Wed Aug 2 14:47:40 2017 -0700

    Last commit missed a bug, this fixes it

diff --git a/repokid/utils/dynamo.py b/repokid/utils/dynamo.py
index 4d5985a..ea93223 100644
--- a/repokid/utils/dynamo.py
+++ b/repokid/utils/dynamo.py
@@ -120,7 +120,7 @@ def find_role_in_cache(dynamo_table, account_number, role_name):
         string: RoleID for active role with name in given account, else None
     """
     for roleID in role_ids_for_account(dynamo_table, account_number):
-        role_data = get_role_data(dynamo_table, roleID, fields=['RoleName', 'Active'])
+        role_data = get_role_data(dynamo_table, roleID, fields=['RoleName', 'Active', 'RoleId'])
         if role_data['RoleName'].lower() == role_name.lower() and role_data['Active']:
             return role_data['RoleId']

I always get the error message "IndexError: list index out of range" when the filter "repokid.filters.optout.OptOutFilter" is activated:

(venv) ubuntu@********:/usr/local/src/repokid$ repokid update_role_cache <account_id>
Loaded config from /usr/local/src/repokid/config.json
2017-08-08 03:59:26,027 INFO: Updating role data for account <account_id> [in /usr/local/src/repokid/repokid/cli/repokid_cli.py:265]
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 23/23 [00:06<00:00,  3.89it/s]
2017-08-08 03:59:32,731 INFO: Finding inactive accounts [in /usr/local/src/repokid/repokid/cli/repokid_cli.py:272]
2017-08-08 03:59:32,744 INFO: Filtering roles [in /usr/local/src/repokid/repokid/cli/repokid_cli.py:275]
2017-08-08 03:59:32,744 INFO: Loaded plugin repokid.filters.age:AgeFilter [in /usr/local/src/repokid/repokid/cli/repokid_cli.py:222]
2017-08-08 03:59:32,745 INFO: Loaded plugin repokid.filters.lambda:LambdaFilter [in /usr/local/src/repokid/repokid/cli/repokid_cli.py:222]
2017-08-08 03:59:32,745 INFO: Loaded plugin repokid.filters.blacklist:BlacklistFilter [in /usr/local/src/repokid/repokid/cli/repokid_cli.py:222]
Traceback (most recent call last):
  File "/usr/local/src/repokid/venv/bin/repokid", line 11, in <module>
    load_entry_point('repokid', 'console_scripts', 'repokid')()
  File "/usr/local/src/repokid/repokid/cli/repokid_cli.py", line 770, in main
    return update_role_cache(account_number, dynamo_table, config)
  File "/usr/local/src/repokid/repokid/cli/repokid_cli.py", line 282, in update_role_cache
    plugin_name = plugin_path.split(':')[1]
IndexError: list index out of range

If I remove the "repokid.filters.optout.OptOutFilter" from the active_filters, everything works well.

    "active_filters": [
        "repokid.filters.age:AgeFilter",
        "repokid.filters.lambda:LambdaFilter",
        "repokid.filters.blacklist:BlacklistFilter",
        "repokid.filters.optout.OptOutFilter"
    ],

Add Flake8 to TravisCI

It would be nice to have TravisCI check flake8 for the project. We can ignore the finding about lines longer than 80 (line length limit should be 120).

Test coverage for Dynamo

We need to increase test coverage for the Dynamo module. I'm thinking either standing up a local dynamo server (in Travis CI) or using Moto.

Lightsail access rights

When doing a repokid update, I got the following warnings:
2017-06-23 12:29:58,030 WARNING: skipping lightsail:getinstancesnapshots [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,030 WARNING: skipping lightsail:allocatestaticip [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,030 WARNING: skipping lightsail:deletedomain [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,030 WARNING: skipping lightsail:openinstancepublicports [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,031 WARNING: skipping lightsail:getinstancestate [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,031 WARNING: skipping lightsail:getinstanceaccessdetails [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,031 WARNING: skipping lightsail:getdomains [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,031 WARNING: skipping lightsail:getblueprints [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,032 WARNING: skipping lightsail:getstaticip [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,032 WARNING: skipping iam:passrole [in /home/ec2-user/repokid/repokid/repokid.py:314] 2017-06-23 12:29:58,032 WARNING: skipping lightsail:importkeypair [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,032 WARNING: skipping lightsail:getoperation [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,033 WARNING: skipping lightsail:updatedomainentry [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,033 WARNING: skipping lightsail:getstaticips [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,033 WARNING: skipping lightsail:getinstancemetricdata [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,033 WARNING: skipping lightsail:createkeypair [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,033 WARNING: skipping lightsail:createdomainentry [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,034 WARNING: skipping lightsail:getinstances [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,034 WARNING: skipping lightsail:deletedomainentry [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,034 WARNING: skipping lightsail:deletekeypair [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,034 WARNING: skipping lightsail:releasestaticip [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,034 WARNING: skipping lightsail:getactivenames [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,034 WARNING: skipping lightsail:detachstaticip [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,035 WARNING: skipping lightsail:getbundles [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,035 WARNING: skipping lightsail:peervpc [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,035 WARNING: skipping lightsail:getoperations [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,035 WARNING: skipping lightsail:deleteinstance [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,036 WARNING: skipping lightsail:getregions [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,036 WARNING: skipping lightsail:closeinstancepublicports [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,036 WARNING: skipping lightsail:rebootinstance [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,036 WARNING: skipping lightsail:getkeypairs [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,036 WARNING: skipping lightsail:unpeervpc [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,037 WARNING: skipping lightsail:getinstance [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,037 WARNING: skipping lightsail:getinstancesnapshot [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,037 WARNING: skipping lightsail:createinstances [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,037 WARNING: skipping lightsail:deleteinstancesnapshot [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,037 WARNING: skipping lightsail:startinstance [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,038 WARNING: skipping lightsail:createinstancesnapshot [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,038 WARNING: skipping lightsail:getinstanceportstates [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,038 WARNING: skipping lightsail:stopinstance [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,039 WARNING: skipping lightsail:isvpcpeered [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,039 WARNING: skipping lightsail:getdomain [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,039 WARNING: skipping lightsail:createdomain [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,039 WARNING: skipping lightsail:getkeypair [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,039 WARNING: skipping lightsail:attachstaticip [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,040 WARNING: skipping lightsail:getoperationsforresource [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,040 WARNING: skipping lightsail:downloaddefaultkeypair [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,040 WARNING: skipping lightsail:createinstancesfromsnapshot [in /home/ec2-user/repokid/repokid/repokid.py:309] 2017-06-23 12:29:58,043 WARNING: Not sure about these services: [] [in /home/ec2-user/repokid/repokid/repokid.py:358]
I tried to find a list of access rights maybe to add in a document, but can't find anything, so I imagine it is not a static reference library that is used.

Pip install doesn't work

It's been reported that pip install doesn't work because config isn't located in the correct place. Fixing this is a pre-requisite to getting it on PyPI.

Restore part of a role

It would be nice to have the ability to only restore some services, rather than the whole old policy. This should work by taking an optional list of services during rollback. The rollback will then restore any policy or permissions from a policy that were in the selected rollback version from the selected services.

Support Athena querying for CloudTrail data

Athena can be used to query the S3 buckets where CloudTrail data is stored directly. This would be useful for organizations without some other storage (such as ElasticSearch) set up. It should be reasonably easy to develop a hook that makes Athena queries to determine which actions have been used for a role in the last n days.

Consider removing permissions through deny?

I am wondering if there could be value in explicitly denying access to services not being used.

The reason I ask is because it's pretty hard to remove access that is granted through a managed policy.

Has any consideration been given to how this should be handled?

TypeError: can't compare offset-naive and offset-aware datetimes

After update I am receiving the error "TypeError: can't compare offset-naive and offset-aware datetimes" when running "repokid update_role_cache "

Output from command is below:

Traceback (most recent call last):
File "/root/aardvark/env/bin/repokid", line 11, in
load_entry_point('repokid', 'console_scripts', 'repokid')()
File "/root/aardvark/env/lib64/python3.7/site-packages/click-8.0.0rc1-py3.7.egg/click/core.py", line 1041, in call
return self.main(*args, **kwargs)
File "/root/aardvark/env/lib64/python3.7/site-packages/click-8.0.0rc1-py3.7.egg/click/core.py", line 971, in main
rv = self.invoke(ctx)
File "/root/aardvark/env/lib64/python3.7/site-packages/click-8.0.0rc1-py3.7.egg/click/core.py", line 1563, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/root/aardvark/env/lib64/python3.7/site-packages/click-8.0.0rc1-py3.7.egg/click/core.py", line 1309, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/root/aardvark/env/lib64/python3.7/site-packages/click-8.0.0rc1-py3.7.egg/click/core.py", line 715, in invoke
return callback(*args, **kwargs)
File "/root/aardvark/env/lib64/python3.7/site-packages/click-8.0.0rc1-py3.7.egg/click/decorators.py", line 23, in new_func
return f(get_current_context(), *args, **kwargs)
File "/root/aardvark/repokid/repokid/cli/repokid_cli.py", line 199, in update_role_cache
_update_role_cache(account_number, config, hooks)
File "/root/aardvark/repokid/repokid/commands/role_cache.py", line 76, in _update_role_cache
filtered_list = plugin.apply(roles)
File "/root/aardvark/repokid/repokid/filters/age/init.py", line 40, in apply
elif role.create_date > now - ago:
TypeError: can't compare offset-naive and offset-aware datetimes

Getting KeyError: 'RoleName' while trying to remove permissions from a role

I have configured the aardvark and repokid config accordingly. However once the role cache is updated, trying to remove permissions from a role leads to the below error. I have copied the complete trace below:-

(env) lab-user @ lab ~/Garage/repokid (master)
└─ $ ▶ repokid remove-permissions-from-roles -f roles -c 
Loaded config from /home/lab/Garage/repokid/config.json
  0%|                                                                                                                           | 0/1 [00:00<?, ?it/s]2021-10-31 23:34:37,922 INFO: Replacing Policies With: 

<REDACTED_POLICY>

Traceback (most recent call last):
  File "/home/lab/Garage/repokid/env/bin/repokid", line 33, in <module>
    sys.exit(load_entry_point('repokid', 'console_scripts', 'repokid')())
  File "/home/lab/Garage/repokid/env/lib/python3.8/site-packages/click/core.py", line 1128, in __call__
    return self.main(*args, **kwargs)
  File "/home/lab/Garage/repokid/env/lib/python3.8/site-packages/click/core.py", line 1053, in main
    rv = self.invoke(ctx)
  File "/home/lab/Garage/repokid/env/lib/python3.8/site-packages/click/core.py", line 1659, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/lab/Garage/repokid/env/lib/python3.8/site-packages/click/core.py", line 1395, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/lab/Garage/repokid/env/lib/python3.8/site-packages/click/core.py", line 754, in invoke
    return __callback(*args, **kwargs)
  File "/home/lab/Garage/repokid/env/lib/python3.8/site-packages/click/decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/lab/Garage/repokid/repokid/cli/repokid_cli.py", line 236, in remove_permissions_from_roles
    _remove_permissions_from_roles(permissions, role_file, config, hooks, commit=commit)
  File "/home/lab/Garage/repokid/repokid/commands/role.py", line 301, in _remove_permissions_from_roles
    role.remove_permissions(permissions, hooks, commit=commit)
  File "/home/lab/Garage/repokid/repokid/role.py", line 606, in remove_permissions
    current_policies = get_role_inline_policies(self.dict(), **conn) or {}
  File "/home/lab/Garage/repokid/env/lib/python3.8/site-packages/cloudaux/aws/iam.py", line 109, in get_role_inline_policies
    policy_names = get_role_inline_policy_names(role, **kwargs)
  File "/home/lab/Garage/repokid/env/lib/python3.8/site-packages/cloudaux/aws/decorators.py", line 43, in decorated_function
    retval = f(*args, **kwargs)
  File "/home/lab/Garage/repokid/env/lib/python3.8/site-packages/cloudaux/aws/sts.py", line 220, in decorated_function
    return f(*args, **kwargs)
  File "/home/lab/Garage/repokid/env/lib/python3.8/site-packages/cloudaux/aws/iam.py", line 78, in get_role_inline_policy_names
    RoleName=role['RoleName'],
KeyError: 'RoleName'

Repokid Commit Id: 376aa82

AgeFilter and blacklisting are not being removed

Hello,
Once you set an agefilter or a blacklistfilter, the account is tagged in this way in the repokid display_role_cache. Even if you remove the agefilter (to 0 or 1) or remove the blacklistfilter, the account stays tagged. Even if you repokid update :

aardvark [u'AgeFilter'] False 0 0 Never []
admin [u'BlacklistFilter'] False 0 0 Never []

Config.json view:
"filter_config": {
"AgeFilter": {
"minimum_age": 0
},
"BlacklistFilter": {
"all": []
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.