Isolar a execução de código de IA com o sandbox do agente

É possível implantar um ambiente de desenvolvedor para usar o cliente Python do Agent Sandbox em um cluster do Google Kubernetes Engine (GKE). Essa configuração ajuda a executar e testar com segurança o código gerado por IA, isolando o código não confiável em um ambiente Python no sandbox. Esse isolamento é essencial para proteger seu sistema contra possíveis vulnerabilidades no código gerado por IA, aumentar a velocidade de desenvolvimento e garantir implantações seguras. Para uma visão geral de como o recurso do Agent Sandbox isola o código não confiável gerado por IA, consulte Sobre o GKE Agent Sandbox.

Custos

O Agent Sandbox é oferecido sem custo extra no GKE. Os preços do GKE se aplicam aos recursos criados.

Antes de começar

  1. No Cloud de Confiance console do, na página do seletor de projetos, escolha ou crie um Cloud de Confiance projeto do.

    Funções necessárias para selecionar ou criar um projeto

    • Selecionar um projeto: a seleção de um projeto não exige um papel específico do IAM. É possível selecionar qualquer projeto em que você tenha recebido um papel.
    • Criar um projeto: para criar um projeto, é necessário ter o papel de criador de projetos (roles/resourcemanager.projectCreator), que contém a resourcemanager.projects.create permissão. Saiba como conceder papéis.

    Acessar o seletor de projetos

  2. Verifique se o faturamento está ativado para o Cloud de Confiance projeto.

  3. Ative o Artifact Registry e as APIs do Kubernetes Engine.

    Funções necessárias para ativar APIs

    Para ativar as APIs, é necessário ter o papel do IAM de administrador de uso do serviço (roles/serviceusage.serviceUsageAdmin), que contém a permissão serviceusage.services.enable. Saiba como conceder papéis.

    Ativar as APIs

  4. No Cloud de Confiance console do, ative o Cloud Shell.

    Ativar o Cloud Shell

  5. Verifique se você tem as permissões necessárias para concluir este guia.
  6. É necessário ter um cluster do GKE com o recurso do Agent Sandbox ativado. Se você não tiver um, siga as instruções em Ativar o Agent Sandbox no GKE para criar um novo cluster ou atualizar um já existente.

Funções exigidas

Para receber as permissões necessárias para criar e gerenciar sandboxes, peça ao administrador para conceder a você o papel do IAM de administrador do Kubernetes Engine (roles/container.admin) no seu projeto. Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias com papéis personalizados ou outros papéis predefinidos.

Definir as variáveis de ambiente

Para simplificar os comandos executados neste documento, é possível definir variáveis de ambiente no Cloud Shell. No Cloud Shell, defina as seguintes variáveis de ambiente úteis executando os comandos a seguir:

export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME="agent-sandbox-cluster"
export LOCATION="us-central1"
export NODE_POOL_NAME="agent-sandbox-node-pool"
export MACHINE_TYPE="e2-standard-2"

Confira uma explicação dessas variáveis de ambiente:

  • PROJECT_ID: o ID do seu projeto atual. Cloud de Confiance by S3NS A definição dessa variável ajuda a garantir que todos os recursos, como o cluster do GKE, sejam criados no projeto correto.
  • CLUSTER_NAME: o nome do cluster do GKE, por exemplo, agent-sandbox-cluster.
  • LOCATION: aregião ou zona em que o cluster do GKE está localizado. Cloud de Confiance by S3NS Defina isso como a região (por exemplo, us-central1) se você estiver usando um cluster do Autopilot ou a zona (por exemplo, us-central1-a) se estiver usando um cluster padrão.
  • NODE_POOL_NAME: o nome do pool de nós que vai executar cargas de trabalho no sandbox, por exemplo, agent-sandbox-node-pool.
  • MACHINE_TYPE: o tipo de máquina dos nós no pool de nós, por exemplo, e2-standard-2. Para mais detalhes sobre diferentes séries de máquinas e como escolher entre diferentes opções, consulte o Guia de comparação e recursos para famílias de máquinas.

Implantar um ambiente no sandbox

Esta seção mostra como criar o blueprint do sandbox (SandboxTemplate), implantar o roteador de rede necessário e instalar o cliente Python que você vai usar para interagir com o sandbox.

