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