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

  1. Defensa en profunditat aplicada a AlpinaShop
  2. Els sis principis que sostenen tota la resta
  3. Confiança zero i BeyondCorp, amb IAP com a implementació pràctica
  4. Identitat: revisió completa del disseny IAM
  5. Elevació temporal de privilegis i federació
  6. Cadena de subministrament del programari
  7. Dades: classificació, xifratge, pseudonimització i esborrat
  8. Detecció: Security Command Center i els registres d'auditoria
  9. Resposta: les dues primeres hores d'un incident
  10. Compliment: què aporta Google i què continua sent teu
  11. Llista de comprovació d'enduriment
  12. El deute de seguretat d'AlpinaShop, prioritzat

  1. 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.

  1. 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.

  1. 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
    - PT

Es 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.

  1. 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(", "))"'
done

El 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.

  1. 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.

  1. 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:app

Les 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-provenance

La 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
EOF

I aplica a Cloud Run, no només a GKE, cosa que el fa directament rellevant per a AlpinaShop després de 07-02:

gcloud run services update alpinashop-web --region=europe-west1 \
  --binary-authorization=default

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.

  1. 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.

gcloud dlp jobs create inspect \
  --project=alpinashop-datos \
  --inspect-job-file=inspeccion.json
{
  "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 Google 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.

  1. 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 DESC

La 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.

  1. 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:

  1. És real o un fals positiu? Hi ha un canvi programat aquesta nit? Hi ha algú treballant?
  2. Està en curs? Continua havent-hi activitat d'aquesta identitat ara mateix?
  3. 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ó.

  1. Compliment: què aporta Google i què continua sent teu

El repartiment de 01-05, revisat ara amb tot el context:

Aspecte Google 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:

  1. Registre d'activitats de tractament (art. 30 RGPD).
  2. Contracte d'encarregat del tractament amb Google Cloud.
  3. Avaluació d'impacte (AIPD) si hi ha tractament d'alt risc.
  4. Política de seguretat de la informació, encara que siguin quatre pàgines.
  5. Procediment de resposta a bretxes, amb els terminis de l'apartat 9.
  6. Registre d'accessos a dades personals — que és just el que donen els registres d'accés a dades.
  7. 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.

  1. 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.

  1. 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_id i ref, 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:

  1. Qualsevol vincle amb rols bàsics (owner, editor, viewer).
  2. Vincles amb allUsers o allAuthenticatedUsers en projectes i en buckets.
  3. Comptes de servei amb claus gestionades per l'usuari, amb la seva antiguitat.
  4. Comptes de servei que no s'han fet servir en 90 dies.
  5. 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) -> \(.)"'
done

Taula 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 sortir

La 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 DESC

I 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

Mòdul 2: Serveis principals de GCP

Mòdul 3: Xarxes i seguretat

Mòdul 4: Dades i anàlisi

Mòdul 5: Aprenentatge automàtic i IA

Mòdul 6: DevOps i monitoratge

Mòdul 7: Temes avançats de GCP

Mòdul 8: Projecte final

© Copyright 2026. Tots els drets reservats