#3796·openbao

Followers return stale entity group membership when using cross-namespace identities and standby reads

Author: indjbCreated Aug 13, 2026Updated Sep 22, 2026
Labelsbugroadmap:scalabilityidentity

Describe the bug

When using unsafe_cross_namespace_identity=true with standby reads enabled (in a multi-node, Raft-backed cluster), creating even a few dozen groups with cross-namespace membership can cause the leader and followers to return different sets of groups for an entity.

The difference in group membership is not merely cosmetic -- the followers will enforce request authorization based on policies in this incorrect set of groups, returning 403s for requests the leader would have allowed (having the correct view of groups).

To Reproduce

The following POC reproduces the bug reliably via Docker Compose. It consists of only two files:

docker-compose.yml

poc.sh

Bringing up the POC and looking at the logs of the poc service shows the divergence:

openbao-inconsistency-poc-poc-1  | REPRODUCED — at least one follower's entity has fewer group edges than the leader.  Counts:
openbao-inconsistency-poc-poc-1  |      Node node1: {"direct":30,"inherited":30,"total":60}
openbao-inconsistency-poc-poc-1  |      Node node2: {"direct":28,"inherited":23,"total":51}
openbao-inconsistency-poc-poc-1  |      Node node3: {"direct":28,"inherited":23,"total":51}

These counts represent the numbers of groups reported for the same entity by each of the nodes (node1 being the leader).

Expected behavior It's expected that the followers would agree with the leader about group membership for all entities.

Environment:

  • OpenBao Server Version: OpenBao v2.6.1 (ba7ad8861d0578cd4da4f7b9e5a6756d30484f8f), committed 2026-07-22T14:22:20Z
  • OpenBao CLI Version (retrieve with bao version): n/a
  • Server Operating System/Architecture: Docker in Linux

OpenBao server configuration file(s):

The POC creates a different file per server, but the leader has:

hcl
disable_mlock                   = true
ui                              = false
disable_standby_reads           = false
unsafe_cross_namespace_identity = true
storage "raft" {
  path = "/openbao/file"
  node_id = "node1"
  retry_join { leader_api_addr = "http://node1:8200" }
  retry_join { leader_api_addr = "http://node2:8200" }
  retry_join { leader_api_addr = "http://node3:8200" }
}
listener "tcp" {
  address         = "0.0.0.0:8200"
  cluster_address = "0.0.0.0:8201"
  tls_disable     = true
}
api_addr     = "http://node1:8200"
cluster_addr = "http://node1:8201"

Note that the POC also allows disabling standby reads in order to confirm that that change removes the divergence.