O ChatCLI foi projetado com segurança em profundidade (defense-in-depth). Esta página documenta todas as medidas de proteção implementadas, como configurá-las e as boas práticas para ambientes de produção.


Resumo das Proteções

CamadaProteçãoStatus
AutenticaçãoComparação de tokens em tempo constante (crypto/subtle)Ativo
ShellQuoting POSIX para prevenir injeção em argumentos de shellAtivo
EditoresValidação de EDITOR contra allowlist de editores conhecidosAtivo
Comandos50+ padrões regex para detecção de comandos perigososAtivo
PoliciesMatching com word-boundary para evitar escalação de permissõesAtivo
gRPCReflection desabilitado por padrão (oculta schema do serviço)Ativo
BináriosResolução de stty via exec.LookPath (evita injeção via PATH)Ativo
Containersread-only filesystem, no-new-privileges, drop ALL capabilitiesAtivo
KubernetesRBAC namespace-scoped por padrão, SecurityContext restritivoAtivo
RedeTLS opcional com warning quando desabilitadoAtivo

Autenticação do Servidor gRPC

Token Bearer com Comparação em Tempo Constante

O servidor gRPC usa autenticação via Bearer token no header authorization de cada request. A comparação do token utiliza crypto/subtle.ConstantTimeCompare, que previne ataques de timing — um atacante não consegue inferir caracteres corretos medindo o tempo de resposta.

  # Definir token via flag
chatcli server --token meu-token-secreto

# Ou via variável de ambiente
export CHATCLI_SERVER_TOKEN=meu-token-secreto
chatcli server
  

O endpoint /Health é sempre acessível sem autenticação para permitir health checks de load balancers e orquestradores.

TLS (Opcional)

O TLS é totalmente opcional. Em ambiente de desenvolvimento local, você pode rodar sem TLS sem problemas. Para produção, recomendamos fortemente habilitar TLS:

  # Produção: com TLS
chatcli server --tls-cert cert.pem --tls-key key.pem --token meu-token

# Desenvolvimento: sem TLS (um warning será logado)
chatcli server
  

Quando o cliente se conecta sem TLS, um log de warning é emitido para lembrar sobre o uso em produção. O comportamento funcional não muda — a conexão continua funcionando normalmente.


Proteção contra Injeção de Shell

ShellQuote — Quoting POSIX Seguro

Todos os pontos do código onde valores dinâmicos são interpolados em comandos shell utilizam a função utils.ShellQuote(), que aplica quoting POSIX com aspas simples:

  // Entrada: it's a "test" $(whoami)
// Saída:   'it'\''s a "test" $(whoami)'
  

Isso protege contra:

  • Injeção via aspas: '; rm -rf /; echo '
  • Substituição de comandos: $(malicious) ou `malicious`
  • Expansão de variáveis: $HOME, ${PATH}
  • Pipe/redirecionamento: | cat /etc/passwd, > /etc/crontab

Pontos Protegidos

ArquivoContexto
cli/agent_mode.goDry-run echo de comandos (simulação)
cli/cli.goSource do arquivo de configuração do shell (~/.bashrc, etc.)
cli/agent/command_executor.goSource do arquivo de configuração do shell (execução interativa)

Resolução de Binários via LookPath

O binário stty (usado para restaurar o terminal) é resolvido uma única vez no startup via exec.LookPath("stty"), retornando o caminho absoluto. Isso evita que um atacante coloque um stty malicioso no PATH.

Validação do EDITOR

Quando o usuário edita comandos no modo agente, a variável EDITOR é validada contra uma allowlist de editores conhecidos:

  vim, vi, nvim, nano, emacs, code, subl, micro, helix, hx,
ed, pico, joe, ne, kate, gedit, kwrite, notepad++, atom
  

Se EDITOR contiver um valor desconhecido (ex: EDITOR="/tmp/exploit.sh"), a operação é recusada com erro. O editor validado é então resolvido via exec.LookPath para obter o caminho absoluto.


Validação de Comandos

50+ Padrões de Detecção

O CommandValidator analisa cada comando sugerido pela IA antes da execução, verificando contra mais de 50 padrões regex que cobrem:

