Vés al contingut

IAM sense por: permisos mínims que funcionen

A AWS, per defecte, tot està prohibit. Cap usuari, cap funció i cap servei pot fer res fins que una política ho permet explícitament. IAM (Identity and Access Management) és el sistema que decideix qui pot fer què, sobre quin recurs.

La temptació és clara: poses AdministratorAccess o "Action": "*" i deixa de sortir l'AccessDenied. Funciona fins al dia que una clau s'escapa a GitHub o una funció té un error, i llavors el dany possible és tot el compte. Aquesta lliçó és per arribar al permís just sense passar-hi el dia.


Qui pot fer coses​

  • L'usuari arrel (root). El correu amb què vas crear el compte. Ho pot tot, també tancar-lo. L'actives amb MFA, el guardes i no el fas servir per a res més que per a les quatre tasques que només ell pot fer.
  • Usuaris d'IAM. Persones o programes amb credencials pròpies: contrasenya per a la consola, claus d'accés per a la CLI. Un usuari, una persona: mai comptes compartits.
  • Grups. Conjunts d'usuaris. Els permisos es posen al grup i no a cada usuari. Un grup no pot contenir altres grups.
  • Rols. Una identitat sense credencials fixes que algú assumeix durant un temps i rep claus temporals. Les funcions Lambda, les instàncies EC2 i els serveis d'AWS treballen sempre amb rols. Les persones, idealment, també.

Per a les persones, avui la recomanació d'AWS ja no són usuaris d'IAM amb claus d'accés que viuen per sempre al teu portàtil, sinó IAM Identity Center: inicies sessió al navegador (aws sso login) i la CLI rep credencials que caduquen soles. Per a un compte personal de proves, un usuari d'IAM amb MFA encara és acceptable. El que no ho és mai és treballar amb l'usuari arrel.


Com és una política​

Una política és un document JSON. Aquesta deixa llegir i escriure una taula de DynamoDB concreta, i res més:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LlistaCompra",
"Effect": "Allow",
"Action": [
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem"
],
"Resource": [
"arn:aws:dynamodb:eu-west-1:111122223333:table/llista-compra",
"arn:aws:dynamodb:eu-west-1:111122223333:table/llista-compra/index/pendents"
]
}
]
}
  • Version: sempre "2012-10-17". És la versió del llenguatge, no una data que hagis de canviar.
  • Effect: Allow o Deny.
  • Action: el servei i l'operació, servei:Operacio.
  • Resource: l'ARN exacte del que es pot tocar. Fixa't que l'índex té un ARN propi: si només poses el de la taula, la Query sobre pendents falla.
  • Condition (opcional): «només si…». Des d'aquesta IP, amb MFA, si la petició ve d'aquesta distribució de CloudFront.

111122223333 és el número de compte d'exemple de la documentació d'AWS. Posa-hi el teu.


Els tres tipus de document que has de distingir​

Aquí és on s'encalla tothom, perquè els tres són JSON i s'assemblen molt.

DocumentOn viuQuè diu
Política d'identitatEn un usuari, grup o rol«Aquest pot fer X sobre Y»
Política de recursosEn el recurs: un bucket, una Lambda, una cua«Aquest recurs el pot tocar Z»
Document de confiançaEn un rol«Aquest rol el pot assumir Z»

Ja n'has fet servir dels tres sense adonar-te'n:

  • A la lliçó 02, el confianca.json deia que el servei Lambda pot assumir el rol de la funció. Sense, la funció no es pot crear.
  • També a la lliçó 02, AWSLambdaBasicExecutionRole és una política d'identitat enganxada a aquell rol: deixa escriure logs.
  • A la lliçó 03, el lambda add-permission va afegir una política de recursos a la funció: deixa que API Gateway la invoqui.
  • A la lliçó 05, la política del bucket era de recursos: deixa llegir només a una distribució de CloudFront.

Regla pràctica per triar: si el permís és «el meu codi necessita tocar coses», va al rol (identitat). Si és «un altre servei o compte necessita tocar això meu», va al recurs.

Les ACL de S3 són un quart mecanisme, anterior a IAM. Els buckets nous les porten desactivades i AWS recomana deixar-les així.


Com decideix AWS​

Quan arriba una petició, AWS ajunta totes les polítiques que hi tenen a veure i aplica tres regles, en aquest ordre:

  1. Un Deny explícit guanya sempre. No hi ha Allow que el superi.
  2. Si no n'hi ha, un Allow permet.
  3. Si no hi ha ni l'un ni l'altre, denegat. És el valor per defecte.

Hi ha capes per sobre de les teves polítiques que també poden denegar: les SCP d'AWS Organizations (si el compte és d'una empresa), els límits de permisos (permissions boundaries) i les polítiques de sessió. Quan un permís «hauria de funcionar» i no funciona, sovint és una d'aquestes.


Llegir un AccessDenied​

Els missatges d'error d'IAM diuen exactament què falta, si els llegeixes sencers:

User: arn:aws:sts::111122223333:assumed-role/llista-rol/llista-afegeix
is not authorized to perform: dynamodb:Query
on resource: arn:aws:dynamodb:eu-west-1:111122223333:table/llista-compra/index/pendents
because no identity-based policy allows the dynamodb:Query action

