Proteção de um sistema de detecção de segurança no local de trabalho

1. Introdução

Neste codelab, você vai criar um aplicativo de demonstração básico que ilustra como integrar vários serviços do Google Cloud para um serviço localizado em um projeto com restrições de conformidade. Este projeto usa os seguintes recursos de segurança:

Este codelab é destinado a desenvolvedores de todos os níveis, incluindo iniciantes. Você vai usar a interface de linha de comando no Google Cloud Shell e no código Python. Não é necessário ser um especialista em Python, mas um conhecimento básico de como ler o código vai ajudar você a entender os conceitos.

Observação:esta é uma prova de conceito simplificada, não um aplicativo de produção. Aplique outras precauções, como acesso externo autenticado e seguro a esse serviço em um cenário real.

2. Antes de começar

Configuração do projeto

../shared/_project-setup.md

Iniciar Cloud Shell

O Cloud Shell é um ambiente de linha de comando executado no Google Cloud que vem pré-carregado com as ferramentas necessárias.

  1. Clique em Ativar o Cloud Shell na parte de cima do console do Google Cloud:

404e4cce0f23e5c5.png

  1. Depois de se conectar ao Cloud Shell, execute este comando para verificar sua autenticação no Cloud Shell:
gcloud auth list
  1. Execute o comando a seguir para confirmar se o projeto está configurado para uso com o gcloud:
gcloud config get project
  1. Confirme se o projeto está como esperado e execute o comando abaixo para definir o ID do projeto:
export PROJECT_ID=$(gcloud config get project)

Permissões do IAM obrigatórias

A conta usada para este codelab precisa ter os seguintes papéis do IAM. Essas permissões são necessárias para criar os recursos necessários do Google Cloud (projetos, pastas, clusters do GKE, chaves do KMS, contas de serviço etc.) e configurar a carga de trabalho garantida.

No nível da organização:

  • roles/assuredworkloads.admin (administrador do Assured Workloads) : para criar e gerenciar o recurso do Assured Workloads, garantindo a configuração de conformidade.

No nível da conta de faturamento (na sua conta de faturamento):

  • roles/billing.accountUser (usuário da conta de faturamento) : para vincular a conta de faturamento especificada.

Como configurar variáveis do codelab

Para criar a infraestrutura necessária, forneça as seguintes variáveis de ambiente:

# The ID of the Billing Account in the format (XXXXXX-XXXXXX-XXXXXX).
# This value will be used to attach in the projects created using Assured Workloads
export BILLING_ACCOUNT=

# The ID of a Google Cloud Platform organization
# Run `gcloud organizations list` to check all your available organizations
export GCP_ORGANIZATION=

# The numeric ID of a folder where the Assured Workloads will create the resources.
export FOLDER_ID=

# Region where the application will be deployed.
# Since you are using Assured Workloads, you MUST use one of the valid locations as described here: <https://docs.cloud.google.com/assured-workloads/docs/locations>
export REGION="us-central1"

# The ID of an existing Google Cloud project to be used for API quota and billing purposes.
# This project will only be used to enable the Assured Workloads API and create an Assured Workload.
export QUOTA_PROJECT_ID=

# Random suffix used to avoid naming collisions when creating the GCP projects.
export RANDOM_SUFFIX=$(cat /dev/urandom | tr -dc 'a-z0-9' | head -c 5 ; echo)

# The ID of the projects that will be created using Assured Workloads.
# You can modify this value if you want a custom id.
export PROJECT_ID="il5-gemini-vision-aw-${RANDOM_SUFFIX}"
export KMS_PROJECT_ID="il5-gemini-vision-kms-${RANDOM_SUFFIX}"

3. Como criar a base do Assured Workloads

Agora você pode criar a base do aplicativo em um ambiente regulamentado. Use o Assured Workloads para ajudar a aplicar os requisitos de conformidade criando um ambiente controlado para seus recursos.

Configurar o projeto de cota

Ative a API Assured Workloads no projeto de cota. Essa API é necessária para criar e gerenciar o Assured Workloads.