CategoriaExemplos
Destruição de dadosrm -rf /, dd if=, mkfs, drop database
Execução remotacurl | bash, wget | sh, base64 | bash
Injeção de códigopython -c, perl -e, ruby -e, node -e, php -r, eval
Substituição de comandos$(curl ...), `wget ...`
Substituição de processos<(cmd), >(cmd)
Escalação de privilégiossudo, chmod 777 /, chown -R /
Manipulação de redenc -l, iptables -F, /dev/tcp/
Kernelinsmod, modprobe, rmmod, sysctl -w
Evasão${IFS;cmd}, VAR=x; bash, export PATH=

Denylist Customizada

Adicione seus próprios padrões via variável de ambiente:

  # Bloquear terraform destroy e kubectl delete namespace
export CHATCLI_AGENT_DENYLIST="terraform destroy;kubectl delete namespace"
  

Controle de sudo

  # Permitir sudo (use com cautela)
export CHATCLI_AGENT_ALLOW_SUDO=true
  

Governança do Modo Coder (Policy Manager)

Matching com Word Boundary

O sistema de policies usa matching com word boundary para prevenir escalação de permissões por prefixo. Exemplo:

RegraComandoResultado
@coder read = allow@coder read file.txtPermitido
@coder read = allow@coder readlink /tmpBloqueado (ask)
@coder read --file /etc = deny@coder read --file /etc/passwdBloqueado (deny)

A lógica verifica se o próximo caractere após o match é um separador (espaço, /, =, etc.) e não a continuação de uma palavra (letra, dígito, -, _). Isso garante que read não case com readlink.

Regras Padrão

Os comandos de leitura são permitidos por padrão:

  {
  "rules": [
    { "pattern": "@coder read", "action": "allow" },
    { "pattern": "@coder tree", "action": "allow" },
    { "pattern": "@coder search", "action": "allow" },
    { "pattern": "@coder git-status", "action": "allow" },
    { "pattern": "@coder git-diff", "action": "allow" },
    { "pattern": "@coder git-log", "action": "allow" },
    { "pattern": "@coder git-changed", "action": "allow" },
    { "pattern": "@coder git-branch", "action": "allow" }
  ]
}
  

Para mais detalhes sobre o sistema de governança, veja a documentação do Modo Coder.


Segurança do Servidor gRPC

gRPC Reflection (Desabilitado por Padrão)

O gRPC reflection expoe o schema completo do serviço, permitindo que ferramentas como grpcurl e grpcui descubram e chamem todos os RPCs. Em produção, isso pode facilitar reconhecimento por atacantes.

Por padrão, o reflection está desabilitado. Para habilitar (desenvolvimento/debug):

  # Via variável de ambiente
export CHATCLI_GRPC_REFLECTION=true
chatcli server

# Ou via campo EnableReflection no Config (programatico)
  
VariávelDescriçãoPadrão
CHATCLI_GRPC_REFLECTIONHabilita gRPC reflection (true/false)false

Interceptors de Segurança

Todas as requests passam por uma cadeia de interceptors:

  1. Recovery: Captura panics e retorna erro gRPC em vez de derrubar o servidor
  2. Logging: Registra metodo, duração e status de cada request
  3. Auth: Valida Bearer token (quando configurado)

Verificação de Versão

O ChatCLI verifica automaticamente se há uma versão mais recente no GitHub. Para desabilitar (ex: ambientes air-gapped ou CI/CD):

  export CHATCLI_DISABLE_VERSION_CHECK=true
  
VariávelDescriçãoPadrão
CHATCLI_DISABLE_VERSION_CHECKDesabilita a verificação automática de versão (true/false)false

Segurança de Containers (Docker)

O docker-compose.yml do projeto inclui as seguintes medidas de hardening:

  services:
  chatcli-server:
    read_only: true           # Filesystem somente-leitura
    tmpfs:
      - /tmp:size=100M        # Diretório temporário em memória
    security_opt:
      - no-new-privileges:true  # Impede escalação de privilégios
    deploy:
      resources:
        limits:
          cpus: "2.0"         # Limite de CPU
          memory: 1G          # Limite de memória
  

O que cada medida faz

MedidaProteção
read_only: trueImpede que malware grave arquivos no filesystem do container
tmpfsFornece diretório /tmp em memória com tamanho limitado
no-new-privilegesImpede que processos filhos ganhem mais privilégios que o pai
Resource limitsPrevine consumo excessivo de CPU/memória (DoS)

