
repokid v0.19.8
Privilegio minimo AWS per distribuzione distribuita e ad alta velocità
Repokid
Repokid utilizza Access Advisor fornito da Aardvark per rimuovere dalle policy inline dei ruoli IAM in un account AWS i permessi che concedono accesso a servizi non utilizzati.
Per Iniziare
Installazione
mkvirtualenv repokid
git clone [email protected]:Netflix/repokid.git
cd repokid
pip install -e .
repokid config config.json
DynamoDB
Avrai bisogno di una tabella DynamoDB chiamata repokid_roles (specifica l'account e l'endpoint in dynamo_db nel file di configurazione).
La tabella deve avere le seguenti proprietà:
RoleId(stringa) come chiave primaria di partizione, nessuna chiave primaria di ordinamento- Un indice secondario globale chiamato
Accountcon una chiave primaria di partizioneAccounteRoleIdeAccountcome attributi proiettati - Un indice secondario globale chiamato
RoleNamecon una chiave primaria di partizioneRoleNameeRoleIdeRoleNamecome attributi proiettati
Per lo sviluppo, puoi eseguire Dynamo in locale.
Per eseguire in locale:
docker-compose up
L'endpoint per DynamoDB sarà http://localhost:8000. Un pannello di amministrazione di DynamoDB si trova a http://localhost:8001.
Se esegui la versione di sviluppo, la tabella e l'indice verranno creati automaticamente per te.
Permessi IAM
Repokid necessita di un ruolo IAM in ogni account che verrà interrogato. Inoltre, Repokid deve essere avviato con un ruolo o un utente che possa eseguire sts:AssumeRole nei diversi ruoli dell'account.
RepokidInstanceProfile:
- Creane solo uno.
- Deve avere la capacità di chiamare
sts:AssumeRolein tutti i RepokidRole. - Permessi DynamoDB per la tabella
repokid_rolese tutti gli indici (specificati nella sottosezioneassume_roledidynamo_dbnella configurazione) e la capacità di eseguiredynamodb:ListTables
RepokidRole:
- Deve esistere in ogni account da gestire con repokid.
- Deve avere una politica di trust che permetta
RepokidInstanceProfile. - Il nome deve essere specificato in
connection_iamnel file di configurazione. - Ha questi permessi:
{
"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": "*"
}
]
}
Quindi, se stai monitorando n account, avrai sempre bisogno di n+1 ruoli. (n RepokidRole e 1 RepokidInstanceProfile).
Modifica di config.json
Eseguendo repokid config config.json viene creato un file che dovrai modificare. Trova e aggiorna questi campi:
dynamodb: Se usi Dynamo in locale, imposta l'endpoint suhttp://localhost:8010. Se usi Dynamo ospitato su AWS, impostaregion,assume_roleeaccount_number.aardvark_api_location: La posizione della tua API REST Aardvark. Qualcosa comehttps://aardvark.yourcompany.net/api/1/advisorsconnection_iam: Impostaassume_rolesuRepokidRole, o come l'hai chiamato.
Configurazione Opzionale
Repokid utilizza filtri per decidere quali ruoli sono candidati per essere ripuliti. I filtri possono essere configurati per adattarsi al tuo ambiente come descritto di seguito.
Filtro Blocca elenco (Blocklist Filter)
I ruoli possono essere esclusi aggiungendoli al filtro Blocklist. Un motivo comune per escludere un ruolo è se il carico di lavoro corrispondente esegue azioni occasionali che potrebbero non essere state osservate ma sono note come necessarie. Ci sono due modi per escludere un ruolo:
- Escludere il nome del ruolo per tutti gli account: aggiungilo a un elenco nella configurazione
filter_config.BlocklistFilter.all - Escludere il nome del ruolo per un account specifico: aggiungilo a un elenco nella configurazione
filter_config.BlocklistFilter.<ACCOUNT_NUMBER>
I blocca elenco possono anche essere mantenuti in un file S3 blocklist. Devono essere nella forma seguente:
{
"arns": ["arn1", "arn2"],
"names": {"role_name_1": ["all", "account_number_1"], "role_name_2": ["account_number_2", "account_number_3"]}
}
Filtro Esclusivo (Exclusive Filter)
Se preferisci ripulire solo determinati ruoli, puoi usare il Filtro Esclusivo. Forse vuoi considerare solo i ruoli utilizzati in produzione o da certi team.
Per selezionare i ruoli da ripulire, puoi elencare i loro nomi nei file di configurazione. Sono supportati anche i pattern glob in stile shell.
La selezione dei ruoli può essere specificata per singolo account o globalmente.
Per attivare questo filtro inserisci "repokid.filters.exclusive:ExclusiveFilter" nella sezione active_filters del file di configurazione.
Per configurarlo, puoi iniziare con il file di configurazione generato automaticamente, che ha un esempio di configurazione nella sezione "filter_config":
"ExclusiveFilter": {
"all": [
"<GLOB_PATTERN>"
],
"<ACCOUNT_NUMBER>": [
"<GLOB_PATTERN>"
]
}
Filtro Età (Age Filter)
Per impostazione predefinita, il filtro età esclude i ruoli più giovani di 90 giorni. Per modificarlo, modifica l'impostazione di configurazione:
filter_config.AgeFilter.minimum_age.
Filtri Attivi (Active Filters)
È possibile creare nuovi filtri per supportare logiche interne. Da Netflix ne abbiamo diversi specifici per i nostri
casi d'uso. Per renderli attivi, assicurati che siano nel percorso Python e aggiungili nella configurazione all'elenco nella
sezione active_filters.
Estendere Repokid
Hook
Repokid è estendibile tramite hook che vengono chiamati prima, durante e dopo varie operazioni come elencato di seguito.
| Nome Hook | Contesto |
|---|---|
AFTER_REPO | ruolo, errori |
AFTER_REPO_ROLES | ruoli, errori |
BEFORE_REPO_ROLES | numero_account, ruoli |
AFTER_SCHEDULE_REPO | ruoli |
DURING_REPOABLE_CALCULATION | role_id, arn, account_number, role_name, permessi_potenzialmente_ripulibili, eta_minima |
DURING_REPOABLE_CALCULATION_BATCH | lotto_ruoli, permessi_potenzialmente_ripulibili, eta_minima |
Gli hook devono aderire alla seguente interfaccia:
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:
"""Le funzioni hook vengono chiamate con un dict contenente le chiavi elencate sopra in base all'hook di destinazione.
Qualsiasi modifica apportata all'input e restituita nell'output verrà passata alle successive funzioni hook.
"""
...
Esempi di implementazioni di hook possono essere trovati in repokid.hooks.loggers.
Filtri
Possono essere scritti filtri personalizzati per escludere i ruoli dall'essere ripuliti. I filtri devono aderire alla seguente interfaccia:
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:
"""I filtri vengono inizializzati con un dict contenente il contenuto di `filter_config.FilterName`
dal file di configurazione. Questo esempio verrebbe inizializzato con `filter_config.CustomFilterName`.
La configurazione può essere accessita tramite `self.config`
Se non hai bisogno di alcuna logica di inizializzazione personalizzata, puoi omettere questa funzione dalla tua
classe filtro.
"""
super().__init__(config=config)
# la logica di inizializzazione personalizzata va qui
...
def apply(self, input_list: RoleList) -> RoleList:
"""Determina i ruoli da escludere e restituiscili come RoleList"""
...
Un'implementazione semplice di filtro si trova in repokid.filters.age. Un esempio più complesso è in repokid.blocklist.age.
Come Usarlo
Una volta configurato Repokid, usalo come segue:
Flusso Standard
- Aggiornare la cache dei ruoli:
repokid update_role_cache <NUMERO_ACCOUNT> - Visualizzare la cache dei ruoli:
repokid display_role_cache <NUMERO_ACCOUNT> - Visualizzare informazioni su un ruolo specifico:
repokid display_role <NUMERO_ACCOUNT> <NOME_RUOLO> - Ripulire un ruolo specifico:
repokid repo_role <NUMERO_ACCOUNT> <NOME_RUOLO> - Ripulire tutti i ruoli in un account:
repokid repo_all_roles <NUMERO_ACCOUNT> -c
Pianificazione
Invece di eseguire una pulizia immediata, puoi pianificarne una (comando schedule_repo). La durata tra la pianificazione e l'idoneità è configurabile, ma per impostazione predefinita i ruoli possono essere ripuliti 7 giorni dopo la pianificazione. Puoi quindi eseguire un comando repo_scheduled_roles per ripulire solo i ruoli che sono già stati pianificati.
Mirare a un permesso specifico
Supponiamo che trovi un determinato permesso particolarmente pericoloso nel tuo ambiente. Qui userò s3:PutObjectACL come esempio. Puoi usare Repokid per trovare tutti i ruoli che hanno questo permesso (anche quelli nascosti in un wildcard), e poi rimuovere solo quel singolo permesso.
Trova e Rimuovi:
- Assicurati che la cache dei ruoli sia aggiornata prima di iniziare.
- Trova i ruoli con un dato permesso:
repokid find_roles_with_permissions <permesso>... [--output=FILE_RUOLI] - Rimuovi il permesso dai ruoli:
repokid remove_permissions_from_roles --role-file=FILE_RUOLI <permesso>... [-c]
Esempio:
$ 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
Rollback
Repokid memorizza una copia di ogni versione delle policy inline di cui è a conoscenza. Queste vengono aggiunte quando
una versione diversa di una policy viene trovata durante update_role_cache e ogni volta che si verifica un'azione di pulizia.
Per ripristinare una versione precedente esegui:
Visualizza tutte le versioni dei ruoli: repokid rollback_role <NUMERO_ACCOUNT> <NOME_RUOLO>
Ripristina una versione specifica: repokid rollback_role <NUMERO_ACCOUNT> <NOME_RUOLO> --selection=<NUMERO> -c
Statistiche
Repokid tiene traccia dei conteggi dei permessi totali per ogni ruolo. Le statistiche vengono aggiunte ogni volta che si verifica un'azione update_role_cache o
repo_role. Per esportare tutte le statistiche in un file CSV esegui: repokid repo_stats <NOME_FILE_OUTPUT>. Può essere specificato un numero di account opzionale per esportare le statistiche solo per un account specifico.
Libreria
Nuovo in
v0.14.2
Repokid può essere chiamato come libreria utilizzando il modulo repokid.lib:
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 è progettato per ascoltare i messaggi su una coda ed eseguire azioni. Finora le azioni sono:
- Elencare i servizi ripulibili da un ruolo
- Impostare o rimuovere un opt-out
- Elencare ed eseguire rollback per un ruolo
Repokid risponderà su un argomento SNS configurabile con informazioni su eventuali successi o fallimenti. Il componente Dispatcher esiste per aiutare con l'operatività del ciclo di vita della pulizia nella tua organizzazione. Potresti scegliere di esporre la coda direttamente agli sviluppatori, ma più probabilmente dovrebbe essere protetta perché il rollback può essere un'azione distruttiva se non eseguita con attenzione.
Sviluppo
Rilascio
Il versionamento è gestito da setupmeta. Per creare una nuova release:
python setup.py version --bump patch --push
# Ispeziona l'output e assicurati che sia quello che ti aspetti
# Se tutto è a posto, fai commit e push del nuovo tag:
python setup.py version --bump patch --push --commit