gcloud services enable assuredworkloads.googleapis.com \
  --project="${QUOTA_PROJECT_ID}"

Criar o ambiente do Assured Workloads

O comando a seguir cria uma "zona de destino" segura para sua demonstração. Ele cria dois novos projetos do Google Cloud na pasta e na conta de faturamento especificadas.

  • Um projeto hospeda o cluster do GKE e o aplicativo.
  • O outro projeto gerencia as chaves de criptografia gerenciadas pelo cliente (CMEK).

Ele aplica automaticamente os controles de conformidade IL5 especificados aos dois projetos no momento em que são criados.

Execute o comando a seguir para criar o ambiente de carga de trabalho.

export ASSURED_WORKLOAD_ID=$(gcloud assured workloads create \
    --project="${QUOTA_PROJECT_ID}" \
    --display-name="DoD IL5 Gemini Vision Demo" \
    --compliance-regime="IL5" \
    --billing-account="billingAccounts/${BILLING_ACCOUNT}" \
    --location="${REGION}" \
    --organization="${GCP_ORGANIZATION}" \
    --provisioned-resources-parent="folders/${FOLDER_ID}" \
    --resource-settings="consumer-project-id=${PROJECT_ID},consumer-project-name=DoD IL5 Workloads,encryption-keys-project-id=${KMS_PROJECT_ID},encryption-keys-project-name=DoD IL5 KMS" \
    --labels="codelab=gemini-vision-demo" \
    --format="value(name)")

echo "Assured Workload created: ${ASSURED_WORKLOAD_ID}"

export WORKLOAD_FOLDER_ID=$(gcloud assured workloads describe ${ASSURED_WORKLOAD_ID} \
    --location="${REGION}" \
    --project="${QUOTA_PROJECT_ID}" \
    --format="json" | grep -B 1 "CONSUMER_FOLDER" | grep -oE "[0-9]{10,}")

echo "Assured Workload folder created: ${WORKLOAD_FOLDER_ID}"

gcloud projects create "${PROJECT_ID}" \
    --folder="${WORKLOAD_FOLDER_ID}" \
    --name="DoD IL5 Workloads"

gcloud billing projects link "${PROJECT_ID}" \
    --billing-account="${BILLING_ACCOUNT}"

export PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")

Como ativar as APIs do Cloud necessárias do Google Cloud

Antes de criar, ative as APIs necessárias para os serviços necessários.

O comando abaixo ativa todos os serviços necessários para este codelab no projeto de carga de trabalho principal.

gcloud services enable \
    aiplatform.googleapis.com \
    artifactregistry.googleapis.com \
    cloudkms.googleapis.com \
    compute.googleapis.com \
    container.googleapis.com \
    iam.googleapis.com \
    logging.googleapis.com \
    monitoring.googleapis.com \
    --project="${PROJECT_ID}"

4. Configuração da infraestrutura do GKE

Crie a infraestrutura principal que oferece suporte ao cluster do GKE. Isso envolve a configuração de uma rede dedicada para o cluster e a configuração das próprias chaves de criptografia para proteger os dados nos nós.

Como configurar a rede VPC

Crie uma nuvem privada virtual (VPC) e uma sub-rede personalizadas. Essa abordagem oferece controle total sobre o intervalo de endereços IP e garante que o cluster seja isolado conforme o esperado.

Execute os comandos a seguir para criar a rede VPC e uma sub-rede na região especificada.

export GKE_NETWORK_NAME="il5-gke-network"
export GKE_SUBNETWORK_NAME="il5-gke-subnet"

gcloud compute networks create "${GKE_NETWORK_NAME}" \
    --description="VPC network for GKE cluster in DoD IL5 Assured Workload" \
    --subnet-mode="custom" \
    --project="${PROJECT_ID}"

gcloud compute networks subnets create "${GKE_SUBNETWORK_NAME}" \
    --network="${GKE_NETWORK_NAME}" \
    --range="10.10.0.0/20" \
    --region="${REGION}" \
    --description="Subnet for GKE cluster nodes in DoD IL5 Assured Workload" \
    --project="${PROJECT_ID}"

