
Privilegio minimo AWS per distribuzione distribuita e ad alta velocità
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.
mkvirtualenv repokid
git clone [email protected]:Netflix/repokid.git
cd repokid
pip install -e .
repokid config config.json
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 ordinamentoAccount con una chiave primaria di partizione Account e RoleId e Account come attributi proiettatiRoleName con una chiave primaria di partizione RoleName e RoleId e RoleName come attributi proiettatiPer 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.
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:
sts:AssumeRole in tutti i RepokidRole.repokid_roles e tutti gli indici (specificati nella sottosezione assume_role di dynamo_db nella configurazione) e la capacità di eseguire dynamodb:ListTablesRepokidRole:
RepokidInstanceProfile.connection_iam nel file di configurazione.{
"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).
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 su http://localhost:8010. Se usi Dynamo ospitato su AWS, imposta region, assume_role e account_number.aardvark_api_location: La posizione della tua API REST Aardvark. Qualcosa come https://aardvark.yourcompany.net/api/1/advisorsconnection_iam: Imposta assume_role su RepokidRole, o come l'hai chiamato.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.
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:
filter_config.BlocklistFilter.allfilter_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"]}
}
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>"
]
}
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.
È 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.
Repokid è estendibile tramite hook che vengono chiamati prima, durante e dopo varie operazioni come elencato di seguito.
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.
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.
Una volta configurato Repokid, usalo come segue:
repokid update_role_cache <NUMERO_ACCOUNT>repokid display_role_cache <NUMERO_ACCOUNT>repokid display_role <NUMERO_ACCOUNT> <NOME_RUOLO>repokid repo_role <NUMERO_ACCOUNT> <NOME_RUOLO>repokid repo_all_roles <NUMERO_ACCOUNT> -cInvece 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.
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:
repokid find_roles_with_permissions <permesso>... [--output=FILE_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
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
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.
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)
Repokid Dispatcher è progettato per ascoltare i messaggi su una coda ed eseguire azioni. Finora le azioni sono:
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.
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
| 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 |