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.