ACL: ConfigDbApiKeyStore confers roles from Cluster-scoped grants in ANY cluster #528
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixed in
3a6b2a1d(#520 stage 3). Filed for the record — this one reachedmasterinfbe7403c.ConfigDbApiKeyStore.LoadClusterGrantsAsyncselected a principal's grants withWhere(a => a.Principal == principal && a.ScopeKind == NodeAclScopeKind.Cluster)and noClusterIdpredicate. The ConfigDb holds the whole fleet's
NodeAclrows, so on a fusedadmin,drivernode aCluster-scoped grant authored in any cluster conferred the server-wideWriteOperate/AlarmAcknowledgerole.ArtifactApiKeyStorewas never affected: it reads a snapshotDeploymentArtifact.ParseDataPlaneAuthorityhas already narrowed with
ClusterFilterMode.ScopeTo. The two stores' behaviour diverged whileArtifactApiKeyStore's doc comment claimed it was "matchingConfigDbApiKeyStore" — it matched on scopekind but not on cluster.
Fix. The store takes the node's own ClusterId, derived from
AkkaClusterOptionsviaRoleParser.IsClusterRole/ClusterIdFromRole(options, notIClusterRoleInfo— resolving that from theSP is the documented boot-
StackOverflowlandmine). A null ClusterId applies no filter, mirroringClusterFilterMode.None, so single-cluster deployments are unchanged.The cluster match is done in memory after the SQL fetch, deliberately:
ParseDataPlaneAuthoritymatchesOrdinalIgnoreCase, anda.ClusterId == clusterIdin SQL is decided by database collation instead. That isnot theoretical —
Cluster:Rolesbinds verbatim (cluster-MAIN⇒MAIN) while theOTOPCUA_ROLESpathgoes through
RoleParser.Parse, which lowercases (⇒main).Regression test staged red→green:
ConfigDbApiKeyStoreTests.A_cluster_scoped_grant_from_another_cluster_confers_nothing.