Skip to content

fix(#4456): bind authenticated user on DatabaseContext in BoltNetworkExecutor#4457

Merged
robfrank merged 4 commits into
mainfrom
fix/4456-bolt-follower-forwarding-no-user
Jun 2, 2026
Merged

fix(#4456): bind authenticated user on DatabaseContext in BoltNetworkExecutor#4457
robfrank merged 4 commits into
mainfrom
fix/4456-bolt-follower-forwarding-no-user

Conversation

@robfrank

@robfrank robfrank commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Closes #4456

Summary

  • BoltNetworkExecutor.ensureDatabase() never called DatabaseContext.INSTANCE.init().setCurrentUser() after resolving the database. On a Raft HA follower, RaftReplicatedDatabase.forwardCommandToLeaderViaRaft reads proxied.getCurrentUserName() to set the X-ArcadeDB-Forwarded-User header; because it was never bound, it returned null and threw SecurityException("Cannot forward command to leader: no authenticated user in the current security context"), surfaced to the client as Neo.DatabaseError.General.UnknownError.
  • One-line fix mirrors PostgresNetworkExecutor.openDatabase() (line 1509) and the prior gRPC fix: after server.getDatabase() succeeds, bind user.getDatabaseUser(database) onto the thread-local DatabaseContext.
  • Adds BoltFollowerForwardingIT: 3-node Raft cluster, Neo4j driver writes CREATE to a follower, asserts replication to all 3 nodes. Adds arcadedb-ha-raft test deps to bolt/pom.xml following the grpcw/pom.xml precedent.

Test plan

  • BoltFollowerForwardingIT (new, @Tag("slow")): 3-node cluster, write via follower succeeds and vertex count is 1 on every node
  • BoltProtocolIT (existing, 71 tests): all pass — concurrentSessions skipped (pre-existing failure on main)
  • BoltMultiLabelIT, BoltPortConfigIT (existing): pass
  • All 212 unit tests in BoltStructureTest, BoltMessageTest, BoltVersionNegotiationTest, BoltChunkedIOTest, PackStreamTest, PackStreamEdgeCasesTest, BoltExceptionTest, BoltSslHelperTest: pass
  • Compilation: mvn -pl bolt -am clean install -DskipTests succeeds

🤖 Generated with Claude Code

…Executor

BoltNetworkExecutor.ensureDatabase() resolved the database but never called
DatabaseContext.INSTANCE.init().setCurrentUser(), so follower-to-leader Raft
forwarding threw "no authenticated user in the current security context" for
every write that landed on a follower pod.

Fix mirrors PostgresNetworkExecutor.openDatabase() (line 1509) and the identical
gRPC fix: after server.getDatabase() succeeds, bind user.getDatabaseUser(database)
onto the thread-local DatabaseContext.

Regression test BoltFollowerForwardingIT: 3-node Raft cluster, Neo4j driver
writes to a follower, asserts the vertex replicates to all nodes.

Closes #4456
@codacy-production

codacy-production Bot commented Jun 2, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 5 complexity

Metric Results
Complexity 5

View in Codacy

🟢 Coverage 100.00% diff coverage · -7.74% coverage variation

Metric Results
Coverage variation -7.74% coverage variation
Diff coverage 100.00% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (cbf9008) 124318 92530 74.43%
Head commit (09336df) 156031 (+31713) 104051 (+11521) 66.69% (-7.74%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#4457) 7 7 100.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses an issue where Bolt protocol write queries fail on Raft HA followers by binding the authenticated user to the thread-local DatabaseContext in BoltNetworkExecutor.ensureDatabase(). It also adds a regression integration test and documentation. However, a critical security vulnerability was identified: during connection re-authentication (via LOGOFF/LOGON), ensureDatabase() returns early and fails to update the DatabaseContext with the new user's context, potentially leading to privilege escalation. It is recommended to ensure the context is properly updated or cleared upon re-authentication.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +971 to +972
if (user != null)
DatabaseContext.INSTANCE.init((DatabaseInternal) database).setCurrentUser(user.getDatabaseUser(database));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-critical critical

Critical Security Vulnerability: Security Context Mismatch on Re-authentication

While binding the authenticated user to the DatabaseContext in ensureDatabase() fixes the forwarding issue, it introduces a critical security vulnerability when a connection is re-authenticated.

Bolt 5.1+ supports LOGOFF and LOGON messages on the same connection (handled in handleLogoff() and handleLogon()). When a client logs off and logs on as a different user, the user field is updated to the new user. However, the next time ensureDatabase() is called, it returns early because database != null && database.isOpen() is true:

    if (database != null && database.isOpen()) {
      // Check if we need to switch to a different database
      ...
      } else {
        return true;
      }
    }

Because of this early return, the code at lines 971-972 is skipped, and the thread-local DatabaseContext is NOT updated with the new user's security context. Consequently, all subsequent operations/queries executed by the new user will run under the security context (and permissions) of the previously authenticated user, leading to privilege escalation or unauthorized data access.

Recommendation

To fix this, you should ensure that the DatabaseContext is updated with the new user even when ensureDatabase() returns early, or explicitly update/clear the DatabaseContext during handleLogon() and handleLogoff().

For example, you can modify the early return block in ensureDatabase() to update the current user on the existing context:

      } else {
        if (user != null) {
          final DatabaseContext.DatabaseContextTL context = DatabaseContext.INSTANCE.getContextIfExists(database.getDatabasePath());
          if (context != null) {
            context.setCurrentUser(user.getDatabaseUser(database));
          }
        }
        return true;
      }

Or, clear the current user in handleLogoff():

  private void handleLogoff() throws IOException {
    if (database != null) {
      final DatabaseContext.DatabaseContextTL context = DatabaseContext.INSTANCE.getContextIfExists(database.getDatabasePath());
      if (context != null) {
        context.setCurrentUser(null);
      }
    }
    user = null;
    sendSuccess(Map.of());
    state = State.AUTHENTICATION;
  }

@claude

claude Bot commented Jun 2, 2026

Copy link
Copy Markdown

Code Review - fix(#4456): bind authenticated user on DatabaseContext in BoltNetworkExecutor

Overview

This PR fixes a real bug: Bolt protocol write queries fail with Cannot forward command to leader: no authenticated user in the current security context when a connection lands on a Raft HA follower. The root cause is that BoltNetworkExecutor.ensureDatabase() resolved the database but never bound the authenticated user to the thread-local DatabaseContext, which is required when RaftReplicatedDatabase.forwardCommandToLeaderViaRaft reads getCurrentUserName() to build the forwarding header.


The Fix (BoltNetworkExecutor.java)

if (user != null)
    DatabaseContext.INSTANCE.init((DatabaseInternal) database).setCurrentUser(user.getDatabaseUser(database));

Correct and minimal. This exactly mirrors PostgresNetworkExecutor.openDatabase() line 1509 and the prior gRPC fix. Key observations:

  • The if (user != null) guard is appropriate - ensureDatabase() can be called before authentication completes in some paths and user is reset to null on RESET. Defensive and consistent with the rest of the file.
  • Placement is correct: the guard runs after database is confirmed non-null and open, so user.getDatabaseUser(database) is safe to call.
  • DatabaseContext is a thread-local, and ensureDatabase() is called on the connection thread before each RUN/BEGIN, so reinitializing it per-call is correct - especially since databaseName can change between RUN messages.

pom.xml

The arcadedb-ha-raft dependency is added correctly as scope: test only (both classes and test-jar). This follows the grpcw/pom.xml precedent and respects the wire protocol module dependency rules in CLAUDE.md (no compile-scope dependency on other modules, server stays provided).


BoltFollowerForwardingIT

The test structure is solid:

  • Correctly annotated @Tag("slow") per CLAUDE.md convention (notably GrpcFollowerForwardingIT - the existing reference test - is missing this tag).
  • @AfterEach teardown closes the driver.
  • Schema creation goes through the leader to isolate the forwarding logic.
  • waitForAllServers() called at the right points.
  • Uses assertThat(...) assertions as required by the style guide.
  • Port assignment: BASE_BOLT_PORT + serverIndex is consistent between onServerConfiguration and the client URL construction. Server names are ArcadeDB_0/1/2, so extracted index is 0/1/2 - the port math is correct.

One suggestion: The follower selection loop always picks the first non-leader server. This is fine, but a comment explaining that this is intentional (any follower is representative) would help future readers understand it isn't missing randomization by accident.


Potential Issues

Minor - docs/ markdown file: CLAUDE.md specifies not to create documentation files unless explicitly requested. The docs/4456-bolt-follower-forwarding-no-user.md file is useful context, but this policy is worth checking against the project's preferences. The same information already lives in the PR description and the test's Javadoc comment.

Follow-up scope - mongodbw and redisw: The PR body correctly identifies that both mongodbw and redisw have zero DatabaseContext.setCurrentUser references. This is worth filing as follow-up issues promptly, as the failure mode (silently broken HA follower writes) is the same and could affect users of those protocols.


Summary

The fix is correct, minimal, and well-tested. The test faithfully reproduces the failure scenario and validates the fix end-to-end on a real 3-node cluster. No concerns about correctness or performance. The only items worth addressing are the docs file (policy question) and filing the mongodbw/redisw follow-up issues.

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

📜 License Compliance Check

✅ License check passed. See artifacts for full report.

License Summary (first 50 lines)

Lists of 394 third-party dependencies.
     (Apache License 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.11.0 - https://github.com/yawkat/lz4-java)
     (EPL-2.0) (LGPL-2.1-only) Logback Classic Module (ch.qos.logback:logback-classic:1.5.33 - http://logback.qos.ch/logback-classic)
     (EPL-2.0) (LGPL-2.1-only) Logback Core Module (ch.qos.logback:logback-core:1.5.33 - http://logback.qos.ch/logback-core)
     (Apache 2) ArcadeDB BOLT Protocol (com.arcadedb:arcadedb-bolt:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-bolt/)
     (Apache 2) ArcadeDB Console (com.arcadedb:arcadedb-console:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-console/)
     (Apache 2) ArcadeDB Engine (com.arcadedb:arcadedb-engine:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-engine/)
     (Apache 2) ArcadeDB GraphQL (com.arcadedb:arcadedb-graphql:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-graphql/)
     (Apache 2) ArcadeDB Gremlin (com.arcadedb:arcadedb-gremlin:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-gremlin/)
     (Apache 2) ArcadeDB gRPC Stubs (com.arcadedb:arcadedb-grpc:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc/)
     (Apache 2) ArcadeDB gRPC Client (com.arcadedb:arcadedb-grpc-client:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc-client/)
     (Apache 2) ArcadeDB gRpcW (com.arcadedb:arcadedb-grpcw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpcw/)
     (Apache 2) ArcadeDB HA Raft (com.arcadedb:arcadedb-ha-raft:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-ha-raft/)
     (Apache 2) ArcadeDB Integration (com.arcadedb:arcadedb-integration:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-integration/)
     (Apache 2) ArcadeDB load tests (com.arcadedb:arcadedb-load-tests:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-load-tests/)
     (Apache 2) ArcadeDB Metrics (com.arcadedb:arcadedb-metrics:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-metrics/)
     (Apache 2) ArcadeDB MongoDB Wire Protocol (com.arcadedb:arcadedb-mongodbw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-mongodbw/)
     (Apache 2) ArcadeDB Network (com.arcadedb:arcadedb-network:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-network/)
     (Apache 2) ArcadeDB PostgresW (com.arcadedb:arcadedb-postgresw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-postgresw/)
     (Apache 2) ArcadeDB RedisW (com.arcadedb:arcadedb-redisw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-redisw/)
     (Apache 2) ArcadeDB Server (com.arcadedb:arcadedb-server:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-server/)
     (Apache 2) ArcadeDB Studio (com.arcadedb:arcadedb-studio:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-studio/)
     (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.7.1 - http://labs.carrotsearch.com/hppc.html/hppc)
     (Apache License 2.0) Metrics Core (com.codahale.metrics:metrics-core:3.0.2 - http://metrics.codahale.com/metrics-core/)
     (The Apache License, Version 2.0) com.conversantmedia:disruptor (com.conversantmedia:disruptor:1.2.21 - https://github.com/conversant/disruptor)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.20 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.1 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.4 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.1 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.4 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.1 - https://github.com/FasterXML/jackson-dataformats-text)
     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.1 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
     (The Apache Software License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.3.1 - https://github.com/ben-manes/caffeine)
     (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport-zerodep (com.github.docker-java:docker-java-transport-zerodep:3.7.1 - https://github.com/docker-java/docker-java)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
     (Apache License 2.0) (GNU Lesser General Public License) javaparser-core (com.github.javaparser:javaparser-core:3.26.3 - https://github.com/javaparser/javaparser-core)
     (Apache License 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
     (Apache License 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/)
     (BSD 3-Clause) API Common (com.google.api:api-common:2.53.0 - https://github.com/googleapis/sdk-platform-java)

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

📜 License Compliance Check

✅ License check passed. See artifacts for full report.

License Summary (first 50 lines)

Lists of 394 third-party dependencies.
     (Apache License 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.11.0 - https://github.com/yawkat/lz4-java)
     (EPL-2.0) (LGPL-2.1-only) Logback Classic Module (ch.qos.logback:logback-classic:1.5.33 - http://logback.qos.ch/logback-classic)
     (EPL-2.0) (LGPL-2.1-only) Logback Core Module (ch.qos.logback:logback-core:1.5.33 - http://logback.qos.ch/logback-core)
     (Apache 2) ArcadeDB BOLT Protocol (com.arcadedb:arcadedb-bolt:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-bolt/)
     (Apache 2) ArcadeDB Console (com.arcadedb:arcadedb-console:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-console/)
     (Apache 2) ArcadeDB Engine (com.arcadedb:arcadedb-engine:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-engine/)
     (Apache 2) ArcadeDB GraphQL (com.arcadedb:arcadedb-graphql:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-graphql/)
     (Apache 2) ArcadeDB Gremlin (com.arcadedb:arcadedb-gremlin:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-gremlin/)
     (Apache 2) ArcadeDB gRPC Stubs (com.arcadedb:arcadedb-grpc:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc/)
     (Apache 2) ArcadeDB gRPC Client (com.arcadedb:arcadedb-grpc-client:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc-client/)
     (Apache 2) ArcadeDB gRpcW (com.arcadedb:arcadedb-grpcw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpcw/)
     (Apache 2) ArcadeDB HA Raft (com.arcadedb:arcadedb-ha-raft:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-ha-raft/)
     (Apache 2) ArcadeDB Integration (com.arcadedb:arcadedb-integration:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-integration/)
     (Apache 2) ArcadeDB load tests (com.arcadedb:arcadedb-load-tests:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-load-tests/)
     (Apache 2) ArcadeDB Metrics (com.arcadedb:arcadedb-metrics:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-metrics/)
     (Apache 2) ArcadeDB MongoDB Wire Protocol (com.arcadedb:arcadedb-mongodbw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-mongodbw/)
     (Apache 2) ArcadeDB Network (com.arcadedb:arcadedb-network:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-network/)
     (Apache 2) ArcadeDB PostgresW (com.arcadedb:arcadedb-postgresw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-postgresw/)
     (Apache 2) ArcadeDB RedisW (com.arcadedb:arcadedb-redisw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-redisw/)
     (Apache 2) ArcadeDB Server (com.arcadedb:arcadedb-server:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-server/)
     (Apache 2) ArcadeDB Studio (com.arcadedb:arcadedb-studio:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-studio/)
     (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.7.1 - http://labs.carrotsearch.com/hppc.html/hppc)
     (Apache License 2.0) Metrics Core (com.codahale.metrics:metrics-core:3.0.2 - http://metrics.codahale.com/metrics-core/)
     (The Apache License, Version 2.0) com.conversantmedia:disruptor (com.conversantmedia:disruptor:1.2.21 - https://github.com/conversant/disruptor)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.20 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.1 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.4 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.1 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.4 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.1 - https://github.com/FasterXML/jackson-dataformats-text)
     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.1 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
     (The Apache Software License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.3.1 - https://github.com/ben-manes/caffeine)
     (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport-zerodep (com.github.docker-java:docker-java-transport-zerodep:3.7.1 - https://github.com/docker-java/docker-java)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
     (Apache License 2.0) (GNU Lesser General Public License) javaparser-core (com.github.javaparser:javaparser-core:3.26.3 - https://github.com/javaparser/javaparser-core)
     (Apache License 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
     (Apache License 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/)
     (BSD 3-Clause) API Common (com.google.api:api-common:2.53.0 - https://github.com/googleapis/sdk-platform-java)

@claude

claude Bot commented Jun 2, 2026

Copy link
Copy Markdown

Code Review - fix(#4456): bind authenticated user on DatabaseContext in BoltNetworkExecutor

Summary

This PR fixes a real and impactful bug: Bolt write queries fail with Cannot forward command to leader: no authenticated user in the current security context when a connection lands on a Raft HA follower. The root cause - BoltNetworkExecutor.ensureDatabase() never binding the authenticated user to the thread-local DatabaseContext - is correctly identified and fixed.


Core Fix (BoltNetworkExecutor.java:979-980)

if (user != null)
    DatabaseContext.INSTANCE.init((DatabaseInternal) database).setCurrentUser(user.getDatabaseUser(database));

Correct and minimal. Mirrors PostgresNetworkExecutor.openDatabase() line 1509 and the prior gRPC fix. The if (user != null) guard is appropriate since user is cleared on RESET (line 448) and ensureDatabase() can be called before authentication completes.


Early-Return Re-Authentication Fix (BoltNetworkExecutor.java:944-949)

if (user != null) {
    final DatabaseContext.DatabaseContextTL ctx =
        DatabaseContext.INSTANCE.getContextIfExists(((DatabaseInternal) database).getDatabasePath());
    if (ctx != null)
        ctx.setCurrentUser(user.getDatabaseUser(database));
}

This correctly addresses the Gemini-flagged privilege-escalation scenario (LOGOFF/LOGON re-authentication on the same connection). Using getContextIfExists() instead of init() is the right choice - init() would roll back any open transactions (see DatabaseContext.java:64-74).

One minor robustness note: if ctx happens to be null in the early-return path (e.g., if removeAllContexts() raced between requests), the user update is silently skipped. This is practically unreachable in normal operation, since init() was called on the previous ensureDatabase() invocation and no code in BoltNetworkExecutor calls removeContext(). The silent skip is acceptable, but a comment explaining why ctx != null is expected (rather than just defensive coding) would help future readers.


pom.xml

arcadedb-ha-raft is correctly added as scope: test (both classes and test-jar), following the grpcw/pom.xml precedent. No compile-scope pollution, consistent with the wire protocol module rules in CLAUDE.md.


BoltFollowerForwardingIT

Well-structured regression test:

  • @Tag("slow") annotation is present and correct per CLAUDE.md convention.
  • @AfterEach teardown closes the Neo4j driver.
  • Schema is created through the leader to isolate the Bolt forwarding path under test.
  • waitForAllServers() called correctly before and after the write.
  • AssertJ assertions used throughout, matching the style guide.
  • Port assignment (BASE_BOLT_PORT + serverIndex = 57687/57688/57689) is consistent between onServerConfiguration and the client URL.

One small point: GrpcFollowerForwardingIT (the analogous test in grpcw) is missing @Tag("slow"). That's a pre-existing inconsistency, not introduced here, but worth a follow-up.


mongodbw and redisw

Confirmed: both modules have zero DatabaseContext/setCurrentUser references. The note in the docs file that they may be affected by the same class of bug is accurate. Follow-up issues are the right approach here - keeping this PR focused on the Bolt fix is correct scoping.


docs/4456-bolt-follower-forwarding-no-user.md

Consistent with the existing pattern in docs/ (other numbered fix notes like 4367-lockmanager-trylock-putifabsent-retry.md). No objection.


Verdict

The fix is correct, targeted, and safe. The re-authentication case is handled without transaction disruption. The test provides solid regression coverage. No blocking issues.

Approved.

🤖 Generated with Claude Code

@claude

claude Bot commented Jun 2, 2026

Copy link
Copy Markdown

Code Review - Cycle 2

This is the second review cycle. The Cycle 1 security concern (LOGOFF/LOGON privilege escalation) was correctly addressed. Here is the full review of the current state.


Core fix (new-database path) - Correct

Minimal, correct, and mirrors PostgresNetworkExecutor line 1509 and the gRPC fix exactly. Placement after database is confirmed non-null and open ensures user.getDatabaseUser(database) is safe to call.


Cycle 2 fix (early-return path) - Correct

Using getContextIfExists() rather than init() in the early-return path is the right call. init() rolls back any open transactions when a context already exists (DatabaseContext.java lines 64-74), so reinitializing would break in-flight transactions on re-auth. The getContextIfExists() + setCurrentUser() approach correctly updates the bound identity without touching the transaction stack.


Minor observation: silent gap when ctx == null in the early-return path

When database != null && database.isOpen() but getContextIfExists() returns null, the user is not bound and we silently return true. This occurs only if the context was cleared (via removeAllContexts()) while the database handle is still open - in practice only during database close, guarded by isOpen(). The risk is minimal, but a follower forwarding attempt in that narrow window would still throw the original SecurityException.

A defensive fallback when ctx == null would call init() instead, creating a fresh context. Low-priority nit - the current code is safe in all normal flows.


pom.xml - Correct

arcadedb-ha-raft added as scope: test only (both jar and test-jar). Follows grpcw/pom.xml precedent and satisfies the CLAUDE.md wire protocol module dependency rules.


BoltFollowerForwardingIT - Good

  • @Tag("slow") at class level is correct per CLAUDE.md.
  • Schema creation goes through the leader deliberately - isolates forwarding logic from schema replication noise.
  • waitForAllServers() called after the write before asserting on all nodes.
  • Port assignment (BASE_BOLT_PORT + serverIndex) is consistent between onServerConfiguration and the driver URL.
  • @AfterEach closes the driver correctly - no resource leak.

One minor point: the follower-selection loop always picks the first non-leader index. This is fine (any follower is equally representative), but a short comment would help future readers understand the omission of randomization is intentional.


docs/4456-bolt-follower-forwarding-no-user.md

Per CLAUDE.md, documentation files should not be created unless explicitly requested. The content is already covered by the PR description and the test Javadoc. Worth removing unless this project has a convention for per-issue design docs in docs/.


Follow-up: mongodbw and redisw

The PR body correctly identifies that both modules have zero DatabaseContext.setCurrentUser references. Filing follow-up issues promptly would help track them before they surface the same way in production.


Summary

The fix is correct and the Cycle 1 security concern is properly addressed. The only actionable items are: (1) the defensive ctx == null fallback in the early-return path (low priority), (2) the docs markdown file (policy question), and (3) filing mongodbw/redisw follow-up issues. The core logic and test are ready to merge.

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

📜 License Compliance Check

✅ License check passed. See artifacts for full report.

License Summary (first 50 lines)

Lists of 394 third-party dependencies.
     (Apache License 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.11.0 - https://github.com/yawkat/lz4-java)
     (EPL-2.0) (LGPL-2.1-only) Logback Classic Module (ch.qos.logback:logback-classic:1.5.33 - http://logback.qos.ch/logback-classic)
     (EPL-2.0) (LGPL-2.1-only) Logback Core Module (ch.qos.logback:logback-core:1.5.33 - http://logback.qos.ch/logback-core)
     (Apache 2) ArcadeDB BOLT Protocol (com.arcadedb:arcadedb-bolt:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-bolt/)
     (Apache 2) ArcadeDB Console (com.arcadedb:arcadedb-console:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-console/)
     (Apache 2) ArcadeDB Engine (com.arcadedb:arcadedb-engine:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-engine/)
     (Apache 2) ArcadeDB GraphQL (com.arcadedb:arcadedb-graphql:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-graphql/)
     (Apache 2) ArcadeDB Gremlin (com.arcadedb:arcadedb-gremlin:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-gremlin/)
     (Apache 2) ArcadeDB gRPC Stubs (com.arcadedb:arcadedb-grpc:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc/)
     (Apache 2) ArcadeDB gRPC Client (com.arcadedb:arcadedb-grpc-client:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc-client/)
     (Apache 2) ArcadeDB gRpcW (com.arcadedb:arcadedb-grpcw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpcw/)
     (Apache 2) ArcadeDB HA Raft (com.arcadedb:arcadedb-ha-raft:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-ha-raft/)
     (Apache 2) ArcadeDB Integration (com.arcadedb:arcadedb-integration:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-integration/)
     (Apache 2) ArcadeDB load tests (com.arcadedb:arcadedb-load-tests:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-load-tests/)
     (Apache 2) ArcadeDB Metrics (com.arcadedb:arcadedb-metrics:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-metrics/)
     (Apache 2) ArcadeDB MongoDB Wire Protocol (com.arcadedb:arcadedb-mongodbw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-mongodbw/)
     (Apache 2) ArcadeDB Network (com.arcadedb:arcadedb-network:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-network/)
     (Apache 2) ArcadeDB PostgresW (com.arcadedb:arcadedb-postgresw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-postgresw/)
     (Apache 2) ArcadeDB RedisW (com.arcadedb:arcadedb-redisw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-redisw/)
     (Apache 2) ArcadeDB Server (com.arcadedb:arcadedb-server:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-server/)
     (Apache 2) ArcadeDB Studio (com.arcadedb:arcadedb-studio:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-studio/)
     (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.7.1 - http://labs.carrotsearch.com/hppc.html/hppc)
     (Apache License 2.0) Metrics Core (com.codahale.metrics:metrics-core:3.0.2 - http://metrics.codahale.com/metrics-core/)
     (The Apache License, Version 2.0) com.conversantmedia:disruptor (com.conversantmedia:disruptor:1.2.21 - https://github.com/conversant/disruptor)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.20 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.1 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.4 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.1 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.4 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.1 - https://github.com/FasterXML/jackson-dataformats-text)
     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.1 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
     (The Apache Software License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.3.1 - https://github.com/ben-manes/caffeine)
     (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport-zerodep (com.github.docker-java:docker-java-transport-zerodep:3.7.1 - https://github.com/docker-java/docker-java)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
     (Apache License 2.0) (GNU Lesser General Public License) javaparser-core (com.github.javaparser:javaparser-core:3.26.3 - https://github.com/javaparser/javaparser-core)
     (Apache License 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
     (Apache License 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/)
     (BSD 3-Clause) API Common (com.google.api:api-common:2.53.0 - https://github.com/googleapis/sdk-platform-java)

@claude

claude Bot commented Jun 2, 2026

Copy link
Copy Markdown

Code Review - fix(#4456): bind authenticated user on DatabaseContext in BoltNetworkExecutor

Overview

This PR fixes a real bug: BoltNetworkExecutor.ensureDatabase() opened the database but never bound the authenticated user onto the thread-local DatabaseContext, so RaftReplicatedDatabase.forwardCommandToLeaderViaRaft found a null user and threw a SecurityException. The fix correctly mirrors the PostgreSQL and gRPC wire-protocol precedents.


Correctness

Core fix (new-database path, line 979-980) - correct. Using DatabaseContext.INSTANCE.init() is the right call when first opening the database for a connection.

Early-return path fix (lines 942-949) - mostly correct, but has a subtle gap:

final DatabaseContext.DatabaseContextTL ctx =
    DatabaseContext.INSTANCE.getContextIfExists(((DatabaseInternal) database).getDatabasePath());
if (ctx != null)
    ctx.setCurrentUser(user.getDatabaseUser(database));

The use of getContextIfExists() instead of init() here is intentional and documented - init() rolls back any open transactions (lines 64-75 in DatabaseContext.java), which would be wrong on an already-open connection. However, if ctx == null (thread-local cleaned up between requests, possible in long-lived connections), the user never gets set and follower forwarding still fails silently. A more robust approach would fall back to init() in that case:

if (user != null) {
    final DatabaseContext.DatabaseContextTL ctx =
        DatabaseContext.INSTANCE.getContextIfExists(((DatabaseInternal) database).getDatabasePath());
    if (ctx != null)
        ctx.setCurrentUser(user.getDatabaseUser(database));
    else
        DatabaseContext.INSTANCE.init((DatabaseInternal) database).setCurrentUser(user.getDatabaseUser(database));
}

Since ctx == null implies no open transactions, calling init() there is safe.


Code Style

Comment length - CLAUDE.md specifies: "Don't write multi-line comment blocks - one short line max." The comment at line 942-943 spans two lines. The WHY is genuinely non-obvious here (using getContextIfExists instead of init to not disturb open transactions), so a comment is warranted, but it should fit in one line, e.g.:

// getContextIfExists avoids init() which would rollback open transactions

user == null guard

Both fix sites guard with if (user != null). If user can be null when ensureDatabase() is called, the DatabaseContext remains without a user and follower forwarding would still fail. Is there a code path where ensureDatabase() is called before the user has been authenticated? If so, the unauthenticated call probably should not reach the database at all, and the guard should be tightened upstream. If user is always non-null by the time ensureDatabase() is called, the null guard is dead code. Either way, clarifying this would help future readers.


Documentation File

docs/4456-bolt-follower-forwarding-no-user.md is well-written but the Review Cycles section (Cycle 1, Cycle 2 history, SHA references) is a development/tracking artifact that belongs in the PR description, not in the repository. Once merged, that section is stale and misleading. Consider stripping the Review Cycles section before merging - the rest of the document (Issue, Root Cause, Fix, Test Plan) is genuinely useful.


Test Coverage

BoltFollowerForwardingIT is a good regression test:

  • Correctly uses @Tag("slow") per project convention
  • Tests exactly the failure mode described in the issue (write via Bolt to a follower in a 3-node cluster)
  • Verifies replication to all nodes via countType
  • Follows the BaseRaftHATest pattern used by the equivalent gRPC test

One minor concern: BASE_BOLT_PORT = 57687 is hardcoded. If two test suites run concurrently on the same machine and both pick this port, the test will be flaky. Using 0 (OS-assigned) or a dynamic port discovery mechanism would be more robust, if the test infrastructure supports it.


mongodbw / redisw

The PR description notes these protocols likely have the same bug. Filing follow-up issues is the right call, just making sure they are tracked.


POM Changes

The arcadedb-ha-raft test dependency additions follow the grpcw/pom.xml precedent and use correct test scope. No issues here.


Summary

Area Verdict
Core fix (new-database path) Correct
Early-return fix (ctx == null gap) Minor issue - silent failure if context was cleaned up
Comment style Violates one-line max from CLAUDE.md
Docs file review history Should be stripped before merge
Test Good coverage, minor port hardcoding concern
POM Clean

The fix addresses the root cause correctly. The two items worth addressing before merge are the ctx == null silent gap in the early-return path and stripping the Review Cycles section from the docs file.

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

📜 License Compliance Check

✅ License check passed. See artifacts for full report.

License Summary (first 50 lines)

Lists of 394 third-party dependencies.
     (Apache License 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.11.0 - https://github.com/yawkat/lz4-java)
     (EPL-2.0) (LGPL-2.1-only) Logback Classic Module (ch.qos.logback:logback-classic:1.5.33 - http://logback.qos.ch/logback-classic)
     (EPL-2.0) (LGPL-2.1-only) Logback Core Module (ch.qos.logback:logback-core:1.5.33 - http://logback.qos.ch/logback-core)
     (Apache 2) ArcadeDB BOLT Protocol (com.arcadedb:arcadedb-bolt:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-bolt/)
     (Apache 2) ArcadeDB Console (com.arcadedb:arcadedb-console:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-console/)
     (Apache 2) ArcadeDB Engine (com.arcadedb:arcadedb-engine:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-engine/)
     (Apache 2) ArcadeDB GraphQL (com.arcadedb:arcadedb-graphql:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-graphql/)
     (Apache 2) ArcadeDB Gremlin (com.arcadedb:arcadedb-gremlin:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-gremlin/)
     (Apache 2) ArcadeDB gRPC Stubs (com.arcadedb:arcadedb-grpc:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc/)
     (Apache 2) ArcadeDB gRPC Client (com.arcadedb:arcadedb-grpc-client:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpc-client/)
     (Apache 2) ArcadeDB gRpcW (com.arcadedb:arcadedb-grpcw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-grpcw/)
     (Apache 2) ArcadeDB HA Raft (com.arcadedb:arcadedb-ha-raft:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-ha-raft/)
     (Apache 2) ArcadeDB Integration (com.arcadedb:arcadedb-integration:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-integration/)
     (Apache 2) ArcadeDB load tests (com.arcadedb:arcadedb-load-tests:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-load-tests/)
     (Apache 2) ArcadeDB Metrics (com.arcadedb:arcadedb-metrics:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-metrics/)
     (Apache 2) ArcadeDB MongoDB Wire Protocol (com.arcadedb:arcadedb-mongodbw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-mongodbw/)
     (Apache 2) ArcadeDB Network (com.arcadedb:arcadedb-network:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-network/)
     (Apache 2) ArcadeDB PostgresW (com.arcadedb:arcadedb-postgresw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-postgresw/)
     (Apache 2) ArcadeDB RedisW (com.arcadedb:arcadedb-redisw:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-redisw/)
     (Apache 2) ArcadeDB Server (com.arcadedb:arcadedb-server:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-server/)
     (Apache 2) ArcadeDB Studio (com.arcadedb:arcadedb-studio:26.6.1-SNAPSHOT - https://arcadedata.com/arcadedb-studio/)
     (The Apache Software License, Version 2.0) HPPC Collections (com.carrotsearch:hppc:0.7.1 - http://labs.carrotsearch.com/hppc.html/hppc)
     (Apache License 2.0) Metrics Core (com.codahale.metrics:metrics-core:3.0.2 - http://metrics.codahale.com/metrics-core/)
     (The Apache License, Version 2.0) com.conversantmedia:disruptor (com.conversantmedia:disruptor:1.2.21 - https://github.com/conversant/disruptor)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.20 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.1 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.4 - https://github.com/FasterXML/jackson-core)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.1 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.4 - https://github.com/FasterXML/jackson)
     (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.1 - https://github.com/FasterXML/jackson-dataformats-text)
     (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.1 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
     (The Apache Software License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:2.3.1 - https://github.com/ben-manes/caffeine)
     (The Apache Software License, Version 2.0) docker-java-api (com.github.docker-java:docker-java-api:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport (com.github.docker-java:docker-java-transport:3.7.1 - https://github.com/docker-java/docker-java)
     (The Apache Software License, Version 2.0) docker-java-transport-zerodep (com.github.docker-java:docker-java-transport-zerodep:3.7.1 - https://github.com/docker-java/docker-java)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) jackson-coreutils-equivalence (com.github.java-json-tools:jackson-coreutils-equivalence:1.0 - https://github.com/java-json-tools/jackson-coreutils)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-core (com.github.java-json-tools:json-schema-core:1.2.14 - https://github.com/java-json-tools/json-schema-core)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) json-schema-validator (com.github.java-json-tools:json-schema-validator:2.2.14 - https://github.com/java-json-tools/json-schema-validator)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple)
     (Apache Software License, version 2.0) (Lesser General Public License, version 3 or greater) uri-template (com.github.java-json-tools:uri-template:0.10 - https://github.com/java-json-tools/uri-template)
     (Apache License 2.0) (GNU Lesser General Public License) javaparser-core (com.github.javaparser:javaparser-core:3.26.3 - https://github.com/javaparser/javaparser-core)
     (Apache License 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations)
     (Apache License 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/)
     (BSD 3-Clause) API Common (com.google.api:api-common:2.53.0 - https://github.com/googleapis/sdk-platform-java)

@codecov

codecov Bot commented Jun 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 57.14286% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.26%. Comparing base (cbf9008) to head (09336df).

Files with missing lines Patch % Lines
...in/java/com/arcadedb/bolt/BoltNetworkExecutor.java 57.14% 0 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4457      +/-   ##
==========================================
+ Coverage   65.24%   65.26%   +0.02%     
==========================================
  Files        1612     1612              
  Lines      124318   124325       +7     
  Branches    26910    26913       +3     
==========================================
+ Hits        81111    81145      +34     
+ Misses      31816    31785      -31     
- Partials    11391    11395       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@robfrank robfrank merged commit bbfbc5e into main Jun 2, 2026
27 of 31 checks passed
@robfrank robfrank deleted the fix/4456-bolt-follower-forwarding-no-user branch June 2, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bolt protocol: writes to a follower in Raft HA fail with "Cannot forward command to leader: no authenticated user in the current security context"

1 participant