Migrate one OpenBaoCluster at a time. The procedure changes controller authentication without recreating OpenBao or
its storage. Existing clusters keep Shared mode after an operator upgrade. New-cluster manifests should select
spec.controllerJWTMode: Target with self-init OIDC enabled.
Prepare the installation
- Install the new CRDs, admission policies, controller RBAC, and controller Deployment. Helm upgrades do not update existing CRDs; follow the installation procedure for your installation method.
- Confirm the controller has permission to create tokens for its own ServiceAccount in the operator namespace.
The installation Role restricts
serviceaccounts/tokento that ServiceAccount name. Do not grant this permission across tenant namespaces. - Confirm the controller Deployment supplies
POD_NAME,POD_UID,POD_NAMESPACE, andOPERATOR_SERVICE_ACCOUNT_NAME. The shipped Helm and Kustomize installations supply these values. - Establish an OpenBao administrator session that can read and update
auth/jwt-operator/role/openbao-operator. Retain an administrator login path independently of the controller JWT.spec.reconcilePoliciesdoes not grant permission to update JWT roles. - Finish active upgrade and restore operations before migration. Record the current controller role, its accepted audiences, exact subject restrictions, policies, and token lifetime settings. Preserve custom restrictions and the policy-approval grant if enrolled.
Prepare the target role
Set the namespace and cluster name, then derive the target audience from the stored CR UID:
namespace=<namespace>
cluster=<cluster>
cluster_uid=$(kubectl -n "$namespace" get openbaocluster "$cluster" -o jsonpath='{.metadata.uid}')
test -n "$cluster_uid"
target_audience="urn:openbao:controller:$cluster_uid"
Using your OpenBao administrator session, add target_audience to the existing controller role’s bound_audiences.
Retain the existing audience temporarily. Preserve all other role fields, including the subject allowlist, policy
assignments, issuer configuration, and TTL restrictions. Do not replace a customized role with the minimal bootstrap
example. Keep backup, restore, and upgrade roles unchanged.
Verify a fresh JWT issued for the target audience can log in as openbao-operator before changing the CR. Use the
actual controller ServiceAccount and Kubernetes issuer. Handle test JWTs as credentials: do not print them, pass them
in command-line arguments, or retain them in shell history or logs.
The role still accepts the shared credential during this stage. This is migration preparation, not proof of isolation.
Switch the controller
Set the mode in the GitOps source of truth, or apply this patch if the resource is managed directly:
kubectl -n "$namespace" patch openbaocluster "$cluster" --type=merge \
-p '{"spec":{"controllerJWTMode":"Target"}}'
The CR must have both spec.selfInit.enabled and spec.selfInit.oidc.enabled set to true. This does not rerun self-init
on an initialized cluster. The operator requests a ten-minute Pod-bound JWT for the target audience and uses it for
Raft maintenance and approved policy reconciliation. Verify that these operations succeed without authentication errors.
Remove shared trust and verify isolation
- Update the controller role to accept only the target audience. Preserve its other restrictions and grants.
- Verify a fresh target-specific JWT succeeds against this target.
- Verify a fresh JWT for the old shared audience fails against this target.
- Verify a target-specific JWT for an unrelated cluster fails against this target, and this target’s JWT fails there.
- Test the configured transport. If both
inlineandstandardare supported in your deployment, verify both. - Revoke existing controller OpenBao sessions issued before the role change, or wait for their effective maximum lifetime. Changing a JWT role does not revoke previously issued OpenBao tokens. Account for renewable sessions.
- Take a new snapshot after role verification and record the audience in the recovery procedure.
Successful login with the new JWT does not establish isolation while another role or audience still accepts the shared controller identity. Inspect administrator-created roles on the JWT mount as part of verification. The selected CR mode records how the controller obtains credentials; it does not attest to every authentication grant inside OpenBao.
Shared targets in the same installation remain exposed to replay among targets that trust the same controller identity and audience. Complete migration or use separate, scoped installations before claiming isolation for the whole fleet.
Recover from older snapshots
Snapshots include JWT role configuration. An older snapshot can remove target trust or restore shared trust. A recreated OpenBaoCluster also receives a new UID and audience. Arrange a usable administrator login in the restored state, or preauthorize the recovery destination’s audience on the source before taking the snapshot. Source and destination then share a deliberate recovery authentication domain; unrelated tenants must not join that allowlist.
After recovery, reapply the intended role configuration and repeat the positive and negative authentication checks. The controller remains in Target mode and can report authentication failures until this is complete. See restore authentication.