A maneira recomendada de criar e interagir com o sandbox é usando o cliente Python do Agentic Sandbox. Esse cliente fornece uma interface que simplifica todo o ciclo de vida de um sandbox, da criação à limpeza. É uma biblioteca Python que pode ser usada para criar, usar e excluir sandboxes de maneira programática.

O cliente usa um roteador de sandbox como um ponto de entrada central para todo o tráfego. No exemplo descrito neste documento, o cliente cria um túnel para esse roteador usando o comando kubectl port-forward, para que você não precise expor nenhum endereço IP público. O uso de kubectl port-forward não é uma solução segura e o uso dele precisa ser limitado a ambientes de desenvolvimento.

Criar um SandboxTemplate e um SandboxWarmPool

Agora, defina a configuração do sandbox criando um recurso SandboxTemplate e um SandboxWarmPool. O SandboxTemplate atua como um blueprint reutilizável que o controlador do Agent Sandbox usa para criar ambientes de sandbox consistentes e pré-configurados. O recurso SandboxWarmPool ajuda a garantir que um número especificado de pods pré-aquecidos esteja sempre em execução e pronto para ser reivindicado. Um sandbox pré-aquecido é um pod em execução que já foi inicializado. Essa pré-inicialização permite que novos sandboxes sejam criados em menos de um segundo e evita a latência de inicialização de um sandbox normal:

  1. No Cloud Shell, crie um arquivo chamado sandbox-template-and-pool.yaml com o seguinte conteúdo:

    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxTemplate
    metadata:
      name: python-runtime-template
      namespace: default
    spec:
      podTemplate:
        metadata:
          labels:
            sandbox: python-sandbox-example
        spec:
          runtimeClassName: gvisor
          automountServiceAccountToken: false # Required
          securityContext:
            runAsNonRoot: true # Required
          nodeSelector:
            sandbox.gke.io/runtime: gvisor # Required
          tolerations:
          - key: "sandbox.gke.io/runtime"
            value: "gvisor"
            effect: "NoSchedule" # Required
          containers:
          - name: python-runtime
            image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0
            ports:
            - containerPort: 8888
            readinessProbe:
              httpGet:
                path: "/"
                port: 8888
              initialDelaySeconds: 0
              periodSeconds: 1
            resources:
              requests:
                cpu: "250m"
                memory: "512Mi"
              limits:
                cpu: "500m"
                memory: "1Gi" # Required
            securityContext:
              capabilities:
                drop: ["ALL"] # Required
          restartPolicy: "OnFailure"
    ---
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxWarmPool
    metadata:
      name: python-sandbox-warmpool
      namespace: default
    spec:
      replicas: 2
      sandboxTemplateRef:
        name: python-runtime-template
    
  2. Aplique o manifesto SandboxTemplate e SandboxWarmPool:

    kubectl apply -f sandbox-template-and-pool.yaml
    

Implantar o roteador de sandbox

O cliente Python que você vai usar para criar e interagir com ambientes no sandbox usa um componente chamado roteador de sandbox para se comunicar com os sandboxes.

Para este exemplo, use o modo de desenvolvedor do cliente para testes. Esse modo é destinado ao desenvolvimento local e usa o comando kubectl port-forward para estabelecer um túnel direto da máquina local para o serviço de roteador de sandbox em execução no cluster. Essa abordagem de tunelamento evita a necessidade de um endereço IP público ou uma configuração de entrada complexa e simplifica a interação com sandboxes do ambiente local.

