Skip to content

Tutorial: acesso temporário

Objetivo

Ao final você vai ver que um token embrulhado funciona uma vez, que a sessão termina quando o token expira que o servidor falha de forma previsível sem token e que, quando um token expira, o OpenBao revoga tudo o que ele criou.

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

Como rodar

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

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

1. Um token embrulhado abre uma sessão

O primeiro servidor desembrulha o token. A segunda partida com o mesmo valor falha: o cofre recusa desembrulhar de novo. Um token embrulhado que vaza depois de usado não vale nada, e um token interceptado antes do uso aparece como esta falha.

# A wrapped token opens one session; reusing it fails

$ BAO_WRAPPING_TOKEN=<wrapped token> khcall 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>
}
exit_code=0

$ BAO_WRAPPING_TOKEN=<same wrapped token> khcall keyholder_status
{
  "addr": "http://127.0.0.1:18200",
  "initialized": true,
  "kv_mount": "secret",
  "scope": "my-project",
  "sealed": false,
  "server_version": "2.7.1",
  "session_error": "unwrap token: vault returned HTTP 400 (already used or expired?)",
  "token_policies": null,
  "token_renewable": false,
  "token_ttl_seconds": 0
}
--- stderr
<timestamp> session not opened: unwrap token: vault returned HTTP 400 (already used or expired?)
exit_code=0

2. Um token de 5 segundos expira no meio da sessão

Uma sessão: a primeira chamada funciona, +wait=7s pausa, keyholder_status informa a expiração e a chamada seguinte é recusada com uma mensagem que diz ao agente o que fazer.

# A 5-second token: the call works, then the same session is refused

$ BAO_WRAPPING_TOKEN=<wrapped token> khcall keyholder_run '{"command":"curl","args":["-sS","-H","Authorization: Bearer {{vault://my-project/dev/API_TOKEN}}","http://127.0.0.1:18080/"]}' +wait=7s keyholder_status keyholder_run '{"command":"curl","args":["-sS","-H","Authorization: Bearer {{vault://my-project/dev/API_TOKEN}}","http://127.0.0.1:18080/"]}'
### keyholder_run
{
  "exit_code": 0,
  "refs_used": [
    "vault://my-project/dev/API_TOKEN"
  ],
  "stderr": "",
  "stdout": "api says: hello, caller with header Authorization: Bearer [hidden:vault://my-project/dev/API_TOKEN]\n"
}
### keyholder_status
{
  "addr": "http://127.0.0.1:18200",
  "initialized": true,
  "kv_mount": "secret",
  "scope": "my-project",
  "sealed": false,
  "server_version": "2.7.1",
  "session_error": "token expired; renew access outside the chat",
  "token_policies": null,
  "token_renewable": false,
  "token_ttl_seconds": 0
}
### keyholder_run
error: vault://my-project/dev/API_TOKEN: read my-project/dev: access denied by the vault: token expired or revoked, or the policy does not allow this path; renew access outside the chat
--- stderr
<timestamp> audit cmd="curl" refs=[vault://my-project/dev/API_TOKEN] exit=0 dur=<duration> status=ok
<timestamp> audit cmd="curl" refs=[] exit=0 dur=<duration> status=error: vault://my-project/dev/API_TOKEN: read my-project/dev: access denied by the vault: token expired or revoked, or the policy does not allow this path; renew access outside the chat
exit_code=1

3. Sem token

O servidor sobe mesmo assim, para o agente chamar keyholder_status e entender por que nada funciona. As outras tools recusam.

# Without a token the server starts, explains, and refuses

$ env -u BAO_TOKEN -u BAO_WRAPPING_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",
  "session_error": "no token: set BAO_WRAPPING_TOKEN (preferred) or BAO_TOKEN",
  "token_policies": null,
  "token_renewable": false,
  "token_ttl_seconds": 0
}
### keyholder_list
error: no session with the vault; a human must renew access outside the chat
--- stderr
<timestamp> session not opened: no token: set BAO_WRAPPING_TOKEN (preferred) or BAO_TOKEN
exit_code=1

4. A expiração revoga o que o token criou

O Keyholder revoga os leases de uma execução quando o comando termina. Se essa limpeza não acontecer, porque o servidor foi encerrado à força ou a máquina caiu, a própria expiração do token os remove. Aqui um token de 5 segundos emite um certificado cujo lease duraria 1 hora; quando o token expira, o lease vai junto. O certificado vem do motor PKI do OpenBao, então o caso não depende de serviço externo.

# A 5-second token creates a 1-hour lease; when the token expires, the lease goes with it

$ BAO_TOKEN=<5-second token> bao write -field=lease_id pki/issue/agent common_name=agent.example.test ttl=1h
pki/issue/agent/<id>
exit_code=0

Leases under pki/issue/agent before the token expires: 1

$ BAO_TOKEN=<5-second token> bao token lookup
--- stderr
Error looking up token: Error making API request.

URL: GET http://127.0.0.1:18200/v1/auth/token/lookup-self
Code: 403. Errors:

* permission denied
exit_code=2

Leases under pki/issue/agent after the token expired: 0