Skip to content

Tutorial: proteções

Objetivo

Ao final você vai ver o escopo do projeto, a lista de comandos permitidos e o filtro de ambiente recusarem o que devem, mesmo com uma política ampla no cofre.

Cada comando e cada saída abaixo vêm de uma execução real, gravada em demo/tutorials/guardrails/expected/ e conferida por run.sh --check. As saídas são do programa, em inglês.

Como rodar

bash demo/tutorials/guardrails/run.sh all
bash demo/tutorials/guardrails/run.sh --check

Script: demo/tutorials/guardrails/run.sh.

1. Só o escopo do projeto

O token aqui tem uma política ampla de propósito (secret/*). Mesmo assim keyholder_list mostra só my-project, e uma referência a other-project é recusada antes de qualquer leitura.

# Only the project scope is listed and usable, even with a broad policy

$ BAO_WRAPPING_TOKEN=<wrapped token> khcall keyholder_list keyholder_run '{"command":"curl","args":["-sS","-H","X-Pass: {{vault://other-project/prod/DB_PASSWORD}}","http://127.0.0.1:9/"]}'
### keyholder_list
{
  "entries": [
    {
      "ref": "vault://my-project/dev/API_TOKEN",
      "version": 1
    }
  ],
  "note": "Use {{vault://path/KEY}} in the args, env or files of keyholder_run.",
  "scope": "my-project"
}
### keyholder_run
error: vault://other-project/prod/DB_PASSWORD: reference outside the project scope (my-project)
--- stderr
<timestamp> audit cmd="curl" refs=[] exit=0 dur=<duration> status=error: vault://other-project/prod/DB_PASSWORD: reference outside the project scope (my-project)
exit_code=1

2. A lista de comandos permitidos

Comando fora da lista, caminho no lugar do nome e placeholder como comando: todos recusados.

# Commands outside the list, with a path or with a placeholder are refused

$ BAO_WRAPPING_TOKEN=<wrapped token> khcall keyholder_run '{"command":"sh","args":["-c","echo hi"]}' keyholder_run '{"command":"/usr/bin/curl","args":["--version"]}' keyholder_run '{"command":"{{vault://my-project/dev/API_TOKEN}}"}'
### keyholder_run
error: command not in the allow list: "sh" (allowed: curl, printenv)
### keyholder_run
error: command not in the allow list: give only the command name
### keyholder_run
error: command not in the allow list: give only the command name
--- stderr
<timestamp> audit cmd="sh" refs=[] exit=0 dur=<duration> status=error: command not in the allow list: "sh" (allowed: curl, printenv)
<timestamp> audit cmd="/usr/bin/curl" refs=[] exit=0 dur=<duration> status=error: command not in the allow list: give only the command name
<timestamp> audit cmd="{{vault://my-project/dev/API_TOKEN}}" refs=[] exit=0 dur=<duration> status=error: command not in the allow list: give only the command name
exit_code=1

3. Variáveis reservadas

O agente não consegue definir BAO_*, VAULT_* ou KEYHOLDER_* para o processo filho, por exemplo para apontá-lo para outro cofre.

# The agent cannot set BAO_*, VAULT_* or KEYHOLDER_* variables

$ BAO_WRAPPING_TOKEN=<wrapped token> khcall keyholder_run '{"command":"curl","args":["--version"],"env":{"BAO_ADDR":"http://attacker.example.com"}}'
error: variable name not allowed: "BAO_ADDR"
--- stderr
<timestamp> audit cmd="curl" refs=[] exit=0 dur=<duration> status=error: variable name not allowed: "BAO_ADDR"
exit_code=1

4. O token do cofre nunca chega ao processo filho

printenv está liberado neste tutorial só para provar o ponto; nunca o libere em uso real. O servidor subiu com BAO_TOKEN definido, e o filho não o recebe.

# The vault token never reaches the child process

The server itself was started with BAO_TOKEN set below; the child must not see it.

$ BAO_TOKEN=<root token> BAO_WRAPPING_TOKEN=<wrapped token> khcall keyholder_run '{"command":"printenv","args":["BAO_TOKEN"]}'
{
  "exit_code": 1,
  "refs_used": [],
  "stderr": "",
  "stdout": ""
}
--- stderr
<timestamp> audit cmd="printenv" refs=[] exit=1 dur=<duration> status=ok
exit_code=0

printenv exits 1 and prints nothing: BAO_TOKEN is not set in the child process.