La seguretat d'AlpinaShop s'ha construït a trossos. A 03-01 es va tancar el tallafoc. A 03-04 es va dissenyar IAM amb grups, rols personalitzats i comptes de servei sense claus. A 03-05 es va posar Cloud Armor al davant. A 03-06 van arribar Secret Manager i les claus gestionades pel client. A 03-07 es va publicar amb TLS. A 06-02 es va protegir la branca principal. A 07-03 es va aixecar un perímetre al voltant de les dades.
Cada peça es va decidir bé en el seu moment. I ningú no ha mirat mai el conjunt.
Aquesta és la diferència entre tenir controls de seguretat i tenir seguretat. Un atacant no ataca el tallafoc: ataca el baula més feble d'una cadena que tu no has recorregut mai sencera. I en una empresa de quaranta persones amb tres persones tècniques, aquesta baula gairebé mai no és la que un s'imagina — no és una vulnerabilitat exòtica al nucli, és una clau JSON de fa dos anys que continua al portàtil d'un becari que ja no hi treballa.
Aquesta lliçó és la revisió completa. Recorre l'arquitectura capa per capa, aplica els principis que fan que les capes se sostinguin, revisa la cadena de subministrament del programari —que és avui el vector d'atac que més creix—, tanca el cicle de les dades, munta detecció i resposta, aclareix quina part del compliment normatiu és de Google i quina és teva, i acaba amb dues coses que no solen aparèixer als cursos: una llista de comprovació d'enduriment que es pot executar, i la llista honesta del deute de seguretat que AlpinaShop encara té, prioritzada.
Avís, i va de debò. Aquesta lliçó és formació, no una auditoria. El model que es presenta és sòlid i aplicable, però qualsevol arquitectura que tracti dades personals, de pagament o de salut ha de ser revisada per un professional de seguretat i de compliment normatiu abans d'anar a producció, i amb la periodicitat que exigeixi el sector. Cap curs, cap llista de comprovació i cap eina automàtica no substitueix aquesta feina.
Contingut
- Defensa en profunditat aplicada a AlpinaShop
- Els sis principis que sostenen tota la resta
- Confiança zero i BeyondCorp, amb IAP com a implementació pràctica
- Identitat: revisió completa del disseny IAM
- Elevació temporal de privilegis i federació
- Cadena de subministrament del programari
- Dades: classificació, xifratge, pseudonimització i esborrat
- Detecció: Security Command Center i els registres d'auditoria
- Resposta: les dues primeres hores d'un incident
- Compliment: què aporta Google i què continua sent teu
- Llista de comprovació d'enduriment
- El deute de seguretat d'AlpinaShop, prioritzat
- Defensa en profunditat aplicada a AlpinaShop
Defensa en profunditat vol dir que cap control no és l'únic. Si un falla, un altre al darrere limita el dany. No és acumular eines: és dissenyar de manera que la fallada de qualsevol capa no sigui catastròfica.
flowchart TB
ATK["Atacant / error humà"]
subgraph L1["CAPA 1 - Vora"]
A1["Cloud Armor pol-catalogo-web<br/>WAF, geo, límit de taxa"]
A2["TLS alpinashop-cert<br/>+ HSTS"]
A3["Cloud CDN<br/>absorbeix volum"]
end
subgraph L2["CAPA 2 - Identitat"]
B1["IAM: grups, sense rols bàsics"]
B2["MFA obligatori + IAP"]
B3["Comptes de servei sense claus"]
B4["Elevació temporal PAM"]
end
subgraph L3["CAPA 3 - Xarxa"]
C1["VPC compartida, tallafoc central"]
C2["Sense IP públiques a les VM"]
C3["Cloud NAT només de sortida"]
C4["VPC Service Controls"]
end
subgraph L4["CAPA 4 - Càrrega de treball"]
D1["Cloud Run sense privilegis"]
D2["Compte de servei mínim"]
D3["ingress només des del balancejador"]
D4["Binary Authorization"]
end
subgraph L5["CAPA 5 - Dades"]
E1["CMEK amb alpinashop-keyring"]
E2["Secret Manager"]
E3["Cloud SQL sense IP pública"]
E4["Xifratge en trànsit i en repòs"]
end
subgraph L6["CAPA 6 - Detecció"]
F1["Security Command Center"]
F2["Cloud Audit Logs"]
F3["Alertes de Cloud Monitoring"]
F4["Retenció immutable de registres"]
end
ATK --> L1 --> L2 --> L3 --> L4 --> L5
L6 -.->|"observa totes"| L1
L6 -.-> L3
L6 -.-> L5
style L1 fill:#fef7e0,stroke:#fbbc04
style L5 fill:#fce8e6,stroke:#ea4335
style L6 fill:#e6f4ea,stroke:#34a853
La manera de comprovar si la defensa en profunditat és real és fer-se la pregunta de la fallada única a cada capa:
| Si falla… | Què ho conté? | Suficient? |
|---|---|---|
| Cloud Armor deixa passar una injecció SQL | Consultes parametritzades al codi; el compte de la BD només té permisos sobre tienda |
Sí |
| Algú roba la sessió de Dani | MFA a l'accés; Dani no és owner de producció; els canvis passen per revisió | Sí |
Es filtra la clau de sa-catalogo-web |
Aquest compte només llegeix un secret, un bucket i una BD; VPC-SC impedeix treure dades a fora | Parcialment: podria llegir comandes |
| Un contenidor té una vulnerabilitat crítica | Sense privilegis, sense accés al node, compte mínim | Sí |
| Es xifra per ransomware el bucket del catàleg | Versionatge d'objectes + retenció + còpia en una altra regió | Cal verificar-ho (07-06) |
| Marta perd el portàtil | MFA amb clau física; les sessions caduquen | Depèn de si hi ha clau |
Les files amb resposta dubtosa són deute, i van a l'apartat 12. Aquesta és la utilitat real de l'exercici: no confirmar el que està bé, sinó trobar el que no.
- Els sis principis que sostenen tota la resta
Les eines canvien; els principis no. Aquests sis expliquen per què cada decisió del curs va ser la correcta.
Mínim privilegi
Cada identitat té exactament els permisos que necessita per a la seva funció, i ni un més.
L'aplicació honesta fa una mica de mal: vol dir que quan algú demana «dona'm Editor per provar una cosa», la resposta és no i cal dedicar quinze minuts a esbrinar quin permís necessita de debò. La drecera de dir que sí és el que ha omplert el món de projectes on tothom és editor.
L'eina que ho fa suportable és el Recommender d'IAM (03-04), que compara permisos concedits amb permisos usats en 90 dies:
gcloud recommender recommendations list \
--project=alpinashop-prod \
--recommender=google.iam.policy.Recommender \
--location=global \
--format="table(content.overview.member, content.overview.removedRole, priority)"Separació de funcions
Qui construeix no desplega tot sol; qui desplega no aprova tot sol; qui administra no audita.
A AlpinaShop: Dani escriu el codi, Cloud Build el construeix, Marta aprova producció, i els registres d'auditoria els custodia un projecte on cap dels dos no pot escriure (07-07). Cap persona no pot, tota sola, posar codi en producció i esborrar l'evidència.
Denegar per defecte
El que no està explícitament permès, està prohibit.
S'ha aplicat sistemàticament: el tallafoc de 03-01 amb denegació implícita; Cloud Run amb --no-allow-unauthenticated; l'ingress restringit al balancejador; el perímetre de VPC-SC; les polítiques d'organització de 07-07. L'alternativa —permetre per defecte i bloquejar el dolent conegut— és una cursa que es perd sempre.
Radi d'explosió limitat
Quan alguna cosa es comprometi —no si—, fins on arriba?
És el principi que justifica separar en projectes, donar comptes de servei diferents a cada càrrega, i no reutilitzar credencials. La pregunta operativa: si aquesta credencial es filtra avui, què pot fer qui la tingui? Si la resposta és llarga, el disseny està malament.
No confiar en la xarxa
Ser dins de la VPC no és una credencial.
El model clàssic —perímetre dur, interior tou— falla perquè així que algú entra, ho té tot. Es desenvolupa a l'apartat 3.
Assumir la bretxa
Dissenya com si ja fossin a dins.
Canvia les prioritats: s'inverteix tant a detectar i limitar com a prevenir. És el que justifica els registres d'auditoria immutables, les alertes de comportament anòmal i l'assaig de la resposta a incidents.
- Confiança zero i BeyondCorp, amb IAP com a implementació pràctica
BeyondCorp és el model de seguretat que Google va adoptar internament després de l'atac conegut com a Operació Aurora el 2009, i que va donar origen al terme confiança zero.
| Model perimetral clàssic | Confiança zero | |
|---|---|---|
| Premissa | La xarxa interna és de confiança | Cap xarxa no és de confiança |
| Accés | VPN → ets a dins → tens accés | Cada petició s'autoritza per separat |
| Senyals | Origen de la IP | Identitat + dispositiu + context + risc |
| Treball remot | VPN obligatòria | Igual des de qualsevol lloc |
| Compromís intern | Accés lateral lliure | Cada salt es torna a autoritzar |
A Google Cloud, la implementació pràctica és IAP (Identity-Aware Proxy), que ja es va usar a 03-04 i que aquí convé mirar com a peça d'arquitectura.
flowchart LR
U["Empleat<br/>des de qualsevol lloc"] --> LB["Balancejador global"]
LB --> IAP{"IAP"}
IAP -->|"identitat OK<br/>+ nivell accés OK"| APP["Tauler intern<br/>Cloud Run privat"]
IAP -->|"rebuig"| X["403"]
CTX["Access Context Manager<br/>dispositiu gestionat,<br/>xifrat, regió, hora"] -.-> IAP
El que fa IAP, i pel que val la pena:
- L'aplicació no veu mai trànsit no autenticat. El rebuig passa a la vora de Google.
- No hi ha VPN per mantenir, ni concentrador que cau, ni client per instal·lar.
- Funciona igual des de l'oficina i des de casa, cosa que elimina l'incentiu de saltar-se el control.
- Es combina amb nivells d'accés per context: dispositiu corporatiu verificat, disc xifrat, pantalla bloquejada, país permès.
I el seu límit honest: IAP protegeix l'accés a aplicacions HTTP i a SSH/RDP per túnel. No és un substitut de la segmentació de xarxa ni d'IAM: és una capa més.
Aplicat a AlpinaShop, resol el problema de l'exercici de 07-03 —Lucía treballant des de casa— millor que cap llista d'IP:
# Nivell d acces basat en el dispositiu, no en la IP
gcloud access-context-manager levels create dispositivo_gestionado \
--title="Dispositiu corporatiu verificat" \
--basic-level-spec=dispositivo.yaml \
--policy=POLICY_ID# dispositivo.yaml
- devicePolicy:
requireScreenlock: true
requireCorpOwned: true
allowedEncryptionStatuses:
- ENCRYPTED
osConstraints:
- osType: DESKTOP_MAC
minimumVersion: "14.0"
- osType: DESKTOP_WINDOWS
minimumVersion: "10.0"
regions:
- ES
- FR
- PTEs llegeix així: pot entrar qui faci servir un equip propietat de l'empresa, xifrat, amb bloqueig de pantalla, amb sistema operatiu actualitzat, des d'Espanya, França o Portugal. La IP ha deixat d'importar, que és exactament el punt.
- Identitat: revisió completa del disseny IAM
La identitat és el nou perímetre. En un núvol ben muntat, la immensa majoria dels incidents greus comencen per una credencial, no per un port obert.
Els rols bàsics: eliminar-los
Owner, Editor i Viewer existeixen des d'abans que IAM tingués rols granulars i no s'haurien d'usar mai en producció:
| Rol bàsic | Què inclou realment |
|---|---|
Viewer |
Lectura de gairebé tot, incloses moltes dades |
Editor |
Modificar i esborrar gairebé qualsevol recurs del projecte |
Owner |
Editor + gestionar permisos + vincular facturació |
Auditoria immediata:
for P in alpinashop-prod alpinashop-dev alpinashop-datos alpinashop-cicd alpinashop-red; do
echo "=== $P ==="
gcloud projects get-iam-policy "$P" --format=json \
| jq -r '.bindings[] | select(.role|test("^roles/(owner|editor|viewer)$")) |
"\(.role): \(.members|join(", "))"'
doneEl que cal trobar i per què:
| Troballa | Risc | Acció |
|---|---|---|
Una persona amb Owner en producció |
Pot esborrar-ho tot i treure l'auditoria | Substituir per rols concrets |
<numero>[email protected] amb Editor |
Compte per defecte de Compute. Qualsevol càrrega que l'hereta té permís per a tot | Desactivar-lo i usar comptes propis |
<numero>@cloudbuild.gserviceaccount.com amb Editor |
El pipeline pot modificar qualsevol cosa | Rol acotat |
allUsers o allAuthenticatedUsers en qualsevol vincle |
Públic. És una fuita, no un risc | Treure-ho immediatament |
El compte per defecte de Compute mereix un paràgraf propi perquè és, amb diferència, la fallada més estesa de Google Cloud. Existeix a tots els projectes, històricament venia amb Editor, i qualsevol VM, funció o servei que no especifiqui un altre compte l'hereta. Una vulnerabilitat a la teva aplicació web passa de «llegir una base de dades» a «administrar el projecte sencer». La política d'organització automaticIamGrantsForDefaultServiceAccounts (07-07) ho evita en projectes nous; en els existents cal arreglar-ho a mà.
El disseny objectiu d'AlpinaShop
| Identitat | Producció | Desenvolupament | Dades | CI/CD | Xarxa |
|---|---|---|---|---|---|
gcp-infra@ (Marta) |
Rols d'operació; owner ningú | editor |
viewer |
builds.editor |
networkAdmin, securityAdmin |
gcp-desarrollo@ (Dani) |
run.viewer, logging.viewer, errorreporting.viewer |
editor |
— | builds.viewer |
networkViewer |
gcp-datos@ (Lucía) |
— | — | bigquery.dataEditor, bigquery.jobUser |
— | networkViewer |
gcp-seguridad@ |
securityReviewer, logging.viewer |
ídem | ídem | ídem | ídem |
gcp-facturacion@ |
billing.viewer |
ídem | ídem | ídem | ídem |
sa-catalogo-web |
3 permisos concrets | — | — | — | — |
sa-deploy-prod |
run.developer + serviceAccountUser |
— | — | — | — |
Ningú no és Owner de producció. És la decisió de 03-04 que més discussió genera i la que més valor té: si ningú no pot saltar-se els controls, els controls són reals. Per a les emergències existeix el procediment d'accés de trencament de vidre de l'apartat 5, que és auditat i temporal.
Comptes de servei sense claus
La regla, ja establerta a 03-04 i que aquí es tanca:
Una clau JSON de compte de servei descarregada és una contrasenya permanent sense caducitat que qualsevol pot copiar.
Alternatives, per ordre de preferència:
| Situació | Solució sense claus |
|---|---|
| Càrrega dins de GCP | Identitat adjunta: la VM, el servei de Cloud Run o el pod la porta posada |
| GKE | Workload Identity |
| CI/CD des de GitHub | Workload Identity Federation (ja en ús des de 06-02) |
| Persona que necessita actuar com un compte | Impersonació amb credencials de curta durada |
| Sistema local que no pot federar | Clau, amb rotació automatitzada i alerta d'ús |
Cerca de claus existents a tota l'organització:
for P in $(gcloud projects list --format='value(projectId)'); do
for SA in $(gcloud iam service-accounts list --project="$P" --format='value(email)' 2>/dev/null); do
gcloud iam service-accounts keys list --iam-account="$SA" --project="$P" \
--managed-by=user --format="value(name,validAfterTime)" 2>/dev/null \
| sed "s|^|$P $SA |"
done
done--managed-by=user és la clau de la comanda: filtra les claus descarregables i descarta les que gestiona Google internament, que són inofensives i omplirien la sortida de soroll.
- Elevació temporal de privilegis i federació
El problema del permís permanent
Marta necessita compute.securityAdmin per tocar el tallafoc. L'usa un cop al mes. La resta del temps, aquest permís només aporta risc: si li roben la sessió un dimarts qualsevol, l'atacant pot obrir el tallafoc.
Privileged Access Manager (PAM) ho resol amb permisos que es demanen, es justifiquen, s'aproven i caduquen sols.
gcloud pam entitlements create firewall-emergencia \
--location=global \
--project=alpinashop-red \
--entitlement-file=derecho.yaml# derecho.yaml
privilegedAccess:
gcpIamAccess:
resourceType: cloudresourcemanager.googleapis.com/Project
resource: projects/alpinashop-red
roleBindings:
- role: roles/compute.securityAdmin
maxRequestDuration: 7200s # maxim 2 hores
eligibleUsers:
- principals:
- group:[email protected]
requesterJustificationConfig:
notMandatory: {} # en emergencies no s exigeix text llarg
approvalWorkflow:
manualApprovals:
requireApproverJustification: true
steps:
- approvers:
- principals:
- group:[email protected]El que canvia:
| Permís permanent | Elevació temporal | |
|---|---|---|
| Finestra d'exposició | Sempre | 2 hores al mes |
| Traçabilitat | Un registre entre milers | Una sol·licitud amb justificació |
| Aprovació | Cap | Una altra persona |
| Revocació | Algú se n'ha de recordar | Automàtica |
I el matís important per a una pime: si l'aprovador és l'única persona que pot aprovar i és de vacances, el procés bloqueja una emergència. Hi ha d'haver un camí de trencament de vidre: un dret amb aprovació automàtica, durada d'una hora, i alerta immediata al canal de seguretat quan s'usa. No s'impedeix; es fa sorollós. És la mateixa filosofia que el procediment d'emergència de Terraform a 06-07: quan no hi pot haver control preventiu, hi ha d'haver control detectiu.
Federació d'identitat
Workload Identity Federation permet que una identitat externa —GitHub Actions, un clúster d'un altre núvol, un proveïdor OIDC— obtingui credencials de curta durada de Google Cloud sense cap clau. AlpinaShop ja ho fa servir des de 06-02.
El punt de seguretat que gairebé tothom configura malament és la condició d'atributs:
# MALAMENT: qualsevol repositori de GitHub del mon pot obtenir credencials
--attribute-condition="assertion.repository_owner=='alpinashop'"Aquesta condició sembla restrictiva i no ho és tant: si algú crea una organització de GitHub anomenada alpinashop, entra. I encara que no fos així, qualsevol branca o pull request del repositori podria desplegar en producció.
# BE: repositori concret, per ID numeric, i nomes la branca principal
--attribute-condition="assertion.repository_id=='123456789' &&
assertion.ref=='refs/heads/main' &&
assertion.repository_visibility=='private'"repository_id és numèric i immutable: no es pot suplantar canviant el nom. Aquest és el detall que separa una federació segura d'una que només ho sembla.
- Cadena de subministrament del programari
És el vector que més ha crescut els darrers anys, i el que menys atenció rep a les pimes. No cal atacar la teva aplicació si es pot atacar una biblioteca que la teva aplicació instal·la.
flowchart LR
DEP["Dependències<br/>PyPI, npm"] --> CODE["Codi a GitHub"]
CODE --> BUILD["Cloud Build"]
BUILD --> IMG["Imatge a<br/>Artifact Registry"]
IMG --> RUN["Cloud Run"]
S1["Assured OSS<br/>+ escaneig de dependències"] -.-> DEP
S2["Revisió obligatòria<br/>+ signatura de commits"] -.-> CODE
S3["Compilació reproduïble<br/>+ procedència SLSA"] -.-> BUILD
S4["Escaneig de vulnerabilitats<br/>+ atestat"] -.-> IMG
S5["Binary Authorization"] -.-> RUN
style S5 fill:#e6f4ea,stroke:#34a853
Escaneig de vulnerabilitats a Artifact Registry
gcloud services enable containerscanning.googleapis.com --project=alpinashop-prod
# Consultar les vulnerabilitats de la imatge desplegada
gcloud artifacts docker images list-vulnerabilities \
europe-west1-docker.pkg.dev/alpinashop-prod/alpinashop/catalogo:a3f91c2 \
--format="table(vulnerability.severity, vulnerability.packageIssue[0].affectedPackage,
vulnerability.packageIssue[0].fixedVersion)"I el pas que converteix l'escaneig en un control: fer fallar la compilació si hi ha vulnerabilitats crítiques amb pedaç disponible.
# Pas de cloudbuild.yaml
- id: comprobar-vulnerabilidades
name: gcr.io/google.com/cloudsdktool/cloud-sdk
entrypoint: bash
args:
- -c
- |
set -e
sleep 60 # donar temps a l escaneig
CRITICAS=$(gcloud artifacts docker images list-vulnerabilities \
"${_IMAGEN}:$COMMIT_SHA" --format=json \
| jq '[.[] | select(.vulnerability.severity=="CRITICAL")
| select(.vulnerability.packageIssue[0].fixedVersion.fullName != "")] | length')
echo "Vulnerabilitats critiques AMB PEDAC: $$CRITICAS"
[ "$$CRITICAS" -eq 0 ] || { echo "COMPILACIO BLOQUEJADA"; exit 1; }El matís de fixedVersion no és un tecnicisme: bloquejar per vulnerabilitats sense pedaç disponible paralitza el desenvolupament sense millorar la seguretat, perquè no hi ha res a fer llevat de canviar de dependència. Es bloqueja el que es pot arreglar; la resta es registra, se'n valora el risc i es decideix.
Imatges base mínimes i reproduïbles
| Imatge base | Mida típica | Paquets | Superfície |
|---|---|---|---|
ubuntu:22.04 |
~78 MB | ~100 | Alta: shell, gestor de paquets, utilitats |
python:3.12 |
~1 GB | ~400 | Molt alta |
python:3.12-slim |
~130 MB | ~120 | Mitjana |
gcr.io/distroless/python3 |
~50 MB | Mínims | Baixa: sense shell |
scratch (binaris estàtics) |
Mida del binari | 0 | Nul·la |
Sense shell, un atacant que aconsegueixi execució de codi no pot llançar sh, ni curl, ni wget. No és invulnerable, però la majoria de les eines de post-explotació deixen de funcionar.
I la reproduïbilitat, que és el que fa verificable tot l'anterior:
# MALAMENT: "latest" canvia sota els teus peus. La imatge d avui no es la d ahir
FROM python:3.12-slim
# BE: digest immutable. Aquesta imatge es exactament aquesta, sempre
FROM python:3.12-slim@sha256:2d3f4a1b9c8e7d6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f
WORKDIR /app
COPY requirements.txt .
# Instal.lar amb hashes verificats: si una dependencia canvia, falla
RUN pip install --no-cache-dir --require-hashes -r requirements.txt
COPY . .
USER 1000:1000 # MAI root
CMD exec gunicorn --bind :$PORT --workers 4 --threads 20 main:appLes tres línies que importen: digest en lloc d'etiqueta, --require-hashes perquè una dependència manipulada faci fallar la instal·lació, i USER 1000 per no executar com a root.
SLSA i procedència
SLSA (Supply-chain Levels for Software Artifacts) és un marc amb nivells de garantia sobre com es va construir un artefacte. Cloud Build genera procedència verificable de manera nativa:
gcloud artifacts docker images describe \
europe-west1-docker.pkg.dev/alpinashop-prod/alpinashop/catalogo:a3f91c2 \
--show-provenanceLa procedència respon amb signatura criptogràfica a: quin commit exacte, quines instruccions de compilació, quina màquina, quin moment. Serveix per al que en un incident és una pregunta d'hores: aquesta imatge que està corrent en producció es va construir des del nostre codi, o algú la va publicar a mà?
| Nivell SLSA | Què garanteix | Com s'assoleix a GCP |
|---|---|---|
| 1 | Existeix procedència | Cloud Build la genera sola |
| 2 | Procedència signada per un servei de compilació | Cloud Build gestionat |
| 3 | Compilació aïllada i no falsificable | Cloud Build amb treballadors aïllats |
Binary Authorization: tancar el cercle
Ja es va presentar a 07-01. Aquí és on encaixa: és el control que impedeix que arribi a producció una imatge que no va passar pel procés.
gcloud container binauthz policy import - <<'EOF'
defaultAdmissionRule:
evaluationMode: REQUIRE_ATTESTATION
enforcementMode: DRYRUN_AUDIT_LOG_ONLY # comencar SEMPRE aqui
requireAttestationsBy:
- projects/alpinashop-cicd/attestors/escaneo-superado
- projects/alpinashop-cicd/attestors/aprobacion-marta
EOFI aplica a Cloud Run, no només a GKE, cosa que el fa directament rellevant per a AlpinaShop després de 07-02:
Dependències: Assured Open Source
Assured Open Source Software és un servei pel qual Google distribueix paquets de codi obert que ell mateix fa servir: els compila a la seva infraestructura, els escaneja, els signa i els dona procedència SLSA.
El seu valor és acotat i convé dir-ho: cobreix un catàleg de paquets populars de Java i Python, no tot el que instal·les. Per a AlpinaShop, amb una desena de dependències comunes, la majoria estarien cobertes. No és una bala de plata; és reduir la superfície on has de confiar cegament.
- Dades: classificació, xifratge, pseudonimització i esborrat
Classificar abans de protegir
No es pot protegir el que no se sap què és. La classificació de les dades d'AlpinaShop:
| Nivell | Què inclou | Controls exigits |
|---|---|---|
| Públic | Catàleg, preus, fotos | Cap d'especial |
| Intern | Mètriques de vendes, inventari | IAM per grup |
| Confidencial | Comandes, adreces, correus | IAM + CMEK + auditoria d'accés a dades |
| Restringit | Dades de pagament, documents d'identitat | No s'emmagatzemen (els té la passarel·la) |
La quarta fila és la millor decisió de seguretat de tot el curs, i no és tècnica: la dada que no guardes no es pot filtrar. AlpinaShop no emmagatzema números de targeta perquè la passarel·la retorna un testimoni. Això elimina de cop l'abast complet de PCI-DSS sobre la seva infraestructura.
Descobriment amb Sensitive Data Protection
A 04-07 es va presentar DLP —avui Sensitive Data Protection— per al govern de la dada. Aquí es fa servir com a control de seguretat: trobar dades personals on no haurien de ser.
{
"inspectJob": {
"storageConfig": {
"bigQueryOptions": {
"tableReference": {
"projectId": "alpinashop-datos",
"datasetId": "alpinashop_analitica",
"tableId": "eventos_web"
},
"sampleMethod": "RANDOM_START"
}
},
"inspectConfig": {
"infoTypes": [
{"name": "EMAIL_ADDRESS"},
{"name": "PHONE_NUMBER"},
{"name": "CREDIT_CARD_NUMBER"},
{"name": "SPAIN_DNI_NUMBER"},
{"name": "IBAN_CODE"}
],
"minLikelihood": "LIKELY",
"includeQuote": false
},
"actions": [
{"saveFindings": {"outputConfig": {"table": {
"projectId": "alpinashop-datos", "datasetId": "seguridad", "tableId": "hallazgos_dlp"}}}}
]
}
}Dues decisions del fitxer:
includeQuote: false: no desar el fragment trobat. Desar el número de targeta detectat a la taula de troballes seria crear una segona còpia del problema. Un error real i freqüent.SPAIN_DNI_NUMBER: existeixen detectors específics per país. Fer servir només els genèrics deixa fora el més rellevant a Espanya.
El que es troba sempre, i AlpinaShop no en va ser excepció: correus electrònics en camps de text lliure de comentaris, telèfons al camp «observacions de la comanda», i adreces completes en registres d'aplicació de fa mesos. Cap no era intencionat. Els tres són dades personals a efectes del RGPD.
Xifratge i CMEK
Google xifra tot en repòs per defecte, sense configurar res. CMEK (03-06) hi afegeix que la clau la controles tu a Cloud KMS:
| Xifratge per defecte | CMEK | |
|---|---|---|
| Qui controla la clau | Tu, a alpinashop-keyring |
|
| Rotació | Automàtica de Google | Tu defineixes el període |
| Revocar l'accés a les dades | No és possible | Deshabilitant la clau |
| Registre de l'ús de la clau | No | Sí, als registres de KMS |
| Cost | Inclòs | Cost de KMS + operacions |
| Complexitat | Cap | Gestió del cicle de vida |
El «botó vermell» que dona CMEK. Si es detecta una intrusió en curs, deshabilitar la clau fa il·legibles les dades xifrades amb ella en segons, fins i tot per a qui tingui permisos de lectura. És una capacitat de contenció que sense CMEK no existeix.
Amb la seva contrapartida, que cal dir clarament: si perds la clau, perds les dades. Definitivament. Per això KMS impedeix l'esborrat immediat i imposa un període de destrucció programada.
Pseudonimització
Perquè Lucía analitzi comportament de compra no necessita saber qui és cada client:
-- Vista pseudonimitzada: analitica sense identificar ningu
CREATE OR REPLACE VIEW `alpinashop-datos.alpinashop_analitica.pedidos_seudonimos` AS
SELECT
TO_HEX(SHA256(CONCAT(cliente_email, @sal_secreta))) AS client_id,
DATE(fecha_pedido) AS data,
SUBSTR(codigo_postal, 1, 2) AS provincia,
categoria_producto,
importe_total,
canal
FROM `alpinashop-datos.alpinashop_analitica.pedidos`;Tres tècniques en cinc línies: hash amb sal perquè el mateix client sigui el mateix client_id sense poder revertir-ho; generalització del codi postal als dos primers dígits, que dona la província sense assenyalar el barri; i omissió de nom, adreça i telèfon, que no aporten res a l'anàlisi.
I l'advertiment honest: la pseudonimització no és anonimització. Amb la sal, la dada continua sent reidentificable i per tant continua sent una dada personal a efectes del RGPD. Redueix el risc; no elimina l'obligació.
Retenció i esborrat
El RGPD obliga a no conservar dades personals més temps del necessari, i a poder esborrar-les a petició de l'interessat.
# Cicle de vida del data lake
resource "google_storage_bucket" "datalake" {
name = "alpinashop-datalake"
location = "EUROPE-WEST1"
lifecycle_rule {
condition { age = 90 }
action { type = "SetStorageClass" storage_class = "NEARLINE" }
}
lifecycle_rule {
condition { age = 365 }
action { type = "SetStorageClass" storage_class = "COLDLINE" }
}
lifecycle_rule {
condition { age = 2555 } # 7 anys: obligacio fiscal
action { type = "Delete" }
}
versioning { enabled = true } # proteccio contra esborrat accidental i ransomware
}-- Caducitat automatica de particions a BigQuery
ALTER TABLE `alpinashop-datos.alpinashop_analitica.eventos_web`
SET OPTIONS (partition_expiration_days = 400);I l'esborrat a petició, que és on la majoria d'empreses descobreix que la seva arquitectura no ho contemplava:
-- Procediment de dret de supressio
CREATE OR REPLACE PROCEDURE `alpinashop-datos.alpinashop_analitica.borrar_cliente`(email STRING)
BEGIN
-- 1. Anonimitzar les comandes: es conserven per obligacio fiscal, sense identificar
UPDATE `alpinashop-datos.alpinashop_analitica.pedidos`
SET cliente_email = 'ESBORRAT', cliente_nombre = 'ESBORRAT',
direccion = 'ESBORRAT', telefono = NULL
WHERE cliente_email = email;
-- 2. Esborrar de les taules on no hi ha obligacio de conservacio
DELETE FROM `alpinashop-datos.alpinashop_analitica.eventos_web` WHERE usuario_email = email;
DELETE FROM `alpinashop-datos.alpinashop_analitica.carritos` WHERE cliente_email = email;
-- 3. Registrar l execucio del dret (sense la dada esborrada)
INSERT INTO `alpinashop-datos.cumplimiento.solicitudes_rgpd`
VALUES (TO_HEX(SHA256(email)), CURRENT_TIMESTAMP(), 'SUPRESSIO', SESSION_USER());
END;Fixa't en el punt 1: les comandes no s'esborren, s'anonimitzen, perquè la normativa fiscal obliga a conservar les factures. El dret de supressió no és absolut i col·lideix amb altres obligacions legals; resoldre aquesta col·lisió no és una decisió tècnica i s'ha de documentar amb assessorament jurídic.
- Detecció: Security Command Center i els registres d'auditoria
Security Command Center
SCC és el centre de seguretat de Google Cloud. Detecta configuracions insegures, vulnerabilitats i amenaces actives.
| Nivell | Què inclou | Cost |
|---|---|---|
| Estàndard | Security Health Analytics bàsic, troballes de configuració, inventari | Gratuït |
| Premium | Event Threat Detection, Container Threat Detection, VM Threat Detection, compliment normatiu (CIS, PCI, ISO), simulació de rutes d'atac | De pagament, orientat a empresa |
| Enterprise | Premium + multinúvol + gestió de casos + intel·ligència de Mandiant | De pagament |
Què detecta de debò el nivell gratuït, que és el que farà servir una pime:
| Troballa | Gravetat | Freqüència amb què apareix |
|---|---|---|
| Bucket accessible públicament | Crítica | Constant |
| Compte de servei amb rol d'administrador | Alta | Molt freqüent |
Regla de tallafoc que permet 0.0.0.0/0 a un port d'administració |
Crítica | Freqüent |
| Instància de Cloud SQL amb IP pública sense SSL | Alta | Freqüent |
| Claus de compte de servei de més de 90 dies | Mitjana | Gairebé sempre |
| MFA no activat en comptes d'administrador | Crítica | Freqüent |
| Registre d'auditoria desactivat | Alta | Ocasional |
Amb Premium s'hi afegeix Event Threat Detection, que analitza els registres en temps real buscant comportament —no configuració—: mineria de criptomonedes en una VM, exfiltració de dades de BigQuery, ús de credencials des d'una geografia impossible, creació d'un compte de servei seguida immediatament d'una concessió de permisos.
El criteri honest per a AlpinaShop: començar amb el nivell gratuït i atendre de debò les seves troballes, que ja és més del que fa la majoria. Premium es justifica quan hi ha alguna cosa a vigilar activament, un requisit de compliment normatiu que ho exigeixi, o algú amb temps per respondre al que detecti. Comprar detecció que ningú no mira és pitjor que no comprar-la, perquè genera la sensació d'estar protegit.
gcloud scc findings list ORGANIZATION_ID \
--filter='state="ACTIVE" AND severity="CRITICAL"' \
--format="table(category, resourceName, eventTime)"Els registres d'auditoria com a font de veritat
Es desenvolupen a fons a 07-07. Aquí, el mínim indispensable:
| Tipus | Què registra | Activat per defecte? |
|---|---|---|
| Activitat d'administrador | Canvis de configuració i permisos | Sí, i no es pot desactivar |
| Accés a dades | Lectures i escriptures de dades | No. Cal activar-ho i costa |
| Esdeveniments del sistema | Accions de Google sobre els teus recursos | Sí |
| Denegacions de política | Peticions rebutjades per polítiques | Sí |
Que «accés a dades» estigui desactivat per defecte té una conseqüència que cal assumir conscientment: sense activar-ho, no pots saber qui va llegir les dades dels teus clients. Per a AlpinaShop, activar-ho a alpinashop-datos i als buckets amb dades personals no és opcional si vol respondre a una bretxa.
Tres consultes que cal tenir escrites abans de necessitar-les:
-- 1. Canvis de permisos IAM en els ultims 7 dies
SELECT timestamp,
protopayload_auditlog.authenticationInfo.principalEmail AS qui,
protopayload_auditlog.methodName AS que,
protopayload_auditlog.resourceName AS on
FROM `alpinashop-prod.auditoria.cloudaudit_googleapis_com_activity`
WHERE protopayload_auditlog.methodName LIKE '%setIamPolicy%'
AND DATE(timestamp) >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
ORDER BY timestamp DESC-- 2. Us de credencials des de fora d Espanya
SELECT DISTINCT
protopayload_auditlog.authenticationInfo.principalEmail AS qui,
protopayload_auditlog.requestMetadata.callerIp AS ip,
protopayload_auditlog.requestMetadata.callerSuppliedUserAgent AS agent,
COUNT(*) AS peticions
FROM `alpinashop-prod.auditoria.cloudaudit_googleapis_com_activity`
WHERE DATE(timestamp) >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
AND NET.IP_TO_STRING(NET.IP_FROM_STRING(
protopayload_auditlog.requestMetadata.callerIp)) NOT LIKE '88.20.145.%'
GROUP BY qui, ip, agent
HAVING peticions > 10
ORDER BY peticions DESC-- 3. Qui ha creat o descarregat claus de compte de servei
SELECT timestamp,
protopayload_auditlog.authenticationInfo.principalEmail AS qui,
protopayload_auditlog.resourceName AS compte
FROM `alpinashop-prod.auditoria.cloudaudit_googleapis_com_activity`
WHERE protopayload_auditlog.methodName =
'google.iam.admin.v1.CreateServiceAccountKey'
ORDER BY timestamp DESCLa tercera mereix una alerta permanent: en una organització que federa identitats i fa servir impersonació, crear una clau JSON és un esdeveniment excepcional que sempre s'ha de mirar.
- Resposta: les dues primeres hores d'un incident
Aquí hi ha el que gairebé cap curs inclou i el que de debò marca la diferència. Un guió realista per a un equip de tres persones.
Escenari: són les 23:40 d'un dijous d'octubre, en plena campanya. Arriba una alerta d'SCC: «Anomalous IAM grant: el compte sa-informes-nocturnos ha concedit roles/owner a un compte extern».
Minuts 0-10: valorar, no actuar
No es toca res encara. El primer impuls —esborrar el compte, tallar accessos— destrueix evidència i de vegades avisa l'atacant. El primer és respondre tres preguntes:
- És real o un fals positiu? Hi ha un canvi programat aquesta nit? Hi ha algú treballant?
- Està en curs? Continua havent-hi activitat d'aquesta identitat ara mateix?
- Quin abast té? Què pot tocar aquesta credencial?
# Activitat d aquesta identitat en l ultima hora
gcloud logging read '
protoPayload.authenticationInfo.principalEmail="[email protected]"
AND timestamp>="'$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ)'"' \
--project=alpinashop-prod --limit=200 \
--format="table(timestamp, protoPayload.methodName, protoPayload.requestMetadata.callerIp)"Minuts 10-30: contenir
Si és real, tallar sense destruir. L'ordre importa:
# 1. Treure el permis concedit indegudament
gcloud projects remove-iam-policy-binding alpinashop-prod \
--member="user:[email protected]" --role="roles/owner"
# 2. DESHABILITAR el compte compromes (no esborrar-lo: es perd l evidencia)
gcloud iam service-accounts disable \
[email protected]
# 3. Revocar els testimonis vius: sense aixo, els testimonis ja emesos continuen valent
# fins a una hora encara que el compte estigui deshabilitat
gcloud iam service-accounts keys list \
--iam-account=sa-informes-nocturnos@alpinashop-prod.iam.gserviceaccount.com
# 4. Congelar l evidencia: copiar els registres rellevants a un bucket amb retencio
gcloud logging read 'timestamp>="'$INICIO'"' --project=alpinashop-prod \
--format=json > /tmp/incidente-$(date +%F).json
gcloud storage cp /tmp/incidente-*.json gs://alpinashop-evidencia-forense/El pas 3 és el que s'oblida sempre. Deshabilitar un compte no invalida els testimonis d'accés ja emesos, que viuen fins a una hora. Durant aquesta hora, l'atacant continua a dins encara que el tauler digui que el compte està deshabilitat.
Minuts 30-60: avaluar l'abast
Les preguntes, en aquest ordre:
| Pregunta | Com es respon |
|---|---|
| Què va fer aquesta identitat els últims 30 dies? | Registres d'activitat d'administrador |
| Va accedir a dades personals? | Registres d'accés a dades (si estaven activats) |
| Va sortir informació? | Flow Logs, registres de VPC-SC, transferències de Cloud Storage |
| Va crear persistència? | Buscar comptes nous, claus noves, regles de tallafoc noves, funcions noves |
| Com va entrar? | Origen de les credencials: clau filtrada? repositori públic? portàtil? |
La cerca de persistència és la part que més es descuida i la que fa que un incident es repeteixi la setmana següent:
# Recursos creats en les ultimes 48 hores a tota l organitzacio
gcloud asset search-all-resources --scope=organizations/ORG_ID \
--query="createTime>$(date -u -d '48 hours ago' +%Y-%m-%dT%H:%M:%SZ)" \
--format="table(name, assetType, createTime)"Hora 1-2: comunicar
| Destinatari | Quan | Què es diu |
|---|---|---|
| Equip intern | Immediat | Què ha passat i qui fa què |
| Direcció | Tan bon punt es confirmi | Impacte en el negoci, en llenguatge de negoci |
| Assessor jurídic / DPD | Abans de les 24 h | Si hi ha dades personals implicades |
| AEPD | Abans de 72 h des del coneixement | Si hi ha risc per als drets de les persones |
| Clients afectats | Segons valoració jurídica | Si el risc és alt |
| Asseguradora | Segons pòlissa | Sol haver-hi terminis estrictes |
Les 72 hores del RGPD per notificar l'autoritat de control no són negociables i el rellotge comença quan en tens coneixement, no quan acabes la investigació. És la raó número u per la qual cal trucar a l'assessor jurídic la primera hora, encara que encara no se'n conegui l'abast.
El que cal tenir preparat ABANS
Un incident no és moment d'improvisar. La carpeta que cal tenir escrita avui:
- Telèfons: intern, direcció, assessor jurídic, asseguradora, suport de Google Cloud.
- La comanda de contenció ja escrita, provada i amb permisos verificats.
- Un bucket d'evidència amb retenció bloquejada i creat fora del projecte que pot estar compromès.
- Un canal de comunicació alternatiu — si el correu corporatiu està compromès, no et pots coordinar per correu.
- L'accés d'emergència provat: que Marta pugui entrar encara que el seu compte habitual estigui bloquejat.
- Un simulacre a l'any. Mitja hora en una sala, sobre un escenari escrit. Descobreix més forats que qualsevol auditoria de configuració.
- Compliment: què aporta Google i què continua sent teu
El repartiment de 01-05, revisat ara amb tot el context:
| Aspecte | Tu | |
|---|---|---|
| Seguretat física dels centres de dades | ✅ | — |
| Maquinari, xarxa física, hipervisor | ✅ | — |
| Xifratge en repòs per defecte | ✅ | — |
| Aplicació de pedaços al sistema operatiu | ✅ en serveis gestionats | ❌ a Compute Engine |
| Configuració d'IAM | — | ❌ Teu |
| Regles de tallafoc | — | ❌ Teu |
| Seguretat del codi de la teva aplicació | — | ❌ Teu |
| Classificació de les dades | — | ❌ Teu |
| Gestió d'accessos d'empleats | — | ❌ Teu |
| Còpies de seguretat i la seva prova | — | ❌ Teu (07-06) |
| Resposta a incidents en la teva capa | — | ❌ Teu |
Les certificacions de Google —ISO 27001, ISO 27017, ISO 27018, SOC 1/2/3, PCI-DSS com a proveïdor, ENS a Espanya, esquemes sectorials— acrediten la seva infraestructura. Es descarreguen del Compliance Reports Manager.
I aquí hi ha el malentès més car del compliment normatiu al núvol:
Que Google estigui certificat en ISO 27001 no certifica la teva empresa. Que la seva infraestructura sigui apta per a PCI-DSS no fa conforme la teva botiga. El que et donen és que la capa de sota ja està auditada, cosa que redueix molt el teu abast — però la teva configuració, el teu codi, els teus processos i les teves persones continuen sent teus i continuen sent auditables.
Per a AlpinaShop, com a botiga en línia espanyola:
| Obligació | Situació | Pendent |
|---|---|---|
| RGPD i LOPDGDD | S'aplica plenament | Registre d'activitats de tractament; contracte d'encarregat amb Google (les Cloud Data Processing Addendum); anàlisi de transferències internacionals |
| PCI-DSS | Abast mínim: no emmagatzema targetes | Mantenir-ho així; qüestionari SAQ-A |
| LSSI-CE | Avís legal, galetes | Revisió periòdica |
| Llei de serveis digitals | Segons mida | Revisar amb assessoria |
| Esquema Nacional de Seguretat | No s'aplica (no és sector públic) | — |
La documentació que cal tenir, i que en una inspecció es demana abans que cap configuració tècnica:
- Registre d'activitats de tractament (art. 30 RGPD).
- Contracte d'encarregat del tractament amb Google Cloud.
- Avaluació d'impacte (AIPD) si hi ha tractament d'alt risc.
- Política de seguretat de la informació, encara que siguin quatre pàgines.
- Procediment de resposta a bretxes, amb els terminis de l'apartat 9.
- Registre d'accessos a dades personals — que és just el que donen els registres d'accés a dades.
- Anàlisi de transferències internacionals i garanties aplicades.
Es repeteix perquè importa: aquesta taula és orientativa i docent. Un professional de compliment normatiu ha de validar què s'aplica al teu cas concret, especialment pel que fa al RGPD, a les transferències internacionals i a l'abast de PCI-DSS.
- Llista de comprovació d'enduriment
Accionable sobre tot el que s'ha construït al curs. La columna d'estat és la d'AlpinaShop avui.
Identitat i accés
| # | Control | Estat |
|---|---|---|
| 1 | MFA obligatori per a tots els comptes, amb clau física per a administradors | ⚠️ MFA sí, claus no |
| 2 | Cap rol bàsic (owner/editor/viewer) en producció |
⚠️ Editor a cloudbuild |
| 3 | Permisos només a grups, mai a persones | ✅ |
| 4 | Zero claus JSON de comptes de servei | ⚠️ Una pendent |
| 5 | Compte per defecte de Compute desactivat o sense permisos | ❌ |
| 6 | Federació d'identitat amb condició per repository_id i branca |
✅ |
| 7 | Elevació temporal (PAM) per a permisos administratius | ❌ |
| 8 | Revisió trimestral d'accessos documentada | ❌ |
| 9 | Procés de baixa d'empleats que revoca en 24 h | ⚠️ Informal |
Xarxa
| # | Control | Estat |
|---|---|---|
| 10 | Sense IP públiques a les VM; sortida per Cloud NAT | ✅ |
| 11 | Tallafoc amb denegació per defecte i regles per etiqueta | ✅ |
| 12 | Cloud SQL només amb IP privada | ✅ |
| 13 | VPC compartida amb permisos per subxarxa | ✅ (07-03) |
| 14 | VPC Service Controls al voltant de les dades | ⚠️ En mode de prova |
| 15 | Flow Logs activats amb mostreig | ✅ |
| 16 | Cloud Armor amb regles gestionades i límit de taxa | ✅ |
| 17 | Accés administratiu només per IAP, sense SSH públic | ✅ |
Càrrega de treball
| # | Control | Estat |
|---|---|---|
| 18 | Contenidors sense root i sense privilegis | ✅ |
| 19 | Compte de servei propi i mínim per servei | ✅ |
| 20 | ingress restringit al balancejador |
✅ (07-02) |
| 21 | Imatges base mínimes fixades per digest | ⚠️ Slim, per etiqueta |
| 22 | Escaneig de vulnerabilitats que bloqueja la compilació | ❌ Escaneja, no bloqueja |
| 23 | Binary Authorization en mode de prova o aplicat | ❌ |
| 24 | Sense secrets en variables d'entorn ni al codi | ✅ |
Dades
| # | Control | Estat |
|---|---|---|
| 25 | Classificació de les dades documentada | ✅ |
| 26 | CMEK a les dades confidencials | ✅ |
| 27 | Sense dades de targeta emmagatzemades | ✅ |
| 28 | Escaneig periòdic amb Sensitive Data Protection | ⚠️ Un cop |
| 29 | Polítiques de retenció i esborrat automatitzades | ⚠️ Parcial |
| 30 | Procediment de dret de supressió provat | ❌ |
| 31 | Versionatge i protecció contra esborrat en buckets crítics | ✅ |
| 32 | Còpies de seguretat amb restauració provada | ❌ (07-06) |
Detecció i resposta
| # | Control | Estat |
|---|---|---|
| 33 | Security Command Center actiu i les seves troballes ateses | ⚠️ Actiu, sense procés |
| 34 | Registres d'accés a dades activats a les dades sensibles | ❌ |
| 35 | Registres d'auditoria exportats a un projecte separat i immutable | ❌ (07-07) |
| 36 | Alertes sobre canvis d'IAM i creació de claus | ❌ |
| 37 | Pla de resposta escrit, amb telèfons i comandes | ❌ |
| 38 | Simulacre anual d'incident | ❌ |
| 39 | Bucket d'evidència forense amb retenció bloquejada | ❌ |
Govern
| # | Control | Estat |
|---|---|---|
| 40 | Polítiques d'organització aplicades | ❌ (07-07) |
| 41 | Tota la infraestructura en Terraform i revisada | ✅ |
| 42 | Registre d'activitats de tractament | ⚠️ Desactualitzat |
| 43 | Contracte d'encarregat amb Google signat | ✅ |
Resultat: 20 ✅, 11 ⚠️, 12 ❌. No està malament per a una empresa de quaranta persones. I no és suficient.
- El deute de seguretat d'AlpinaShop, prioritzat
Cap empresa no està al 100 %. El que distingeix una organització madura no és no tenir deute, sinó saber quin té, haver-lo prioritzat i estar-lo pagant. Priorització per risc (probabilitat × impacte) davant d'esforç.
Prioritat 1 — Aquesta setmana
| # | Deute | Risc | Esforç |
|---|---|---|---|
| 1 | La clau JSON pendent. Existeix una clau de sa-dataflow-pedidos creada fa 14 mesos per a una prova. No se sap on és. Pot llegir tot el data lake |
Crític: credencial permanent perduda | 2 h |
| 2 | Compte per defecte de Compute amb Editor. Qualsevol càrrega que no especifiqui compte l'hereta |
Crític: escalada de privilegis trivial | 4 h |
| 3 | Cloud Build amb Editor en producció. Un compromís del pipeline és un compromís total |
Alt | 4 h |
| 4 | Alertes de canvis d'IAM i creació de claus. Avui ningú no se n'assabentaria | Alt: sense detecció no hi ha resposta | 2 h |
Els quatre sumen menys de dos dies de feina i són el que més redueix el risc. Començar per aquí no és opinable.
Prioritat 2 — Aquest mes
| # | Deute | Risc | Esforç |
|---|---|---|---|
| 5 | Registres d'accés a dades desactivats. Davant d'una bretxa, AlpinaShop no pot dir qui va llegir què. És un problema legal, no només tècnic | Alt | 1 dia + cost recurrent |
| 6 | Sense pla de resposta escrit. L'apartat 9 és teoria fins que existeix la carpeta | Alt | 1 dia |
| 7 | VPC-SC en mode de prova des de fa setmanes. Un control a mitges no protegeix | Mitjà-alt | 2 dies |
| 8 | Restauració de còpies mai provada. Es tracta a 07-06 | Crític si passa | 1 dia |
| 9 | Escaneig que no bloqueja. Es despleguen imatges amb vulnerabilitats crítiques pedaçables | Mitjà | 4 h |
Prioritat 3 — Aquest trimestre
| # | Deute | Risc | Esforç |
|---|---|---|---|
| 10 | Polítiques d'organització sense aplicar (07-07) | Mitjà | 3 dies |
| 11 | Sense revisió periòdica d'accessos | Mitjà | Procés |
| 12 | Claus físiques per a administradors | Mitjà | 1 dia + compra |
| 13 | Elevació temporal amb PAM | Mitjà | 2 dies |
| 14 | Binary Authorization | Baix-mitjà | 3 dies |
| 15 | Imatges per digest i --require-hashes |
Baix-mitjà | 1 dia |
| 16 | Simulacre d'incident | Mitjà | 4 h |
| 17 | Registre de tractament actualitzat | Legal | Amb assessoria |
Deute acceptat conscientment
I això també forma part de la maduresa: decidir no fer una cosa, per escrit, amb motiu.
| Decisió | Motiu |
|---|---|
| No contractar SCC Premium | No hi ha ningú que pugui atendre el que detecti. Es revisarà en superar els 10 empleats tècnics |
| No adoptar Cloud Service Mesh per a mTLS entre serveis | Hi ha un servei (DA-004). El trànsit intern ja va xifrat per la xarxa de Google |
| No xifrar a nivell d'aplicació sobre CMEK | El model d'amenaça no inclou un administrador de Google. Es revisaria amb dades de salut |
| No fer proves de penetració externes aquest any | Cost davant de maduresa actual. Primer cal pagar la prioritat 1 i 2 |
Un risc acceptat i documentat no és una fallada de seguretat: és una decisió de gestió. Un risc que ningú no ha mirat, sí.
Errors Habituals i Consells
- Confondre tenir eines amb tenir seguretat. SCC activat i ningú mirant les troballes és pitjor que no tenir-lo: genera falsa confiança.
- Deixar el compte per defecte de Compute amb
Editor. És la fallada més estesa de Google Cloud i converteix qualsevol vulnerabilitat en un compromís total del projecte. - Crear claus JSON «per provar». No s'esborren mai. Busca-les periòdicament amb
--managed-by=user. - Federar identitat sense condició d'atributs estricta. Sense
repository_idiref, qualsevol branca o repositori amb el mateix nom d'organització pot desplegar en producció. - Esborrar el compte compromès durant un incident. Destrueix evidència. Es deshabilita.
- Oblidar que els testimonis vius sobreviuen a la deshabilitació fins a una hora.
- Desar el fragment detectat per DLP. Crear una taula amb els números de targeta trobats és duplicar el problema, no resoldre'l.
- Creure que la pseudonimització és anonimització. Amb la sal, continua sent dada personal a efectes del RGPD.
- Pensar que les certificacions de Google certifiquen la teva empresa. Certifiquen la capa de sota. La teva configuració és teva.
- Bloquejar compilacions per vulnerabilitats sense pedaç disponible. Paralitza l'equip sense millorar res. Es bloqueja el que es pot arreglar.
- Activar tots els controls alhora. VPC-SC, Binary Authorization i polítiques d'organització el mateix dia és garantia de caiguda. Un cada vegada, en mode de prova primer.
- Deixar el pla de resposta per quan calgui. L'incident és el pitjor moment per escriure'l.
- Consell: fes la pregunta de la fallada única a cada capa. És mitja hora i troba més que qualsevol escàner.
- Consell: la millor mesura de seguretat és la dada que no guardes. Abans de protegir una dada, pregunta si cal emmagatzemar-la.
- Consell: un simulacre de mitja hora a l'any descobreix més forats reals que una auditoria de configuració.
- Consell: escriu el deute acceptat. Converteix un forat en una decisió, i fa que es revisi.
Exercicis
Exercici 1 — Auditoria d'identitat
Escriu un script d'auditoria que, sobre els cinc projectes d'AlpinaShop, detecti i informi de:
- Qualsevol vincle amb rols bàsics (
owner,editor,viewer). - Vincles amb
allUsersoallAuthenticatedUsersen projectes i en buckets. - Comptes de servei amb claus gestionades per l'usuari, amb la seva antiguitat.
- Comptes de servei que no s'han fet servir en 90 dies.
- Comptes de servei amb rols d'administrador.
Per a cada troballa, indica gravetat i acció recomanada. Explica a més per què el punt 4 és més important del que sembla.
Exercici 2 — Dissenyar la resposta a un incident concret
Escenari. Un dilluns al matí, un desenvolupador extern publica en un fòrum públic que ha trobat un repositori de GitHub d'AlpinaShop amb un fitxer credenciales.json a l'historial de commits. El fitxer és una clau de sa-dataflow-pedidos, esborrada del repositori fa vuit mesos però present a l'historial. Aquest compte té roles/bigquery.dataViewer sobre alpinashop_analitica i roles/storage.objectAdmin sobre alpinashop-datalake.
Escriu el pla de resposta complet amb marques de temps: què es fa en els primers 10 minuts, en els primers 30, en la primera hora i en les primeres 24 hores. Inclou les comandes, les decisions de comunicació (amb qui i quan), com es determina si hi va haver accés indegut, i quins canvis estructurals es fan després perquè no torni a passar.
Exercici 3 — Prioritzar amb pressupost limitat
La direcció d'AlpinaShop aprova 10 dies de feina de Marta i 3.000 € per a seguretat aquest trimestre. No n'hi ha més.
De la llista de deute de l'apartat 12, tria què es fa i què no, justificant cada decisió amb criteri de risc davant d'esforç. Elabora un pla per setmanes i, el més important, escriu què li dius a direcció sobre el que queda sense fer, en llenguatge que un director general entengui.
Solucions
Solució 1 — Auditoria d'identitat
#!/usr/bin/env bash
# auditoria-identidad.sh — revisio d identitat d AlpinaShop
set -uo pipefail
PROYECTOS=(alpinashop-prod alpinashop-dev alpinashop-datos alpinashop-cicd alpinashop-red)
HOY=$(date +%s)
echo "===== 1. ROLS BASICS ====="
for P in "${PROYECTOS[@]}"; do
gcloud projects get-iam-policy "$P" --format=json 2>/dev/null \
| jq -r --arg p "$P" '
.bindings[]
| select(.role | test("^roles/(owner|editor|viewer)$"))
| .role as $r
| .members[]
| "\($p) | \($r) | \(.)"'
done | while IFS='|' read -r PROY ROL MIEMBRO; do
GRAV="MITJANA"
[[ "$ROL" == *owner* ]] && GRAV="CRITICA"
[[ "$ROL" == *editor* ]] && GRAV="ALTA"
[[ "$PROY" == *prod* ]] && GRAV="CRITICA"
echo "[$GRAV] $PROY $ROL -> $MIEMBRO"
done
echo
echo "===== 2. ACCES PUBLIC ====="
for P in "${PROYECTOS[@]}"; do
gcloud projects get-iam-policy "$P" --format=json 2>/dev/null \
| jq -r --arg p "$P" '.bindings[] | select(.members[]? | test("^all(Users|AuthenticatedUsers)$"))
| "[CRITICA] \($p) PROJECTE PUBLIC: \(.role)"'
done
for B in $(gcloud storage buckets list --format='value(name)' 2>/dev/null); do
gcloud storage buckets get-iam-policy "gs://$B" --format=json 2>/dev/null \
| jq -r --arg b "$B" '.bindings[]? | select(.members[]? | test("^all(Users|AuthenticatedUsers)$"))
| "[CRITICA] BUCKET PUBLIC gs://\($b): \(.role)"'
done
echo
echo "===== 3. CLAUS JSON ====="
for P in "${PROYECTOS[@]}"; do
for SA in $(gcloud iam service-accounts list --project="$P" --format='value(email)' 2>/dev/null); do
gcloud iam service-accounts keys list --iam-account="$SA" --project="$P" \
--managed-by=user --format='value(name,validAfterTime)' 2>/dev/null \
| while read -r NOMBRE FECHA; do
[ -z "$NOMBRE" ] && continue
DIAS=$(( (HOY - $(date -d "$FECHA" +%s)) / 86400 ))
GRAV="ALTA"; [ "$DIAS" -gt 90 ] && GRAV="CRITICA"
echo "[$GRAV] $P $SA clau de $DIAS dies"
done
done
done
echo
echo "===== 4. COMPTES DE SERVEI SENSE US (90 dies) ====="
for P in "${PROYECTOS[@]}"; do
gcloud recommender insights list --project="$P" --location=global \
--insight-type=google.iam.serviceAccount.Insight \
--filter='insightSubtype=SERVICE_ACCOUNT_USAGE' \
--format="value(description)" 2>/dev/null | sed "s|^|[MITJANA] $P |"
done
echo
echo "===== 5. COMPTES DE SERVEI AMB ROLS D ADMINISTRADOR ====="
for P in "${PROYECTOS[@]}"; do
gcloud projects get-iam-policy "$P" --format=json 2>/dev/null \
| jq -r --arg p "$P" '
.bindings[]
| select(.role | test("[Aa]dmin$|^roles/owner$|^roles/iam\\.securityAdmin$"))
| .role as $r | .members[]
| select(startswith("serviceAccount:"))
| "[ALTA] \($p) \($r) -> \(.)"'
doneTaula de troballes, gravetat i acció:
| Troballa | Gravetat | Acció |
|---|---|---|
owner en producció a una persona |
Crítica | Substituir per rols concrets; usar PAM per a l'excepcional |
editor a cloudbuild en producció |
Crítica | Acotar a run.developer + serviceAccountUser |
allUsers a qualsevol lloc |
Crítica | Eliminar en el moment i revisar els registres d'accés |
| Clau JSON de més de 90 dies | Crítica | Migrar a federació o impersonació i esborrar la clau |
| Compte de servei sense ús en 90 dies | Mitjana | Deshabilitar 30 dies; si res no es trenca, esborrar |
Compte de servei amb rol *Admin |
Alta | Rol personalitzat amb els permisos reals |
Per què el punt 4 és més important del que sembla. Un compte de servei sense ús és un objectiu silenciós: ningú no vigila la seva activitat, ningú no notaria un ús anòmal, i com que no s'utilitza, ningú no recorda per què existeix ni quins permisos té. A més d'eliminar superfície d'atac, la neteja aporta una cosa més valuosa: cada compte que s'elimina redueix el soroll de l'auditoria, i una llista de vint comptes dels quals se n'entenen vint és infinitament més segura que una de seixanta dels quals se n'entenen vint.
La tècnica correcta és deshabilitar abans d'esborrar (gcloud iam service-accounts disable): si alguna cosa es trenca, es reactiva en un segon; si s'ha esborrat, cal recrear-lo i reconstruir tots els seus permisos. Trenta dies d'espera és un termini raonable, perquè captura els processos mensuals.
Solució 2 — Dissenyar la resposta a un incident concret
T+0 a T+10 min — Valorar sense actuar.
La primera decisió: això ja és públic. A diferència d'una detecció interna, aquí l'atacant potencial no només existeix: hi ha un fòrum sencer que sap de la clau. La urgència és màxima i la discreció ja no aporta res, cosa que canvia el càlcul respecte de l'apartat 9.
# 1. Confirmar que la clau existeix i continua activa
gcloud iam service-accounts keys list \
--iam-account=sa-dataflow-pedidos@alpinashop-datos.iam.gserviceaccount.com \
--managed-by=user --format="table(name, validAfterTime, validBeforeTime)"
# 2. Activitat d aquest compte en les ultimes 48 hores
gcloud logging read '
protoPayload.authenticationInfo.principalEmail="[email protected]"
AND timestamp>="'$(date -u -d '48 hours ago' +%Y-%m-%dT%H:%M:%SZ)'"' \
--project=alpinashop-datos --limit=500 \
--format="table(timestamp, protoPayload.methodName, protoPayload.requestMetadata.callerIp)"Es busca una sola cosa: peticions des d'IP que no siguin les de Dataflow. Si apareixen, l'incident passa de «credencial exposada» a «accés confirmat», amb implicacions legals immediates.
T+10 a T+30 min — Contenir.
# 1. Esborrar la clau (aqui SI que s esborra: es la credencial exposada, no l evidencia)
gcloud iam service-accounts keys delete KEY_ID \
--iam-account=sa-dataflow-pedidos@alpinashop-datos.iam.gserviceaccount.com
# 2. Deshabilitar el compte fins a entendre l abast
# (trenca el pipeline de Dataflow: s assumeix conscientment)
gcloud iam service-accounts disable \
[email protected]
# 3. Congelar evidencia FORA del projecte afectat
gcloud logging read 'timestamp>="'$(date -u -d '9 months ago' +%Y-%m-%dT%H:%M:%SZ)'"
AND protoPayload.authenticationInfo.principalEmail=~"sa-dataflow-pedidos"' \
--project=alpinashop-datos --format=json > /tmp/evidencia.json
gcloud storage cp /tmp/evidencia.json gs://alpinashop-evidencia-forense/incidente-clave/
# 4. Activar VPC-SC en mode aplicat sobre alpinashop-datos
# Encara que robessin mes credencials, les dades ja no poden sortirLa decisió difícil d'aquests vint minuts: deshabilitar el compte trenca el pipeline de comandes cap a BigQuery. Es fa igualment. Davant d'una credencial pública amb accés al data lake, l'analítica pot esperar unes hores. I és exactament la decisió que cal haver pensat abans, no en calent.
El punt 4 mereix atenció: si el perímetre hagués estat aplicat en lloc d'en mode de prova (deute #7), la clau filtrada no hauria pogut treure ni un sol byte fora de l'organització. L'incident il·lustra per què un control a mitges no és mig control.
T+30 min a T+1 h — Determinar si hi va haver accés.
-- Tot l us del compte des de la creacio de la clau, amb IP i metode
SELECT
DATE(timestamp) AS dia,
protopayload_auditlog.requestMetadata.callerIp AS ip,
protopayload_auditlog.methodName AS metode,
COUNT(*) AS n
FROM `alpinashop-datos.auditoria.cloudaudit_googleapis_com_data_access`
WHERE protopayload_auditlog.authenticationInfo.principalEmail
= '[email protected]'
GROUP BY dia, ip, metode
ORDER BY dia DESCI aquí apareix el problema que converteix aquest exercici en la millor demostració de per què el deute #5 importa: els registres d'accés a dades estan desactivats. AlpinaShop té els registres d'activitat d'administrador —sabrà si algú va canviar permisos— però no pot saber si algú va llegir la taula de comandes.
Conseqüència pràctica, i és greu: en no poder demostrar que no hi va haver accés, jurídicament cal tractar el cas com si hagués pogut haver-n'hi. Es passa de «credencial exposada sense evidència d'ús» a «possible bretxa de dades personals amb un abast que no es pot acotar». Això canvia completament la notificació a l'AEPD.
Vies alternatives d'evidència, totes pitjors:
| Font | Què aporta | Limitació |
|---|---|---|
| Registres de facturació | Consultes de BigQuery anòmales per bytes processats | Només si el volum va ser gran |
| Mètriques de Cloud Storage | Pics de descàrrega del data lake | Granularitat gruixuda |
| Historial del repositori | Quan es va pujar i quan es va fer públic | No diu qui el va fer servir |
| Activitat d'administrador | Si van crear persistència | No cobreix lectura de dades |
T+1 a T+2 h — Comunicar.
| Moment | A qui | Què |
|---|---|---|
| T+35 min | Direcció | «Credencial amb accés a dades de clients exposada públicament. Continguda. Investigant l'abast. Possible obligació de notificar l'AEPD.» |
| T+45 min | Assessor jurídic / DPD | Els fets, i la limitació de l'evidència |
| T+1 h | Equip | Repartiment: Marta conté, Dani revisa el repositori, Lucía valida quines dades hi havia |
| T+2 h | Suport de Google Cloud | Obrir cas: poden aportar dades i ajudar en l'anàlisi |
T+2 a T+24 h — Abast i erradicació.
# 1. Buscar ALTRES credencials a l historial de TOTS els repositoris
# Gairebe mai n hi ha nomes una
for REPO in alpinashop-catalogo alpinashop-infra alpinashop-datos alpinashop-ml; do
git clone --mirror "[email protected]:alpinashop/$REPO.git" "/tmp/$REPO"
trufflehog git "file:///tmp/$REPO" --json > "/tmp/hallazgos-$REPO.json"
done
# 2. Buscar persistencia creada en els ultims 8 mesos
gcloud asset search-all-iam-policies --scope=organizations/ORG_ID \
--query="policy:serviceAccount" --format=json > /tmp/todas-politicas.json
# 3. Rotar TOT el que estigues al mateix repositori
gcloud secrets versions add db-password-catalogo --data-file=- <<< "$NUEVA"
gcloud secrets versions add api-key-pasarela-pago --data-file=- <<< "$NUEVA_API"T+24 a T+72 h — Notificació. Si l'assessor jurídic determina que hi ha risc per als drets dels interessats, notificació a l'AEPD dins de les 72 hores. En no poder descartar l'accés, el més probable és que calgui notificar. La notificació descriu: què va passar, quines dades podrien estar afectades, quines mesures s'han pres, i per què no es pot acotar l'abast — cosa que, dit amb claredat, és en si mateixa una troballa desfavorable sobre l'organització.
Canvis estructurals després:
| Canvi | Prevé |
|---|---|
Activar registres d'accés a dades a alpinashop-datos |
La impossibilitat d'acotar l'abast. El més important de tots |
| Escaneig de secrets a cada push (Secret Scanning de GitHub + ganxo de pre-commit) | Que es torni a pujar una credencial |
| Eliminar totes les claus JSON i migrar a federació i impersonació | L'existència mateixa de credencials permanents |
| VPC-SC en mode aplicat | Que una credencial filtrada pugui treure dades |
Alerta sobre CreateServiceAccountKey |
Que es creï una clau sense que ningú se n'assabenti |
| Reescriptura de l'historial dels repositoris (BFG) o rotació de tot el que continguin | Que l'històric continuï sent explotable |
| Post mortem sense culpables (07-06) | Que la lliçó es perdi |
La reflexió final de l'exercici. La clau es va pujar fa vuit mesos, es va esborrar del repositori, i tothom va pensar que el problema estava resolt. Esborrar un fitxer de Git no esborra el seu historial: qualsevol amb accés al repositori —o al repositori públic, o a un fork— podia recuperar-lo amb git log -p. És un malentès tan estès que mereix una regla:
Un secret que ha estat en un repositori, encara que sigui un minut, està compromès. L'única resposta correcta és rotar-lo. Esborrar-lo de l'historial és neteja, no remediació.
Solució 3 — Prioritzar amb pressupost limitat
Restriccions: 10 dies de Marta, 3.000 €, un trimestre. I una premissa que cal respectar: Marta també ha d'operar la plataforma, així que 10 dies de seguretat són 10 dies reals, no elàstics.
El que es fa:
| Setmana | Tasca | Dies | € | Per què |
|---|---|---|---|---|
| 1 | Localitzar i eliminar la clau JSON; migrar a federació | 0,5 | 0 | Credencial permanent perduda. Risc màxim, cost mínim |
| 1 | Compte per defecte de Compute: treure Editor i desactivar |
0,5 | 0 | Escalada trivial. Mitja jornada |
| 1 | Cloud Build: acotar a rols concrets | 0,5 | 0 | Compromís del pipeline = compromís total |
| 1 | Alertes de canvis d'IAM i creació de claus | 0,5 | 0 | Sense detecció no hi ha resposta. Dues hores |
| 2 | Activar registres d'accés a dades a alpinashop-datos i buckets sensibles |
1 | ~600/any | Requisit legal de facto. Sense això no es pot acotar una bretxa |
| 2-3 | Pla de resposta a incidents escrit i provat en simulacre | 1,5 | 0 | Converteix la teoria en capacitat |
| 3-4 | Assaig de restauració d'alpinashop-pedidos |
1,5 | ~100 | Una còpia no provada no existeix. Risc existencial |
| 5 | VPC-SC de mode de prova a aplicat | 2 | 0 | La feina ja està feta a mitges; acabar-la és barat i molt eficaç |
| 6 | Escaneig de vulnerabilitats bloquejant al pipeline | 0,5 | 0 | Mig dia |
| 7 | Claus físiques per a les 3 persones tècniques | 0,5 | ~200 | Elimina el phishing de credencials, que és el vector número u |
| 8 | Revisió d'accessos + procés trimestral documentat | 1 | 0 | Procés, no eina |
| — | Total | 10 | ~900 € |
Sobren 2.100 €. I aquí ve la proposta que dona més valor per euro:
Contractar una revisió externa de seguretat de mig dia (~1.500-2.000 €) al final del trimestre, sobre l'arquitectura ja endurida.
El raonament: Marta ha construït aquesta plataforma i té els punts cecs de qui la va construir. Una mirada externa sobre un sistema ja ordenat troba coses diferents de les que trobaria sobre un de desordenat — i per això es contracta després de pagar el deute de prioritat 1 i 2, no abans. A més aporta una cosa que a dins no es pot fabricar: un informe signat per un tercer, que és el que demana un client corporatiu, una asseguradora o una inspecció.
El que NO es fa, i per què:
| No es fa | Motiu |
|---|---|
| SCC Premium | ~1.000 €/mes i ningú no pot atendre el que detecti. Comprar detecció sense capacitat de resposta és gastar en tranquil·litat, no en seguretat |
| Binary Authorization | 3 dies per a un risc baix-mitjà amb la cadena de subministrament ja controlada per altres vies |
| PAM | 2 dies. Valuós, però amb 3 persones i ningú sent owner de producció, l'exposició és menor |
| Polítiques d'organització | Van a 07-07 amb la zona d'aterratge. Fer-ho dues vegades és malgastar dies |
| Proves de penetració externes | 5.000-15.000 € i trobaria el que ja sabem. Es fa quan el deute conegut estigui pagat, no abans |
El que se li diu a direcció — i aquesta és la part que més costa i més importa:
«Amb aquests deu dies tanquem els quatre forats que avui ens exposen més: una contrasenya permanent que vam perdre fa més d'un any i que continua funcionant, un compte intern que dona permís per esborrar qualsevol cosa, un sistema automàtic que ho pot tocar tot, i la manca d'avís quan algú canvia permisos.
A més fem dues coses que avui no tenim i que són obligació legal o de sentit comú: saber qui accedeix a les dades dels nostres clients —avui no podríem respondre aquesta pregunta davant de l'Agència de Protecció de Dades, i no poder respondre-la és en si mateix un problema— i comprovar que les nostres còpies de seguretat es poden restaurar de debò, cosa que no hem verificat mai. I assagem què faríem si demà passa alguna cosa, perquè el dia de l'incident és el pitjor dia per improvisar.
El que queda sense fer, i vull que consti per escrit: no tindrem vigilància activa d'amenaces —si algú entra sense fer soroll, ens n'assabentaríem tard—; no impedirem tècnicament que es desplegui programari no aprovat; els permisos administratius continuaran sent permanents en lloc de temporals; i no contractarem un atac simulat professional. Cadascuna d'aquestes quatre coses és una decisió de pressupost, no un descuit, i les revisem el trimestre que ve.
Amb el que fem passem d'un risc que jo qualificaria d'alt a un de mitjà. Arribar a baix requereix una persona dedicada a seguretat o un servei gestionat, i això és una conversa diferent que convé tenir quan siguem seixanta persones o quan un client gran ens ho exigeixi per contracte.»
Els tres elements que fan bona aquesta comunicació, i que es poden reutilitzar en qualsevol empresa: es parla de riscos de negoci i no de noms de productes; es diu explícitament el que queda sense cobrir en lloc de deixar que la direcció assumeixi que tot està resolt; i es fixa quan es revisa, cosa que converteix una retallada pressupostària en una decisió conscient amb data en lloc de en un silenci.
Conclusió
AlpinaShop ha passat de tenir controls de seguretat a tenir seguretat revisada, i —el que és més útil— a saber exactament què li falta.
Has aplicat defensa en profunditat capa per capa —vora, identitat, xarxa, càrrega de treball, dades, detecció— i sobretot has après la pregunta de la fallada única, que és l'eina més barata i més eficaç de tota la lliçó: per a cada capa, si això falla, què ho conté? Les respostes dubtoses són el deute.
Tens els sis principis que expliquen totes les decisions del curs: mínim privilegi amb el Recommender que el fa suportable, separació de funcions —Dani escriu, Cloud Build construeix, Marta aprova, i ningú no pot desplegar i esborrar l'evidència—, denegar per defecte, radi d'explosió limitat amb la seva pregunta operativa, no confiar en la xarxa, i assumir la bretxa.
Entens confiança zero i BeyondCorp amb IAP com a implementació pràctica, i has vist que un nivell d'accés basat en el dispositiu —corporatiu, xifrat, bloquejat, actualitzat, des d'una regió permesa— resol el teletreball molt millor que qualsevol llista d'IP, perquè fa que la IP deixi d'importar.
Has revisat la identitat a fons: eliminar els rols bàsics, l'script que els troba, i les tres troballes que apareixen sempre —una persona amb Owner, Cloud Build amb Editor i, sobretot, el compte per defecte de Compute amb Editor, que és la fallada més estesa de Google Cloud i la que converteix qualsevol vulnerabilitat d'aplicació en un compromís total. Coneixes les alternatives sense claus per a cada situació i la comanda amb --managed-by=user que troba les que queden. Saps muntar elevació temporal amb PAM —amb el camí de trencament de vidre que no impedeix sinó que fa soroll— i federació d'identitat amb la condició d'atributs per repository_id i ref que separa una federació segura d'una que només ho sembla.
Domines la cadena de subministrament: escaneig que bloqueja només el que té pedaç, imatges base mínimes —amb la taula que va de python:3.12 a distroless— fixades per digest i amb --require-hashes, USER 1000 en lloc de root, procedència SLSA que respon a «aquesta imatge va sortir del nostre codi?», Binary Authorization —que també aplica a Cloud Run— i Assured Open Source amb el seu abast honest.
Has tancat el cicle de les dades: classificació en quatre nivells amb la millor decisió de seguretat del curs —no emmagatzemar targetes, perquè la dada que no guardes no es filtra—, descobriment amb Sensitive Data Protection i detectors espanyols, includeQuote: false per no duplicar el problema, CMEK amb el seu «botó vermell» de deshabilitar la clau i la seva contrapartida irreversible, pseudonimització amb hash salat i generalització —que no és anonimització— i retenció amb el procediment de supressió que anonimitza les comandes en lloc d'esborrar-les perquè l'obligació fiscal mana.
Saps detectar: Security Command Center amb els seus tres nivells, el que el gratuït troba de debò, i el criteri honest que comprar detecció que ningú no mira és pitjor que no comprar-la. I tens els quatre tipus de registre d'auditoria amb la dada que ho canvia tot — accés a dades està desactivat per defecte, i sense això no pots saber qui va llegir les dades dels teus clients— juntament amb les tres consultes que cal tenir escrites abans de necessitar-les.
Tens un guió de resposta realista: deu minuts per valorar sense tocar res, vint per contenir sense destruir evidència —deshabilitar i no esborrar, i revocar els testimonis vius que sobreviuen una hora—, mitja hora per a l'abast incloent-hi la cerca de persistència, i la comunicació amb les 72 hores del RGPD comptant des del coneixement i no des de la conclusió. Amb la carpeta que cal preparar avui, inclòs el canal de comunicació alternatiu i el simulacre anual.
Saps quin compliment normatiu aporta Google i quin continua sent teu, amb el malentès més car aclarit: les seves certificacions acrediten la capa de sota, no la teva empresa. I tens la llista dels set documents que es demanen abans que cap configuració tècnica.
I t'endús dues coses que valen més que cap apartat teòric: la llista de comprovació de 43 controls amb l'estat real d'AlpinaShop —20 ✅, 11 ⚠️, 12 ❌— i el deute prioritzat en tres blocs, amb quatre tasques de prioritat 1 que sumen menys de dos dies i són el que més risc elimina. Més la llista de deute acceptat conscientment, perquè un risc documentat és una decisió de gestió i un risc que ningú no ha mirat és un forat.
L'exercici de la clau filtrada ha deixat la lliçó més incòmoda de totes, i convé endur-se-la literal: un secret que ha estat en un repositori, encara que sigui un minut, està compromès; esborrar-lo de l'historial és neteja, no remediació.
I l'exercici del pressupost ha deixat l'altra: la seguretat d'una pime no es decideix amb la llista del que és ideal, sinó triant deu dies ben gastats i dient a direcció, per escrit i en el seu idioma, el que queda sense cobrir.
Dos fils d'aquesta lliçó queden explícitament oberts. Un apunta a 07-06: la restauració de còpies no s'ha provat mai, i apareix com a risc crític tant a la llista de comprovació com a la priorització. L'altre apunta a 07-07: les polítiques d'organització, els registres d'auditoria immutables en un projecte separat i la revisió periòdica d'accessos són govern, i allà es resolen.
Però abans hi ha una conversa que porta set mòduls ajornant-se. Cada lliçó ha afegit serveis; cap no ha tancat la factura. Aquesta mateixa lliçó ha proposat activar els registres d'accés a dades —que costen—, ha descartat SCC Premium per preu, i ha repartit 3.000 € com si fossin molts diners, que per a una empresa de quaranta persones ho són. Cap d'aquestes tres decisions no es pot prendre bé sense entendre d'on surt cada euro de la factura d'AlpinaShop. La lliçó següent obre la factura sencera, línia a línia, i l'explica.
Curs de Google Cloud Platform (GCP)
Mòdul 1: Introducció a Google Cloud Platform
- Què és Google Cloud Platform?
- Configuració del teu compte de GCP
- Descripció general de la consola de GCP
- Projectes, jerarquia de recursos i facturació
- Regions, zones i model de responsabilitat compartida
- Cloud Shell i la CLI de gcloud
Mòdul 2: Serveis principals de GCP
- Compute Engine: màquines virtuals a Google Cloud
- Cloud Storage: emmagatzematge d'objectes
- Cloud SQL: bases de dades relacionals gestionades
- App Engine: plataforma com a servei
- Google Kubernetes Engine (GKE)
- Bases de dades NoSQL: Firestore, Bigtable i Spanner
- Com triar el servei de còmput adequat
Mòdul 3: Xarxes i seguretat
- Xarxes VPC
- Balanceig de càrrega al núvol
- Cloud CDN
- Gestió d'identitat i accés (IAM)
- Cloud Armor
- Secrets i xifratge: Secret Manager i Cloud KMS
- Cloud DNS, certificats TLS i publicació segura de serveis
Mòdul 4: Dades i anàlisi
- BigQuery: el magatzem de dades analític
- Cloud Dataflow: processament de dades per lots i en temps real
- Cloud Dataproc: Spark i Hadoop gestionats
- Cloud Pub/Sub: missatgeria asíncrona
- Cloud Data Fusion: integració de dades sense codi
- Orquestració de pipelines amb Cloud Composer i Workflows
- Govern de les dades i taulers amb Dataplex i Looker Studio
Mòdul 5: Aprenentatge automàtic i IA
- Vertex AI: la plataforma d'aprenentatge automàtic de GCP
- AutoML: models a mida sense escriure codi
- TensorFlow a GCP: entrenament i servei de models
- API de llenguatge natural
- API de visió
- IA generativa a Vertex AI: models Gemini i incrustacions
- MLOps: del model al producte amb Vertex AI Pipelines
Mòdul 6: DevOps i monitoratge
- Cloud Build: integració contínua a GCP
- Cloud Source Repositories i gestió del codi font
- Cloud Functions: funcions sense servidor
- Cloud Monitoring (abans Stackdriver): mètriques, taulers i alertes
- Cloud Deployment Manager i infraestructura com a codi nativa
- Cloud Logging i Cloud Trace: registres, traces i diagnòstic
- Terraform a GCP: infraestructura com a codi a la pràctica
Mòdul 7: Temes avançats de GCP
- Híbrid i multinúvol amb Anthos
- Computació sense servidor amb Cloud Run
- Xarxes avançades: VPC compartida, aparellament i connectivitat híbrida
- Bones pràctiques de seguretat
- Gestió i optimització de costos
- Fiabilitat: SLO, alta disponibilitat i recuperació de desastres
- Govern a escala: organització, polítiques i auditoria