Siga estas etapas para implantar o roteador de sandbox:

  1. No Cloud Shell, crie um arquivo chamado sandbox-router.yaml com o seguinte conteúdo:

    # A ClusterIP Service to provide a stable endpoint for the router pods.
    apiVersion: v1
    kind: Service
    metadata:
      name: sandbox-router-svc
      namespace: default
    spec:
      type: ClusterIP
      selector:
        app: sandbox-router
      ports:
      - name: http
        protocol: TCP
        port: 8080 # The port the service will listen on
        targetPort: 8080 # The port the router container listens on (from the sandbox_router/Dockerfile)
    ---
    # The Deployment to manage and run the router pods.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sandbox-router-deployment
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sandbox-router
      template:
        metadata:
          labels:
            app: sandbox-router
        spec:
          # Ensure pods are spread across different zones for HA
          topologySpreadConstraints:
            - maxSkew: 1
              topologyKey: topology.kubernetes.io/zone
              whenUnsatisfiable: ScheduleAnyway
              labelSelector:
                matchLabels:
                  app: sandbox-router
          containers:
          - name: router
            image: us-central1-docker.pkg.dev/k8s-staging-images/agent-sandbox/sandbox-router:latest-main
            ports:
            - containerPort: 8080
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8080
              initialDelaySeconds: 5
              periodSeconds: 5
            livenessProbe:
              httpGet:
                path: /healthz
                port: 8080
              initialDelaySeconds: 10
              periodSeconds: 10
            resources:
              requests:
                cpu: "100m"
                memory: "512Mi"
              limits:
                cpu: "1000m"
                memory: "1Gi"
          securityContext:
            runAsUser: 1000
            runAsGroup: 1000
    
  2. Aplique o manifesto para implantar o roteador no cluster:

    kubectl apply -f sandbox-router.yaml
    
  3. Verifique se a implantação do roteador de sandbox está em execução corretamente:

    kubectl get deployment sandbox-router-deployment
    

    Aguarde até que a implantação mostre 2/2 ou 1/1 na coluna READY.

Instalar o cliente Python

Agora que os componentes no cluster, como o roteador de sandbox, estão implantados, a etapa preparatória final é instalar o cliente Python do Agentic Sandbox na sua máquina local. Lembre-se de que esse cliente é uma biblioteca Python que permite criar, usar e excluir sandboxes de maneira programática. Você o usa na próxima seção para testar o ambiente:

  1. Crie e ative um ambiente virtual Python:

    python3 -m venv .venv
    source .venv/bin/activate
    
  2. Instale o pacote do cliente:

    pip install k8s-agent-sandbox
    

Testar o sandbox

Com todos os componentes de configuração no lugar, agora é possível criar e interagir com um sandbox usando o cliente Python do Agentic Sandbox.

  1. No diretório agent-sandbox, crie um script Python chamado test_sandbox.py com o seguinte conteúdo:

    from k8s_agent_sandbox import SandboxClient
    from k8s_agent_sandbox.models import SandboxLocalTunnelConnectionConfig
    
    # Automatically tunnels to svc/sandbox-router-svc
    client = SandboxClient(
        connection_config=SandboxLocalTunnelConnectionConfig()
    )
    
    sandbox = client.create_sandbox(template="python-runtime-template", namespace="default")
    try:
        print(sandbox.commands.run("echo 'Hello from the sandboxed environment!'").stdout)
    except Exception as e:
        print(f"An error occurred: {e}")
    
  2. No terminal (com o ambiente virtual ainda ativo), execute o script de teste:

    python3 test_sandbox.py
    

Você verá a mensagem "Hello from the sandboxed environment!", que é a saída do sandbox.

Parabéns! Você executou um comando shell em um sandbox seguro. Usando o método sandbox.run(), é possível executar qualquer comando shell, e o Agent Sandbox executa o comando em uma barreira segura que protege os nós do cluster e outras cargas de trabalho de códigos não confiáveis. Isso oferece uma maneira segura e confiável para um agente de IA ou qualquer fluxo de trabalho automatizado executar tarefas.

Ao executar o script, o SandboxClient processa todas as etapas para você. Ele cria o recurso SandboxClaim para iniciar o sandbox, aguarda até que o sandbox esteja pronto e usa o método sandbox.run() para executar comandos shell bash dentro do contêiner seguro. Em seguida, o cliente captura e imprime o stdout desse comando. O sandbox é excluído automaticamente após a execução do programa.

Quando um recurso SandboxClaim é criado, um pod disponível é atribuído do pool quente ao objeto do sandbox e a reivindicação é marcada como pronta. O SandboxWarmPool é reabastecido automaticamente para manter o número configurado de réplicas.

Para verificar se um sandbox específico foi reivindicado ou está disponível, verifique as ownerReferences nos metadados do pod do sandbox. Se o valor do campo kind for Sandbox, o pod estará em uso. Se o valor do campo kind for SandboxWarmPool, o pod estará inativo e aguardando a reivindicação.

Executar sandboxes na produção

Neste documento, você interage com sandboxes de fora do cluster usando o Cloud Shell. O cliente Python usa suas credenciais de usuário para autenticar no cluster e gerenciar recursos de sandbox, e usa o comando kubectl port-forward para estabelecer uma conexão com sandboxes. Essas etapas funcionam bem para cenários de desenvolvimento.

