Isolamento
Cada time, projeto e serviço roda isolado dos demais. Esta página diz o que você pode assumir (e o que não deve tentar). Ela não lista regras internas: o objetivo é você projetar o app certo, não conhecer a parede.
Serviços: um container, sem privilégio
Seção intitulada “Serviços: um container, sem privilégio”- Um serviço = um container próprio, sem root. Se a imagem pede root, a plataforma o força a um usuário sem privilégio; se o app não funcionar assim, o deploy falha com
image_requires_roote a ação é declararbuild.user(Tabela de erros). - Sistema de arquivos somente leitura. Escreva em
/tmp(memória, pequeno) ou em um volume. Dados fora do volume somem a cada deploy. - Sem capabilities extras e sem escalar privilégio: não há
sudo,setuidútil, montar discos, mexer em rede ou em módulos do kernel. Portas abaixo de 1024 não são acessíveis ao app. - Sandbox de kernel. Os containers rodam sob um runtime com sandbox (gVisor), de modo que uma falha no app não chega ao kernel do host. Algumas chamadas de sistema exóticas não existem; apps comuns (web, workers, bancos embarcados) não notam.
- Limites de recursos por serviço: memória, CPU e número de processos/threads. Estourar a memória reinicia o container (veja o log de execução); um fork bomb só derruba o próprio serviço. Os máximos dependem do plano (Limites e cotas, Escala e recursos).
- Cada projeto tem a sua rede privada. Os serviços do mesmo projeto se encontram pelo
name(Rede privada). Serviços de outros projetos e de outros times não são alcançáveis, nem pelo nome nem pelo IP. - Serviço
privatenão tem rota pública; sópublicrecebe URL e domínio. - O app não alcança o host da plataforma, a rede interna da infraestrutura nem os endpoints de metadados da nuvem. O tráfego de saída para a internet pública é permitido, com uma exceção prática: envio direto de e-mail por SMTP é bloqueado. Use um provedor de e-mail por API HTTPS.
- Entrada: só o proxy da plataforma fala com o seu app, por HTTPS na borda. Confie em
X-Forwarded-*apenas vindo dele.
Volumes
Seção intitulada “Volumes”Cada volume pertence a um serviço e só ele o monta. Há cota de tamanho. O volume é preservado entre deploys.
Bancos gerenciados
Seção intitulada “Bancos gerenciados”Cada banco é uma instância lógica só sua: usuário e credencial próprios, sem privilégios administrativos, conexão somente com TLS e somente a partir de origens autorizadas (os serviços do seu projeto). Uma credencial abre o seu banco e nenhum outro: nem os de outros projetos do mesmo time. Não há SUPERUSER, CREATE ROLE/DATABASE, leitura de arquivos do servidor nem execução de programas. Esperam-se erros de permissão se você tentar. Quando o banco atinge a cota (quota_mb) ele vira somente leitura até você reduzir os dados (Bancos).
Ao rotacionar a credencial, a antiga deixa de valer.
Times e projetos na API
Seção intitulada “Times e projetos na API”- Todo recurso pertence a um time. Recurso de outro time responde
404, nunca403: não é possível descobrir se um id existe. Não varie ids para “testar”. - O token carrega o time e (opcional) os projetos permitidos; o servidor ignora qualquer
team_id/project_idenviado no corpo. Escopos finos por rota (Tokens e escopos). - Valores sensíveis de variáveis só saem com o escopo
env:reveal(e, para criá-lo, confirmação forte de uma pessoa). Respostas de recusa nunca carregam segredo nem dados do recurso alheio. - Referências
${{svc.VAR}}só enxergam o próprio projeto; apontar para outro projeto ou time responde422 unresolved_reference. - Parâmetros de template e valores de variável são tratados como texto literal:
${{...}}dentro de um parâmetro não vira referência.
Como isso testa
Seção intitulada “Como isso testa”A plataforma roda continuamente suítes que tentam atravessar essas paredes (containers que atacam vizinhos, credenciais de banco usadas fora do seu banco, tokens de um time em recursos de outro). Se você achar um caminho que atravessa, é uma falha de segurança: reporte pelo canal descrito em Reportar abuso (security no assunto) em vez de explorar.
O que isso significa para o seu agent
Seção intitulada “O que isso significa para o seu agent”- Escreva só em
/tmpou no volume; não dependa de root. - Fale com outros serviços do projeto pelo nome; use
privatepara o que não deve ter URL. - Use as credenciais de banco entregues por variável (referências
${{db.…}}, veja Conexão e referências), nunca outras. 404em recurso que “deveria existir” quase sempre é id ou time errado: liste comGETe use o id devolvido.