Skip to content

Tutorial: início rápido

Objetivo

Ao final você vai guardar um segredo, emitir um token embrulhado e ver um agente listar a credencial e chamar uma API com ela, sem que o valor volte.

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

Como rodar

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

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

1. O humano guarda um segredo e uma política

Fora do chat, como administrador do cofre. API_URL também é guardada: qualquer valor pode virar referência, não só senhas.

# The human stores a secret and a read policy (outside the chat)

$ bao kv put -mount=secret my-project/dev API_TOKEN=tok-fake-not-a-real-secret API_URL=http://127.0.0.1:18080/health
======= Secret Path =======
secret/data/my-project/dev

======= Metadata =======
Key                Value
---                -----
created_time       <time>
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1
exit_code=0

$ bao policy write my-project-read deploy/policy-project-read.hcl
Success! Uploaded policy: my-project-read
exit_code=0

2. O agente vê as tools, a sessão e os nomes

Cada khcall é uma sessão MCP, e cada sessão usa um token embrulhado novo. keyholder_status informa o TTL e as políticas, mas nunca o token; keyholder_list devolve só nomes.

# The agent sees the tools, the session and the reference names

$ BAO_WRAPPING_TOKEN=<wrapped token> khcall -tools
keyholder_list
keyholder_run
keyholder_status
exit_code=0

$ BAO_WRAPPING_TOKEN=<wrapped token> khcall keyholder_status keyholder_list
### keyholder_status
{
  "addr": "http://127.0.0.1:18200",
  "initialized": true,
  "kv_mount": "secret",
  "scope": "my-project",
  "sealed": false,
  "server_version": "2.7.1",
  "token_expire_time": "<time>",
  "token_policies": [
    "default",
    "my-project-read"
  ],
  "token_renewable": true,
  "token_ttl_seconds": <ttl>
}
### keyholder_list
{
  "entries": [
    {
      "ref": "vault://my-project/dev/API_TOKEN",
      "version": 1
    },
    {
      "ref": "vault://my-project/dev/API_URL",
      "version": 1
    }
  ],
  "note": "Use {{vault://path/KEY}} in the args, env or files of keyholder_run.",
  "scope": "my-project"
}
exit_code=0

3. O agente chama uma API com o token

A API de teste responde com o cabeçalho que recebeu. O agente lê [hidden:...]; a última linha confirma, por hash, que a API recebeu o valor real guardado. A linha de auditoria no stderr nomeia o comando e as referências, nunca o valor.

# The agent calls an API with the token; the value is masked

$ BAO_WRAPPING_TOKEN=<wrapped token> khcall keyholder_run '{"command":"curl","args":["-sS","-H","Authorization: Bearer {{vault://my-project/dev/API_TOKEN}}","{{vault://my-project/dev/API_URL}}"]}'
{
  "exit_code": 0,
  "refs_used": [
    "vault://my-project/dev/API_TOKEN",
    "vault://my-project/dev/API_URL"
  ],
  "stderr": "",
  "stdout": "api says: hello, caller with header Authorization: Bearer [hidden:vault://my-project/dev/API_TOKEN]\n"
}
--- stderr
<timestamp> audit cmd="curl" refs=[vault://my-project/dev/API_TOKEN vault://my-project/dev/API_URL] exit=0 dur=<duration> status=ok
exit_code=0

Did the API receive the stored token? yes