Segurança no Kubernetes (Helm)

Pod SecurityContext

O Helm chart define um SecurityContext restritivo por padrão:

  # values.yaml
podSecurityContext:
  runAsNonRoot: true          # Obriga execução como usuário não-root
  runAsUser: 1000
  runAsGroup: 1000
  fsGroup: 1000
  seccompProfile:
    type: RuntimeDefault       # Filtro de syscalls do kernel

securityContext:
  allowPrivilegeEscalation: false  # Sem escalação de privilégios
  readOnlyRootFilesystem: true     # Filesystem somente-leitura
  capabilities:
    drop:
      - ALL                        # Remove TODAS as capabilities Linux
  

RBAC Namespace-Scoped (Padrão)

Por padrão, o chart cria Role e RoleBinding (namespace-scoped) em vez de ClusterRole. Isso garante que o ChatCLI só tenha acesso ao namespace onde está deployado.

  # values.yaml
rbac:
  create: true
  clusterWide: false   # false = Role (namespace-scoped, padrão)
                       # true  = ClusterRole (cluster-wide)
  

Para monitorar deployments em múltiplos namespaces, habilite clusterWide:

  helm install chatcli deploy/helm/chatcli \
  --set rbac.clusterWide=true \
  --set watcher.enabled=true
  

tmpfs Automático

Quando securityContext.readOnlyRootFilesystem está true, o chart automaticamente monta um volume emptyDir em /tmp (limitado a 100Mi) para que a aplicação possa gravar arquivos temporários.


Variáveis de Ambiente de Segurança

Resumo de todas as variáveis relacionadas a segurança:

VariávelDescriçãoPadrão
CHATCLI_SERVER_TOKENToken de autenticação do servidor gRPC"" (sem auth)
CHATCLI_SERVER_TLS_CERTCertificado TLS do servidor""
CHATCLI_SERVER_TLS_KEYChave TLS do servidor""
CHATCLI_GRPC_REFLECTIONHabilita gRPC reflectionfalse
CHATCLI_DISABLE_VERSION_CHECKDesabilita verificação de versãofalse
CHATCLI_AGENT_ALLOW_SUDOPermite sudo no modo agentefalse
CHATCLI_AGENT_DENYLISTPadrões regex adicionais para bloquear (; separados)""
CHATCLI_AGENT_CMD_TIMEOUTTimeout de execução por comando10m

Criptografia de Credenciais

As credenciais OAuth são armazenadas com criptografia AES-256-GCM em ~/.chatcli/auth-profiles.json. A chave de criptografia é gerada automaticamente e salva em ~/.chatcli/.auth-key com permissão 0600 (somente o dono pode ler).

ArquivoPermissãoConteúdo
~/.chatcli/auth-profiles.json0600Credenciais OAuth criptografadas
~/.chatcli/.auth-key0600Chave AES-256-GCM
~/.chatcli/coder_policy.json0600Regras de policy do Coder

Boas Práticas para Produção

1. Sempre use token de autenticação

  export CHATCLI_SERVER_TOKEN=$(openssl rand -hex 32)
chatcli server --token $CHATCLI_SERVER_TOKEN
  

2. Habilite TLS em produção

  chatcli server --tls-cert cert.pem --tls-key key.pem
  

3. Mantenha gRPC reflection desabilitado

Não defina CHATCLI_GRPC_REFLECTION=true em produção. Use apenas para debugging local.

4. Use RBAC namespace-scoped

Mantenha rbac.clusterWide: false (padrão) a menos que precise monitorar múltiplos namespaces.

5. Revise as policies do Coder regularmente

  cat ~/.chatcli/coder_policy.json
  

6. Configure resource limits

Sempre defina limites de CPU e memória para evitar consumo excessivo:

  resources:
  requests:
    memory: "128Mi"
    cpu: "100m"
  limits:
    memory: "512Mi"
    cpu: "500m"
  

7. Mantenha o ChatCLI atualizado

A verificação de versão é habilitada por padrão. Se você desabilitou com CHATCLI_DISABLE_VERSION_CHECK, verifique periodicamente:

  chatcli --version
  

Próximo Passo