Como configurar a criptografia com o Cloud KMS

Para atender aos requisitos de conformidade rigorosos para dados em repouso, use chaves de criptografia gerenciadas pelo cliente (CMEK). Isso oferece controle direto sobre as chaves usadas para criptografar os discos de inicialização dos nós do GKE.

export KMS_KEYRING_NAME="il5_gke_key_ring"
export KMS_KEY_NAME="il5_gke_key"

gcloud kms keyrings create "${KMS_KEYRING_NAME}" \
    --location="$REGION" \
    --project="${KMS_PROJECT_ID}"

gcloud kms keys create "${KMS_KEY_NAME}" \
    --keyring="${KMS_KEYRING_NAME}" \
    --location="${REGION}" \
    --purpose="encryption" \
    --project="${KMS_PROJECT_ID}"

Como a chave de criptografia existe em um projeto do KMS separado do serviço que precisa usá-la, o agente de serviço do Google Compute Engine no projeto de carga de trabalho precisa de acesso à chave.

Você precisa conceder explicitamente ao agente de serviço do GCE do projeto de carga de trabalho a permissão para usar essa chave. O comando abaixo adiciona uma vinculação de política do IAM à chave, concedendo o papel necessário ao agente de serviço.

gcloud kms keys add-iam-policy-binding "${KMS_KEY_NAME}" \
    --location="${REGION}" \
    --keyring="${KMS_KEYRING_NAME}" \
    --member="serviceAccount:service-${PROJECT_NUMBER}@compute-system.iam.gserviceaccount.com" \
    --role="roles/cloudkms.cryptoKeyEncrypterDecrypter" \
    --project="${KMS_PROJECT_ID}"

Como configurar uma conta de serviço de nó do GKE

export GKE_NODE_SA=gke-node-sa

gcloud iam service-accounts create "${GKE_NODE_SA}" \
    --display-name="GKE Node Service Account" \
    --project="${PROJECT_ID}"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/logging.logWriter"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/monitoring.metricWriter"

5. Criação e configuração do cluster do GKE

Agora, você pode criar o cluster do GKE. O comando a seguir provisiona um cluster do GKE com vários recursos de segurança ativados.

Isso leva vários minutos para ser concluído, já que o Google Cloud provisiona os nós e o plano de controle.

export GKE_CLUSTER=ppe-app

gcloud beta container clusters create "${GKE_CLUSTER}" \
    --project="$PROJECT_ID" \
    --region="$REGION" \
    --service-account="${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --release-channel="regular" \
    --machine-type="n2d-standard-4" \
    --image-type="COS_CONTAINERD" \
    --disk-type="pd-ssd" \
    --disk-size="50" \
    --boot-disk-kms-key="projects/${KMS_PROJECT_ID}/locations/${REGION}/keyRings/${KMS_KEYRING_NAME}/cryptoKeys/${KMS_KEY_NAME}" \
    --metadata disable-legacy-endpoints=true \
    --num-nodes="1" \
    --network="projects/${PROJECT_ID}/global/networks/${GKE_NETWORK_NAME}" \
    --subnetwork="projects/${PROJECT_ID}/regions/${REGION}/subnetworks/${GKE_SUBNETWORK_NAME}" \
    --security-posture="standard" \
    --workload-vulnerability-scanning="disabled" \
    --workload-pool="${PROJECT_ID}.svc.id.goog" \
    --workload-metadata=GKE_METADATA \
    --addons="HorizontalPodAutoscaling,HttpLoadBalancing,NodeLocalDNS,GcePersistentDiskCsiDriver" \
    --max-surge-upgrade=1 \
    --max-unavailable-upgrade=0 \
    --binauthz-evaluation-mode="DISABLED" \
    --no-enable-basic-auth \
    --enable-autoupgrade \
    --enable-autorepair \
    --enable-confidential-nodes \
    --confidential-node-type=sev \
    --enable-ip-access \
    --enable-ip-alias \
    --enable-managed-prometheus \
    --enable-dns-access \
    --enable-shielded-nodes \
    --shielded-integrity-monitoring \
    --shielded-secure-boot