Em um cenário de produção, um aplicativo de controlador (como um orquestrador de IA) é responsável por criar e gerenciar recursos de sandbox. Para usar o Agent Sandbox na produção, considere o seguinte:

  • Autenticação: o aplicativo do controlador precisa ser autenticado no servidor da API do cluster para executar sandboxes. A forma como você configura a autenticação depende de onde o aplicativo do controlador é executado, da seguinte maneira:

  • Roteamento: as solicitações do cliente Python no aplicativo do controlador precisam chegar ao roteador de sandbox no cluster. Na produção, use um dos seguintes métodos para estabelecer uma conexão de rede:

    • Se o aplicativo do controlador for executado no mesmo cluster, use a função SandboxDirectConnectionConfig para segmentar o URL e a porta usados pelo serviço de roteador de sandbox.
    • Se o aplicativo do controlador for executado fora do cluster, use a API GKE Gateway para criar um balanceador de carga interno ou externo. No código do cliente, use a função SandboxGatewayConnectionConfig para referenciar o gateway.

    Para mais informações sobre esses métodos de roteamento, consulte os exemplos de uso no GitHub e as etapas de implantação do gateway para o roteador.

  • Acesso do sandbox a Cloud de Confiance recursos: se o código do sandbox precisar enviar solicitações para Cloud de Confiance APIs, como o Cloud Storage, use uma política do IAM com a federação de identidade da carga de trabalho para o GKE para conceder à ServiceAccount do Kubernetes que o pod do sandbox usa as permissões necessárias para esse acesso. Como a política de rede padrão bloqueia o acesso ao Cloud de Confiance by S3NS servidor de metadados (169.254.169.254), é necessário personalizar a política de rede para permitir este tráfego.

  • Restrições da política de rede: por padrão, o Agent Sandbox aplica uma postura de rede segura por padrão (networkPolicyManagement: Managed). As seguintes restrições se aplicam a essa postura:

    • A entrada é bloqueada de todas as origens, exceto o roteador de sandbox designado.
    • A saída é permitida para a Internet pública, mas a saída para intervalos de LAN particulares (RFC 1918), DNS de cluster interno (CoreDNS) e o servidor de metadados do provedor de nuvem (169.254.0.0/16) é explicitamente bloqueada.

    Para usar a federação de identidade da carga de trabalho para o GKE ou acessar outros recursos particulares, é necessário definir políticas de rede personalizadas no SandboxTemplate. Para detalhes de configuração e modelos personalizáveis (como sandboxes isolados ou federação de identidade da carga de trabalho para integração do GKE), consulte Gerenciamento de políticas de rede do Agent Sandbox.

Políticas de segurança do sandbox

Para ajudar a garantir um ambiente seguro por padrão, o complemento do GKE Agent Sandbox usa políticas de admissão de validação do Kubernetes (VAPs, na sigla em inglês) para aplicar restrições de segurança aos recursos Sandbox e SandboxTemplate. Essas políticas são aplicadas automaticamente.

O complemento divide a aplicação de segurança em um modelo de política de duas camadas para maior flexibilidade. As seções a seguir descrevem essas políticas: a política principal gerenciada estritamente e a política de proteção personalizável.

Política de segurança principal (sandbox-core-policy)

A política de segurança principal aplica requisitos de isolamento que ajudam a proteger a integridade do sandbox. Essa política inclui regras que exigem o uso do gVisor, isolamento de rede, como a desativação de hostNetwork, e isolamento do sistema de arquivos, como o bloqueio de hostPath. Como o GKE gerencia essa política pela configuração addonmanager.kubernetes.io/mode: Reconcile, não é possível modificar ou substituir essas regras principais.

Política de segurança de proteção (sandbox-hardening-policy)

A política de segurança de proteção oferece outras práticas recomendadas de segurança e opções de gerenciamento. Ela aplica restrições, como descartar todos os recursos, impedir a adição de novos recursos e exigir que os contêineres sejam executados como não raiz com limites de recursos. O GKE implanta essa política no modo EnsureExists pela configuração addonmanager.kubernetes.io/mode: EnsureExists. Essa configuração significa que o GKE cria a política se ela estiver ausente, mas é possível modificar ou excluir a política ou a vinculação dela, se necessário.

Modificar ou remover restrições de proteção

