openbao-session
Hook SessionStart untuk Claude Code dan Codex yang menyuntikkan token OpenBao berumur pendek ke lingkungan sesi agent. Dengan ini agent tidak perlu memegang credential statis — setiap sesi mendapat token baru yang scoped dan kadaluarsa sendiri.
Cara kerja
Saat sesi mulai, hooks/bao-session.sh:
- Memastikan SSH tunnel loopback ke listener VPC privat OpenBao hidup (
127.0.0.1:8200 → 10.104.0.12:8200lewat jumphostmbu-backup-jumphost). - Mengambil CA cert OpenBao (
/opt/openbao/tls/tls.crt) dan menyimpannya lokal. - Membaca bootstrap credential dari secrets store lokal (
manage.py get openbao bootstrap_token). - Mint token sesi
claude-session(TTL4h, renewable) memakai bootstrap credential sebagai caller; bilaOPENBAO_SESSION_ENTITYdiset, token dikaitkan ke entity pemakai (-entity-alias) sehingga{{identity.entity.id}}resolve dan sesi dapat membacahumans/self. - Menyuntikkan
OPENBAO_TOKEN,BAO_ADDR,BAO_CACERT,BAO_TLS_SERVER_NAMEke sesi:
| Host | Mekanisme injeksi |
|---|---|
| Claude Code | Menulis export OPENBAO_TOKEN=... ke $CLAUDE_ENV_FILE — file yang di-source Claude Code ke setiap command Bash sesi itu. |
| Codex / host lain | Hook Codex tidak bisa persist env (proses hook terpisah). Skrip menulis session env file (mode 600) dan memberitahu agent lewat additionalContext untuk source file itu — nilai token tidak pernah masuk konteks model. |
Token sesi cuma bisa membaca secret yang diizinkan policy claude-session (bukan semua). Semua akses tercatat di audit OpenBao.
Prasyarat sekali-jalan (platform admin)
Dengan token admin di jumphost (lihat OpenBao Production Operations and Recovery):
export BAO_ADDR=https://10.104.0.12:8200
export BAO_CACERT=/opt/openbao/tls/tls.crt
export BAO_TOKEN=<token admin Anda> # jangan di-paste ke chat
# 1. Policy bootstrap: bisa membuat token, TIDAK bisa membaca secret.
# Wajib menyertakan auth/token/create/* agar pembuatan token via -role (entity-alias) diizinkan.
cat > /tmp/openbao-session-creator.hcl <<'EOF'
path "auth/token/create" {
capabilities = ["create", "update", "sudo"]
}
path "auth/token/create/*" {
capabilities = ["create", "update", "sudo"]
}
path "auth/token/renew-self" { capabilities = ["update"] }
path "auth/token/revoke-self" { capabilities = ["update"] }
path "auth/token/lookup-self" { capabilities = ["read"] }
EOF
bao policy write openbao-session-creator /tmp/openbao-session-creator.hcl
# 2. Policy sesi: baca-only untuk secret yang memang di-assign ke agent.
# humans/self otomatis ter-scope ke entity pemakai via {{identity.entity.id}}
cat > /tmp/claude-session.hcl <<'EOF'
# Refine daftar path di sini sesuai owner/consumer assignment.
path "shared/data/*" { capabilities = ["read", "list"] }
path "shared/metadata/*" { capabilities = ["read", "list"] }
path "humans/data/{{identity.entity.id}}/*" { capabilities = ["read", "list"] }
path "humans/metadata/{{identity.entity.id}}/*" { capabilities = ["read", "list"] }
EOF
bao policy write claude-session /tmp/claude-session.hcl
# 3. Token roles (wajib utk -entity-alias). Perluas allowed_entity_aliases sesuai tim.
bao write auth/token/roles/openbao-session \
allowed_policies=claude-session \
allowed_entity_aliases=adnan,rizal \
ttl=4h renewable=true
# 4. Issue bootstrap token (TTL panjang, renewable) dan simpan NILAINYA ke secrets store LOKAL:
bao token create -policy=openbao-session-creator -ttl=720h -renewable \
-display-name=openbao-session-bootstrap -format=json
# → ambil auth.client_token, lalu di Mac Anda:
python3 ~/.config/devops-secrets/manage.py set openbao bootstrap_token --description "OpenBao session bootstrap (creator)"
Bootstrap credential ini kuat (bisa mint token policy apa pun) tapi tidak bisa membaca nilai secret. Karena itu simpan hanya di secrets store lokal (
~/.config/devops-secrets, mode 700/600), jangan di vault/repo/chat. Upgrade ke AppRole atau OIDC saat identity provider disetujui.
Instalasi
Claude Code
- Daftarkan marketplace (jika belum):
claude plugin marketplace add infra-plugins https://git.senkensha.space/senkensha/infra-plugins.git - Pasang:
claude plugin install openbao-session@infra-plugins - Konfirmasi hook aktif: buka sesi baru, lihat status message "Provisioning OpenBao session token...", lalu
echo ${OPENBAO_TOKEN:+SET}.
Codex
codex plugin install openbao-session@infra-plugins(marketplace sudah terdaftar sebagaiinfra-plugins).
Konfigurasi (opsional, via env)
| Variable | Default | Keterangan |
|---|---|---|
OPENBAO_SESSION_CONF_DIR |
~/.config/openbao |
dir cache CA cert + binary bao |
OPENBAO_SESSION_LOCAL_PORT |
8200 |
port tunnel lokal |
OPENBAO_SESSION_VPC_ADDR |
10.104.0.12 |
alamat VPC listener OpenBao |
OPENBAO_SESSION_DROPLET |
mbu-backup-jumphost |
droplet jumphost |
OPENBAO_SESSION_HOST |
(kosong) | public IP jumphost eksplisit (default: resolve via doctl) |
OPENBAO_SESSION_SSH_KEY |
~/.ssh/id_ed25519 |
key SSH ke jumphost |
OPENBAO_SESSION_POLICY |
claude-session |
policy token sesi |
OPENBAO_SESSION_TTL |
4h |
umur token sesi |
OPENBAO_SESSION_ENTITY |
(kosong) | nama entity OpenBao pemakai (mis. adnan, rizal) → token sesi diikat ke entity (aktifkan humans/self) |
OPENBAO_SESSION_ROLE |
(kosong) | token role utk sesi (mis. openbao-session). Wajib diisi jika OPENBAO_SESSION_ENTITY diset (-entity-alias hanya bekerja dgn -role) |
OPENBAO_SESSION_BAO_VER |
2.6.2 |
versi binary bao (auto-download jika belum ada) |
OPENBAO_SESSION_SECRETS_HELPER |
~/.config/devops-secrets/manage.py |
helper baca bootstrap |
OPENBAO_SESSION_BOOTSTRAP_TOOL / _KEY |
openbao / bootstrap_token |
lokasi bootstrap di secrets store |
Keamanan
- Nilai secret tidak pernah ditulis ke repo, chat, atau log; token sesi mengalir lewat
$CLAUDE_ENV_FILE(Claude) atau session env file mode 600 (Codex), bukan argv dan bukan ke konteks model. - Token sesi short-lived (
4h, renewable) dan scoped ke policyclaude-sessionsaja. humans/selfhanya terbaca lewat token yang terikat entity pemakai ({{identity.entity.id}}) — sesi orang lain tidak bisa membaca ruang pribadi Anda.- Bootstrap credential tidak bisa membaca secret, tapi bisa mint token → rotasi bila dicurigai bocor: buat bootstrap baru,
manage.py set, revoke yang lama (bao token revoke <accessor>). - Tunnel hanya bind
127.0.0.1; jangan pernah expose port publik atau pakai TLS skip-verify.