Como se conectar ao novo cluster

Para interagir com o novo cluster, configure a ferramenta de linha de comando kubectl local.

Esse comando busca as credenciais e o endpoint do cluster e configura automaticamente o arquivo kubeconfig local. Depois de executar esse comando, todos os comandos kubectl executados serão direcionados ao novo cluster do GKE.

gcloud container clusters get-credentials "${GKE_CLUSTER}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --dns-endpoint

6. Configuração da identidade do aplicativo

Para conectar uma conta de serviço do Kubernetes a uma conta de serviço do Cloud IAM do Google Cloud, configure a Identidade da carga de trabalho.

Como criar contas de serviço

Crie uma conta de serviço do Kubernetes (KSA) dedicada no cluster.

export GKE_NAMESPACE=default
export GKE_SA=ppe-sa

kubectl create sa "${GKE_SA}" --namespace="${GKE_NAMESPACE}"

Em seguida, o aplicativo precisa de uma identidade no Google Cloud. Crie uma conta de serviço do Cloud IAM do Google Cloud para o aplicativo. Depois de criar a conta de serviço, conceda a ela os papéis necessários.

# Create GCP service account
gcloud iam service-accounts create "${GKE_SA}" \
    --project="${PROJECT_ID}"
# Grant necessary roles
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:${GKE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/aiplatform.user"

Como permitir que a conta de serviço do Kubernetes represente a do IAM

Com as duas contas de serviço criadas, a etapa final é criar o link entre elas. Esse é um processo de duas partes. Primeiro, adicione uma política do IAM à sua conta de serviço do Google Cloud.

# Allow the Kubernetes service account to act as GCP service account by using Workload Identity
gcloud iam service-accounts add-iam-policy-binding "${GKE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --project="${PROJECT_ID}" \
    --role="roles/iam.workloadIdentityUser" \
    --member="serviceAccount:${PROJECT_ID}.svc.id.goog[${GKE_NAMESPACE}/${GKE_SA}]"

Em segundo lugar, anote sua conta de serviço do Kubernetes.

kubectl annotate --namespace="${GKE_NAMESPACE}" serviceaccount "$GKE_SA" \
    iam.gke.io/gcp-service-account="${GKE_SA}@${PROJECT_ID}.iam.gserviceaccount.com"

Com isso concluído, qualquer pod em execução no cluster com a conta de serviço do Kubernetes poderá acessar a API Vertex.

Observação: é possível eliminar a identidade temporária de conta de serviço para simplificar essa configuração. Consulte aqui para mais detalhes e limitações.

7. Criação e implantação de aplicativos

É hora de empacotar seu aplicativo, armazená-lo e implantá-lo no cluster do GKE.

Como criar o repositório do Artifact Registry

Antes de executar o app, empacote-o como um contêiner do Docker e armazene-o em um repositório do Artifact Registry. Use o comando abaixo para criar esse repositório.

export REPOSITORY_ID=ppe-repo

gcloud artifacts repositories create "${REPOSITORY_ID}" \
  --repository-format=docker \
  --location="${REGION}" \
  --project="${PROJECT_ID}" \
  --description="Regional Docker repo for PPE App"

Você precisa conceder explicitamente à conta de serviço usada pelos nós do GKE a capacidade de ler no novo repositório.

gcloud artifacts repositories add-iam-policy-binding "${REPOSITORY_ID}" \
    --location="${REGION}" \
    --role="roles/artifactregistry.reader" \
    --project="${PROJECT_ID}" \
    --member="serviceAccount:${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com"

Como criar e enviar a imagem Docker

Crie e envie a imagem Docker para o repositório. Primeiro, clone o código-fonte e crie a imagem do contêiner. Em seguida, marque-o com o caminho completo do Artifact Registry e envie-o para o repositório que você criou anteriormente.

git clone https://github.com/GoogleCloudPlatform/next-26-sessions.git

cd BRK3-034-workplace-safety

cd ppe

export IMAGE_TAG="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_ID}/ppe-app:v15"
docker build -t "${IMAGE_TAG}" .
docker push "${IMAGE_TAG}"

Como implantar no GKE

Com a imagem do contêiner disponível no Artifact Registry, a etapa final é instruir o GKE a extrair e executar a imagem. Isso é feito definindo os recursos do aplicativo em um arquivo de manifesto do Kubernetes e aplicando-o ao cluster. Esse comando cria os objetos de implantação e serviço definidos no arquivo.

export GKE_DEPLOY=ppe-detector

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ${GKE_DEPLOY}
spec:
  replicas: 2
  selector:
    matchLabels:
      app: ${GKE_DEPLOY}
  template:
    metadata:
      labels:
        app: ${GKE_DEPLOY}
    spec:
      serviceAccountName: ${GKE_SA}
      containers:
      - name: ${GKE_DEPLOY}
        image: ${IMAGE_TAG}
        env:
        - name: PROJECT_ID
          value: ${PROJECT_ID}
        - name: LOCATION
          value: ${REGION}
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: "250m"
            memory: "512Mi"
          limits:
            cpu: "500m"
            memory: "1Gi"
---
apiVersion: v1
kind: Service
metadata:
  name: ${GKE_DEPLOY}
spec:
  type: LoadBalancer
  selector:
    app: ${GKE_DEPLOY}
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
EOF

8. Teste o aplicativo

A etapa final é acessar e testar o aplicativo de demonstração. Isso envolve a recuperação do endereço IP externo atribuído ao serviço e a interação com ele por meio de um front-end simples.

Como recuperar o IP externo do serviço

Receba o IP externo do serviço exposto (leva cerca de 30 segundos para provisionar)

export IP_ADDRESS=$(kubectl get service "${GKE_DEPLOY}" -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $IP_ADDRESS

Como executar o front-end localmente

Para esta demonstração, o front-end é uma página HTML/JavaScript simples que não faz parte da implantação do GKE. Ele foi projetado para ser executado na sua máquina local.

O front-end precisa ser veiculado no GCP em um aplicativo de produção. Na máquina local:

# Update the index.html file with the server IP address
cd frontend

# For Linux
sed -i "s#\(const BACKEND_URL = \"http://\)[^/]\+\(\/analyze\";\)#\1${IP_ADDRESS}\2#g" "index.html"

# For MacOS
#sed -i '' "s#\(const BACKEND_URL = #\"http://\)[^/]*\(\/analyze\";\)#\1${IP_ADDRESS}\2#g" "index.html"

python3 -m http.server 8001

Abra http://localhost:8001/index.html no Chrome.

9. Limpeza

Para evitar cobranças contínuas, exclua os recursos criados neste codelab.

Como destruir o cluster do GKE

Para excluir todo o aplicativo, basta excluir o cluster do GKE. Para fazer isso, execute:

gcloud container clusters delete "${GKE_CLUSTER}" \
    --region="$REGION" \
    --project="${PROJECT_ID}"

Como excluir o Assured Workloads

Execute os comandos a seguir para excluir todos os recursos relacionados ao Assured Workloads.

# Workload project deletion
gcloud billing projects unlink "${PROJECT_ID}"
gcloud projects delete "${PROJECT_ID}"

# KMS project deletion
gcloud billing projects unlink "${KMS_PROJECT_ID}"
gcloud projects delete "${KMS_PROJECT_ID}"

# Assured Workload folder deletion
gcloud resource-manager folders delete ${WORKLOAD_FOLDER_ID} --quiet

# Assured Workload deletion
gcloud assured workloads delete "${ASSURED_WORKLOAD_ID}" \
    --location="${REGION}" \
    --organization="${GCP_ORGANIZATION}" \
    --project="${QUOTA_PROJECT_ID}"

10. Parabéns

Missão concluída! Você criou um sistema de detecção de segurança no local de trabalho para setores regulamentados que usa o Gemini para detectar capacetes.

O que você realizou:

  • Proteção e privacidade de dados:você provisionou um nó confidencial do GKE com CMEK.
  • Limites de dados:você ativou os controles de conformidade da plataforma para um ambiente regulamentado.

Documentos de referência