Como a política de proteção é implantada no modo EnsureExists, o GKE cria a política se ela estiver ausente, mas não substitui suas modificações. Se as cargas de trabalho exigirem isenções dessas regras de proteção, é possível modificar a política para remover restrições específicas ou excluir a vinculação da política completamente.

Para modificar a política de proteção e remover uma restrição específica (por exemplo, para permitir que os contêineres sejam executados como raiz ou omitir limites de recursos), edite o recurso ValidatingAdmissionPolicy:

kubectl edit validatingadmissionpolicy sandbox-hardening-policy

No editor de texto que é aberto, localize a seção validations e remova ou modifique a expressão de restrição que bloqueia a carga de trabalho.

Como alternativa, se você quiser desativar a política de proteção completamente para o cluster, exclua a vinculação da política:

kubectl delete validatingadmissionpolicybinding sandbox-hardening-binding

Problemas conhecidos

Esta seção descreve problemas conhecidos ao usar o Agent Sandbox no GKE e como resolvê-los ou contorná-los.

A política de segurança bloqueia recursos ao usar uma malha de serviço

Se você tentar implantar um sandbox que se integra a um sidecar de malha de serviço (por exemplo, Envoy ou Istio), a criação do sandbox poderá ser bloqueada pela política de segurança de proteção com um erro como este:

sandbox create error: sandboxes.agents.x-k8s.io "claude-cli-claim-managed" is forbidden:
ValidatingAdmissionPolicy 'sandbox-hardening-policy' with binding 'sandbox-hardening-binding'
denied request: Security Violation: Capabilities.add must be empty. You cannot add capabilities.
  • Causa: os sidecars de malha de serviço geralmente usam um contêiner de inicialização, como istio-init ou proxy-init. Esses contêineres de inicialização exigem recursos como NET_ADMIN ou NET_RAW para configurar iptables regras para roteamento de saída transparente. Por padrão, a sandbox-hardening-policy do GKE bloqueia todas as adições de recursos em todos os tipos de contêineres.
  • Solução alternativa: como a política de proteção do GKE é implantada no modo EnsureExists, é possível modificar a ValidatingAdmissionPolicy para permitir que contêineres de inicialização confiáveis específicos solicitem recursos NET_ADMIN e NET_RAW. Para instruções sobre como modificar ou remover essas restrições de proteção, consulte Modificar ou remover restrições de proteção. Por exemplo, é possível atualizar as expressões ou variáveis de validação da política para isentar nomes de contêineres confiáveis da regra de recursos.

Latência ou tempo limite de saída ao se conectar às APIs do Google pelo IPv6

As cargas de trabalho dentro do sandbox podem apresentar tempos limite de conexão ou alta latência, de até dois minutos, ao tentar se conectar a recursos externos ou APIs do Google (como Vertex AI ou Cloud Storage).

  • Causa: se o cluster do GKE tiver o IPv6 de pilha dupla ativado, a resolução de DNS para as APIs do Google vai retornar endereços IPv4 (A) e IPv6 (AAAA) endereços. Alguns algoritmos em mecanismos de execução, como o Node.js, tentam se conectar pelo IPv6 primeiro. Se a VPC do GKE não tiver uma rota de saída IPv6 válida, como um Cloud NAT ou um gateway de Internet para IPv6, a conexão TCP vai parar de responder (para mais informações, consulte https://developers.google.com/style/word-list#hang) até que o tempo limite TCP SYN expire. Em seguida, a conexão TCP volta para o IPv4.
  • Resolução: para resolver esse problema, faça uma das seguintes ações:

    • Configurar a saída IPv6: para permitir que o tráfego IPv6 de saída retorne ao cluster, configure um Cloud NAT IPv6 válido ou um gateway de Internet na rede VPC.
    • Preferir IPv4 na carga de trabalho: para preferir a resolução de DNS IPv4, configure o ambiente de execução da carga de trabalho. Por exemplo, em um aplicativo Node.js, é possível definir as seguintes variáveis de ambiente na definição SandboxTemplate:

      env:
      - name: NODE_OPTIONS
        value: "--dns-result-order=ipv4first --no-network-family-autoselection"
      

Limpar recursos

Para evitar cobranças na sua Cloud de Confiance by S3NS conta, exclua o cluster do GKE criado:

gcloud container clusters delete $CLUSTER_NAME --location=$LOCATION --quiet

A seguir