Quatre dades: qui (el rol llista-rol, assumit per la funció), quina acció (dynamodb:Query), sobre què (l'índex, no la taula) i per què (cap política d'identitat ho permet). La solució és afegir l'ARN de l'índex a la política del rol. No és posar un asterisc.

Si el motiu diu with an explicit deny, busca el Deny: en una SCP, en un límit de permisos o en la política del recurs.


El camí cap al permís mínim​

No cal encertar-ho a la primera. El mètode que funciona:

  1. Comença per la llista d'operacions que fa el codi. Si fa PutCommand i QueryCommand, són dynamodb:PutItem i dynamodb:Query. No n'hi ha més.
  2. Escriu-les amb l'ARN exacte del recurs. Un recurs per entorn: la taula de proves i la de producció són ARN diferents.
  3. Prova-ho i llegeix l'error si n'hi ha. Cada AccessDenied et diu l'acció i el recurs que falten.
  4. Revisa al cap d'un temps. L'IAM Access Analyzer pot generar una política a partir del que el rol ha fet realment (llegeix CloudTrail) i et diu quins permisos no s'han fet servir mai.

Les polítiques gestionades d'AWS del tipus AmazonS3FullAccess o AmazonDynamoDBFullAccess són per a persones que administren, no per a funcions. Una Lambda amb AmazonS3FullAccess pot esborrar tots els buckets del compte. A les pràctiques del curs presencial les fèiem servir per anar ràpid; en una aplicació de debò, no.


Claus d'accés: el que no s'ha de fer​

  • Mai en un repositori. Hi ha bots que escanegen GitHub cada minut. Quan AWS en detecta una de publicada, et posa una política de quarantena a l'usuari, però el temps que passa fins llavors és el que fa servir l'atacant per aixecar màquines de minar.
  • Mai a l'usuari arrel. L'usuari arrel no ha de tenir claus d'accés.
  • Esborrar ~/.aws/credentials no revoca res. La clau continua sent vàlida a AWS. Per invalidar-la, s'ha de desactivar o esborrar a IAM.
  • Dins d'AWS, cap clau. Una Lambda, una EC2 o un contenidor fan servir el seu rol. Si veus una clau d'accés en una variable d'entorn d'una funció, és un error de disseny.

Què costa això​

IAM és gratuït. Usuaris, grups, rols i polítiques no costen res. Access Analyzer, en la part que analitza l'accés extern, tampoc.

El que costa és el que passa quan IAM està mal configurat: una clau filtrada pot generar milers de dòlars en un cap de setmana. AWS acostuma a perdonar el primer incident si actues ràpid, però no t'hi refiïs.


Errors habituals​

  • El permís «no s'aplica». Els canvis d'IAM triguen uns segons a propagar-se. Si acabes de crear el rol o la política, espera i torna-ho a provar abans de canviar res.
  • Resource correcte, acció correcta, i encara denegat. Mira si l'operació treballa sobre un subrecurs: els índexs de DynamoDB (/index/...), els objectes de S3 (bucket/*, que no és el mateix que bucket), les versions d'una Lambda.
  • s3:ListBucket sobre bucket/*. Llistar és una operació sobre el bucket (arn:aws:s3:::bucket); llegir un objecte és sobre l'objecte (arn:aws:s3:::bucket/*). Es posen en dues declaracions o en dues línies de Resource.
  • Una política d'identitat que permet invocar una Lambda des d'un altre servei. Per a API Gateway, S3 o EventBridge, el permís va a la política de recursos de la funció (lambda add-permission), no al rol.
  • Treballar cada dia amb AdministratorAccess. Per a tu, en un compte de proves, potser. Però que no sigui el rol de cap funció.

Exercici​

L'exercici d'IAM de classe, amb una peça més:

  1. Crea dos grups, comptabilitat i desenvolupament, i un usuari a cada un, amb accés a la consola i MFA.
  2. Comptabilitat ha de poder veure i gestionar els buckets de S3; desenvolupament, no. Entra amb cada usuari en una finestra privada i comprova-ho.
  3. Desenvolupament necessita llistar els usuaris del compte des de la CLI. Escriu una política pròpia amb només iam:ListUsers i assigna-la al grup. Prova aws iam list-users abans i després.
  4. Fes el rol de la Lambda de la lliçó 04 amb la política d'aquesta lliçó, sense cap FullAccess. Treu l'ARN de l'índex, prova la ruta dels pendents i llegeix l'AccessDenied sencer.
Repàs: quatre preguntes
  1. Si una política permet una acció i una altra la denega explícitament, què passa? Es denega. Un Deny explícit guanya sempre.
  2. On va el permís perquè API Gateway pugui invocar una Lambda? A la política de recursos de la funció.
  3. Què diu el document de confiança d'un rol? Qui el pot assumir.
  4. Esborrar el fitxer de credencials del portàtil desactiva la clau d'accés? No. Cal desactivar-la o esborrar-la a IAM.

La IA a l'empresa, amb criteri

Cada setmana, una sola cosa que pots fer servir: la notícia que toca la teva empresa i què en faria jo, una pregunta de client, un cas real o un exercici de quinze minuts. Un correu per setmana com a molt, i te'n pots donar de baixa amb un clic.