
repokid v0.19.8
AWS Least Privilege для распределенного высокоскоростного развертывания
Repokid
Repokid использует Access Advisor, предоставляемый Aardvark, для удаления разрешений, предоставляющих доступ к неиспользуемым сервисам, из inline-политик IAM-ролей в учётной записи AWS.
Начало работы
Установка
mkvirtualenv repokid
git clone [email protected]:Netflix/repokid.git
cd repokid
pip install -e .
repokid config config.json
DynamoDB
Вам понадобится таблица DynamoDB с именем repokid_roles (укажите учётную запись и endpoint в разделе dynamo_db файла конфигурации).
Таблица должна иметь следующие свойства:
RoleId(строка) в качестве первичного ключа раздела, без первичного ключа сортировки.- Глобальный вторичный индекс с именем
Account, где первичный ключ раздела —Account, а проецируемые атрибуты —RoleIdиAccount. - Глобальный вторичный индекс с именем
RoleName, где первичный ключ раздела —RoleName, а проецируемые атрибуты —RoleIdиRoleName.
Для разработки вы можете запустить DynamoDB локально.
Для локального запуска:
docker-compose up
Endpoint для DynamoDB будет http://localhost:8000. Панель администрирования DynamoDB доступна по адресу http://localhost:8001.
Если вы используете версию для разработки, таблица и индексы будут созданы автоматически.
Разрешения IAM
Repokid требует IAM-роль в каждой учётной записи, которая будет опрашиваться. Кроме того, Repokid должен запускаться с ролью или пользователем, который может выполнять sts:AssumeRole для ролей разных учётных записей.
RepokidInstanceProfile:
- Создаётся только один.
- Должна иметь возможность вызывать
sts:AssumeRoleдля всех RepokidRole. - Разрешения DynamoDB для таблицы
repokid_rolesи всех индексов (указываются в подразделеassume_roleразделаdynamo_dbконфигурации) и возможность выполнятьdynamodb:ListTables.
RepokidRole:
- Должна существовать в каждой учётной записи, управляемой repokid.
- Должна иметь политику доверия, разрешающую
RepokidInstanceProfile. - Имя должно быть указано в
connection_iamфайла конфигурации. - Имеет следующие разрешения:
{
"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": "*"
}
]
}
Таким образом, если вы отслеживаете n учётных записей, вам всегда понадобится n+1 ролей (n RepokidRole и 1 RepokidInstanceProfile).
Редактирование config.json
Запуск repokid config config.json создаёт файл, который необходимо отредактировать. Найдите и обновите следующие поля:
dynamodb: При использовании локального DynamoDB укажите endpointhttp://localhost:8010. При использовании DynamoDB, размещённого в AWS, укажитеregion,assume_roleиaccount_number.aardvark_api_location: Адрес вашего REST API Aardvark. Например,https://aardvark.yourcompany.net/api/1/advisors.connection_iam: Установитеassume_roleвRepokidRole(или любое другое имя, которое вы выбрали).
Дополнительная конфигурация
Repokid использует фильтры для определения того, какие роли являются кандидатами на репо. Фильтры могут быть настроены под вашу среду, как описано ниже.
Фильтр блокировки (Blocklist Filter)
Роли могут быть исключены путём добавления в фильтр блокировки. Одна из распространённых причин исключения роли — если соответствующая рабочая нагрузка изредка выполняет действия, которые не были замечены, но, как известно, являются обязательными. Есть два способа исключить роль:
- Исключить имя роли для всех учётных записей: добавить его в список в конфигурации
filter_config.BlocklistFilter.all. - Исключить имя роли для конкретной учётной записи: добавить его в список в конфигурации
filter_config.BlocklistFilter.<ACCOUNT_NUMBER>.
Чёрные списки также можно поддерживать в S3-файле блокировки. Они должны быть в следующем формате:
{
"arns": ["arn1", "arn2"],
"names": {"role_name_1": ["all", "account_number_1"], "role_name_2": ["account_number_2", "account_number_3"]}
}
Фильтр исключительности (Exclusive Filter)
Если вы предпочитаете репозировать только определённые роли, можете использовать фильтр исключительности. Например, вы хотите учитывать только роли, используемые в production или определёнными командами. Чтобы выбрать роли для репо, перечислите их имена в файлах конфигурации. Также поддерживаются шаблоны в стиле glob. Выбор ролей может быть задан для каждой учётной записи отдельно или глобально. Чтобы активировать этот фильтр, добавьте "repokid.filters.exclusive:ExclusiveFilter" в раздел active_filters файла конфигурации. Для настройки вы можете начать с автоматически сгенерированного файла конфигурации, в котором есть пример конфигурации в разделе "filter_config":
"ExclusiveFilter": {
"all": [
"<GLOB_PATTERN>"
],
"<ACCOUNT_NUMBER>": [
"<GLOB_PATTERN>"
]
}
Фильтр возраста (Age Filter)
По умолчанию фильтр возраста исключает роли, возраст которых меньше 90 дней. Чтобы изменить это, отредактируйте настройку конфигурации: filter_config.AgeFilter.minimum_age.
Активные фильтры
Могут быть созданы новые фильтры для поддержки внутренней логики. В Netflix у нас есть несколько, специфичных для наших случаев использования. Чтобы сделать их активными, убедитесь, что они находятся в пути Python, и добавьте их в конфигурацию в список в разделе active_filters.
Расширение Repokid
Хуки (Hooks)
Repokid расширяется с помощью хуков, которые вызываются до, во время и после различных операций, как указано ниже.
| Имя хука | Контекст |
|---|---|
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 |
Хуки должны соответствовать следующему интерфейсу:
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:
"""Функции хуков вызываются со словарём, содержащим ключи, перечисленные выше, в зависимости от целевого хука.
Любые изменения, внесённые во входные данные и возвращённые в выходных, будут переданы последующим функциям хуков.
"""
...