jsantana avatar image
jsantana asked jsantana commented

Reload User and Password in runtime in Java Driver version 3.x

I am running a Java app with DataStax Java driver version 3.3.0 and I am trying to change Cassandra user and password at runtime. According to this issue by calling setUser and setPassword in this object it should reuse it for future calls to the DB, so I did in my code something like

PlainTextAuthProvider authProvider = (PlainTextAuthProvider) cluster.getConfiguration().getProtocolOptions().getAuthProvider();


But even after this change I find that it still use the user/pass I set on startup.

This docu indicates that in versions > 4.x you can force a config reload at runtime.

So my question is, Is there a way to force all new calls to Cassandra start using the new User and Pass provided via PlainTextAuthProvider in version 3.x ?

Extra: I am doing this to try to rotate Vault passwords when they expire and update the driver accordingly. Something like what is described in this post for relational DB accessed by Spring Boot but on Cassandra

java driver
10 |1000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Erick Ramirez avatar image
Erick Ramirez answered Erick Ramirez commented

I'm not familiar with this API but I think the credentials are used just for new connections initiated after the credentials are set. I suspect it doesn't apply to existing connections which continue to use the old credentials.

I'm going to reach out to the Driver devs here at DataStax and will either get them to respond directly or I will update my answer. Cheers!

2 comments Share
10 |1000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jsantana avatar image jsantana commented ·

Thanks for responding so quickly Erick.

Yes, the updated credentials seems to be only for new connections, so one possible solution for my problem would be to drain all existing connections and force all to be new. Take into account that Hashicorp Vault will invalidate previous password, so keeping existing connections is not an option.

Don't know if this is possible in this version, but hope this facts clarify the problem even more.

0 Likes 0 ·
Erick Ramirez avatar image Erick Ramirez ♦♦ jsantana commented ·
I did suspect you were using some vault solution and rotating credentials. I'll pass it on to the devs here and will let you know. Cheers!
0 Likes 0 ·
alexandre.dutra avatar image
alexandre.dutra answered jsantana commented

First, I am surprised that calling authProvider.setUsername(user) and authProvider.setPassword(pwd) is not working. It should. If you are confident that this is not working, please file a Jira bug here:

Secondly, even if driver 4.x does have the ability to reload the config at runtime, in fact not all the config options are hot-reloadable, and the authentication credentials unfortunately are among those (see here). As a consequence, there is no built-in way to hot-reload the credentials in driver 4.x. Of course you can write your own auth provider, it's trivial – but I filed JAVA-2953 to add the missing feature.

And lastly, I think the most difficult problem to solve, as Erik pointed out, is that credentials are used when new connections are opened, and the driver uses the same credentials for every node. How are you rotating your credentials in Cassandra? I suspect that you would need to first update the driver with the new credentials, then proceed with a rolling restart of the Cassandra nodes, and as nodes restart, connections will be closed then re-opened with new credentials. But if in this process a connection is opened to a node that still has the old credentials, the connection will fail. To avoid that, you would have to write an AuthProvider that is capable of returning different credentials per endpoint.

1 comment Share
10 |1000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jsantana avatar image jsantana commented ·

Hi Alexandre, thanks for your response and I am sorry for my delayed one. I checked many times and I am confident that is not working, however before filing the bug I think I should describe my scenario since a bit different to the one you mention and maybe I am misunderstanding they way this should be used.

  1. Driver connects using user/password 1 provided by Hashicorp Vault
  2. Vault detects that user/password 1 are about to expire (according to its lease policy) and n seconds ahead request a new one user/password 2 (Create USER with Pass...)
  3. Vault send new credentials to Driver that updates them using setUsername and setPassword
  4. Vault Revokes previous all privileges from previous user DB (REVOKE USER)

No restart of DB is involved. After this, on the first use. I see an error indicating that user/password 1 doesn't have privileges to access table X. This lead me to think that some connections remain with all data which is not valid anymore in DB. Is this the way it was supposed to work?

0 Likes 0 ·