Gestire i dati sensibili in Python con AWS Secrets Manager
Generalmente memorizziamo le credenziali in modi diversi, ad esempio usando variabili di ambiente, memorizzandole in un file e facendo riferimento al file nell’applicazione: tutti esempi di persistenza non sicuri, soprattutto se lavoriamo con servizi legati al cloud… Quindi, quali alternative abbiamo con AWS?
AWS Secrets Manager è un servizio progettato per aiutarci a conservare e gestire in modo sicuro informazioni sensibili come password, chiavi API, e così via.
Pre-requisiti
In questo esempio, useremo Python per recuperare e usare le credenziali a livello di codice e ci servirà anche installare la CLI di AWS per configurare le tue credenziali recuperate da IAM.
Infatti, dobbiamo assicurarci di avere un utente IAM con accesso alla CLI, chiavi di accesso e policy specifiche per accedere al servizio AWS Secrets Managers, ossia il gestore dei segreti come “GetSecretValue” e “KMS Decrypt” nel caso in cui tu stia utilizzando una chiave KMS diversa da quella predefinita.
Un esempio di policy potrebbe essere la seguente:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:ListSecrets",
"kms:Decrypt",
"kms:DescribeKey"
],
"Resource": "*"
}
]
}
Nota: invece di usare “*” per specificare la risorsa, puoi usare l’ARN (ossia, il nome della risorsa) del secret specifico per avere un accesso ancora più granulare.
Creazione del secret
A questo punto, apri il servizio AWS Secrets Manager e crea un nuovo secret, scegliendo che tipo di secret vuoi memorizzare in base al servizio per cui lo utilizzerai. Come vedrai di seguito, ci sono diversi tipi disponibili: nell’esempio, sceglieremo l’ultima opzione per memorizzare una coppia chiave-valore con una e-mail e una password.
Tipologie di secret
Creazione di un secret con coppia chiave-valore
Nello step successivo definisci un nome per il secret, una descrizione e procedi al passaggio successivo, dove puoi definire la rotazione del secret se lo desideri.
La rotazione è fondamentale perché riduce al minimo il rischio di accessi non autorizzati, garantendo che le credenziali compromesse vengano aggiornate regolarmente, limitando così la finestra di opportunità per chi cerca di sfruttare informazioni più vecchie.
Una volta controllate le impostazioni, salva e controlla che il secret sia presente nell’elenco all’interno della dashboard del servizio.
Accesso al secret con Python
Abbiamo le nostre credenziali su AWS: ora, per usarlo nell’applicazione Python, abbiamo bisogno del modulo boto3
. Inoltre, userò selenium
per automatizzare il processo di login.
Il codice riportato di seguito è un esempio per mostrare in che modo si possa utilizzare la libreria di boto3
per recuperare e utilizzare il secret: tramite questa semplice funzione, avviamo una nuova sessione e creiamo un oggetto client relativo al servizio Secrets Manager con la region che andremo a specificare dopo.
Poi, usiamo la funzione get_secret_value
per recuperare il secret usando il nome definito all’inizio durante la creazione. Se qualcosa andasse storto, possiamo sfruttare le eccezioni di botocore
per gestire l’errore, altrimenti possiamo restituire il secret, che sarà in formato JSON.
Chiusa la funzione, definiamo le variabili che ci servono per utilizzarla e la invochiamo per testare il recupero delle credenziali et… voilà!
import boto3
from botocore.exceptions import ClientError
import json
def get_secret(secret_name, region_name):
session = boto3.session.Session()
client = session.client(service_name='secretsmanager', region_name=region_name)
try:
response = client.get_secret_value(SecretId=secret_name)
except ClientError as e:
raise e
else:
secret = response['SecretString']
return secret
secret_name = "webapp_creds" # nome del secret
region_name = "us-east-1"
secret_json = get_secret(secret_name, region_name)
secret = json.loads(secret_json)
email = secret["email"] # campo email
password = secret["password"] # campo password
print(email, password)