---
id: w4/m5/t004
title: "Kubernetes auth method: role + policy for the bex-api ServiceAccount scoped to tenants/*"
worker: worker4
status: done
estimate: 30m
depends_on: [w4/m5/t003]
---

## Objective

bex components authenticate to OpenBao with their own ServiceAccounts, not the root token: enable the Kubernetes auth method, define a `bex-api` policy granting CRUD on `tenants/*` (data + metadata paths for KV v2) and nothing else, and bind it to the bex-api ServiceAccount via an auth role. Configuration applied idempotently by script (extend `bao-init.sh` or a sibling), not by hand.

## Context

- OpenBao Kubernetes auth: reviewer JWT / token-review API against the app cluster's apiserver.
- bex-api's ServiceAccount lives in `bex-system` (see `operator/config/` RBAC for the exact SA name).
- Root token stays in `.env` for break-glass only; the m6 product path uses this SA login exclusively.
- Policy scope is the enforcement half of "tenants never talk to OpenBao directly" — bex-api is the sole broker.

## Steps

1. Extend `scripts/bao-init.sh` (or add `scripts/bao-auth.sh`) to: enable `auth/kubernetes`, configure it for the cluster, write the `bex-api` policy, create the role binding SA → policy.
2. Idempotent + `DRY_RUN=1` like t003.
3. Verify manually: a token obtained via the SA login can `kv put/get tenants/...` but gets 403 on `sys/health`-adjacent privileged paths and other mounts.

## Files

- `scripts/bao-init.sh` (or `scripts/bao-auth.sh` new)

## Acceptance criteria

- [ ] SA login yields a token that can read/write `tenants/*` (KV v2 data + metadata).
- [ ] The same token is denied outside `tenants/*`.
- [ ] Re-running the script changes nothing (idempotent).

## Out of scope

- bex-api actually performing the login (m6 t002).
