Skip to content

dbeaver/cloudbeaver#4564 change db user password - #4586

Open
TobyTheHutt wants to merge 1 commit into
dbeaver:develfrom
TobyTheHutt:feature/issue-4564-db-user-password-change
Open

dbeaver/cloudbeaver#4564 change db user password#4586
TobyTheHutt wants to merge 1 commit into
dbeaver:develfrom
TobyTheHutt:feature/issue-4564-db-user-password-change

Conversation

@TobyTheHutt

Copy link
Copy Markdown

Summary

Relates to #4564

Adds a Security > Change database password context-menu action on connections. The action opens a modal dialog and calls a new GraphQL mutation that invokes the DBeaver core DBAUserPasswordManager adapter of the connected driver.

Design

  • Server flag dbUserPasswordChangeEnabled gates the mutation server-wide. Default is false. Persistence goes through CBAppConfig, AdminServerConfig, CBServerConfigurationController, CBServerConfigurationMapper, and WebServerConfig. Admin toggle lives in Configuration Wizard > Security.
  • Mutation changeConnectionUserPassword(projectId: ID, connectionId: ID!, oldPassword: String!, newPassword: String!): Boolean!. Guard: @WebProjectAction(requireProjectPermissions = {PERMISSION_PROJECT_DATASOURCES_EDIT}). Both password parameters carry @WebParameterSecure to keep them out of logs.
  • On DB rejection the mutation raises DBWebException wrapping the driver's exception. Callers receive the original SQL state, message, and cause chain.
  • Frontend menu appears when the server flag is on and connection.canEdit is true. Backend re-checks the project permission on every call.
  • Audit events fire on the cb_security_audit topic with kinds ATTEMPTED, SUCCEEDED, FAILED, and GATE_REJECTED. Payload carries sessionId, userId, projectId, connectionId, driverId, kind, reasonCode, errorClass. No plaintext passwords.

Screenshots:

Details

PW-Reset Flag:

Screenshot 2026-08-21 102959

PW-Change navigation:

Screenshot 2026-08-21 103043

PW-Change dialog:

Screenshot 2026-08-21 103120

PW-Change confirmation:
Screenshot 2026-08-21 103136

Engine coverage

Dispatch runs through the DBeaver core DBAUserPasswordManager adapter. Verified against Oracle 21c XE, PostgreSQL 16, and SQL Server 2022. Engines whose driver ships an adapter (Greenplum, CockroachDB, Exasol, Vertica) inherit support without further code changes. Drivers without an adapter (H2, MySQL) return GATE_REJECTED reasonCode=DIALECT_UNSUPPORTED in the audit trail and This driver does not support password change from CloudBeaver. in the notification.

Out of scope

  • Expired-password login variant (Oracle ORA-28001, MySQL 1820, SQL Server 18488).
  • MySQL adapter (upstream DBeaver contribution).
  • Locale translations beyond English.

Test plan

  • Admin toggles Enable database user password change in Configuration Wizard or Server Administration > Security.
  • With flag on: right-click a configured and logged-on PostgreSQL/Oracle/MSSQL connection > Security > Change database password. Submit oldpw, newpw, newpw. Reconnect with newpw succeeds. Reconnect with oldpw returns SQLSTATE 28P01 or technology equivalent.
  • With flag off: the Security submenu is absent.
  • Non-admin user without datasources-edit on the project sees no menu. Direct GraphQL mutation returns a permission-denied response.
  • Wrong-old-password on Oracle: notification body contains ORA-28008: invalid old password. On SQL Server: Msg 15116.
  • H2 connection: notification This driver does not support password change from CloudBeaver.. Audit line kind=GATE_REJECTED reasonCode=DIALECT_UNSUPPORTED.
  • docker logs cloudbeaver-dev | grep cb_security_audit shows one ATTEMPTED + one SUCCEEDED per successful change, ATTEMPTED + FAILED with errorClass on driver rejection, and no plaintext passwords.

Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 14 complexity · 0 duplication

Metric Results
Complexity 14
Duplication 0

View in Codacy

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.

@TobyTheHutt TobyTheHutt changed the title #4564 change db user password dbeaver/cloudbeaver#4564 change db user password Aug 21, 2026
@LonwoLonwo LonwoLonwo added the external For external PRs label Aug 24, 2026
@LonwoLonwo
LonwoLonwo requested a balanced review from Copilot August 24, 2026 07:52
@LonwoLonwo

Copy link
Copy Markdown
Member

Hello @TobyTheHutt

Thanks for the contribution.
We will take a look and get back to you with the answer and comments soon.

Copilot AI 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.

Pull request overview

Adds database-user password changes for editable connections, gated by server configuration.

Changes:

  • Adds the connection security menu and password dialog.
  • Adds the GraphQL mutation, driver-adapter dispatch, persistence, and audit events.
  • Adds an administrator-controlled feature flag.

Reviewed changes

Copilot reviewed 26 out of 28 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
webapp/yarn.lock Updates a local package checksum.
webapp/packages/plugin-connections/src/locales/en.ts Adds password-dialog strings.
webapp/packages/plugin-connections/src/ContextMenu/MENU_CONNECTION_SECURITY.ts Defines the Security submenu.
webapp/packages/plugin-connections/src/ContextMenu/ConnectionMenuBootstrap.ts Registers the menu action and dialog.
webapp/packages/plugin-connections/src/ContextMenu/ChangeDatabasePasswordDialog/ChangeDatabasePasswordDialog.tsx Implements the password form and mutation call.
webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_CHANGE_DB_PASSWORD.ts Defines the password-change action.
webapp/packages/plugin-administration/src/locales/en.ts Adds administration labels.
webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/ServerConfigurationFormPart.ts Loads the feature flag state.
webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/IServerConfigurationFormPartState.ts Extends configuration validation.
webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/Form/ServerConfigurationSecurityForm.tsx Adds the security toggle.
webapp/packages/core-sdk/src/queries/fragments/ServerConfig/ServerConfig.gql Queries the feature flag.
webapp/packages/core-sdk/src/queries/connections/changeConnectionUserPassword.gql Defines the client mutation.
webapp/packages/core-root/src/ServerConfigResource.ts Exposes the feature flag.
server/bundles/io.cloudbeaver.service.admin/schema/service.admin.graphqls Extends admin configuration input.
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java Binds the mutation resolver.
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java Implements password changes and auditing.
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/DBWServiceCore.java Declares the secured service method.
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSSecurityAuditEventHandler.java Logs audit events.
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSSecurityAuditEvent.java Defines audit payloads.
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebServerConfig.java Publishes the feature flag.
server/bundles/io.cloudbeaver.server/schema/service.core.graphqls Adds the flag and mutation schema.
server/bundles/io.cloudbeaver.server/plugin.xml Registers the audit handler.
server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBServerConfigurationMapper.java Maps the flag into application configuration.
server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBServerConfigurationController.java Persists the flag.
server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/model/config/AdminServerConfig.java Models the admin flag.
server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionInfo.java Removes trailing whitespace.
server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/CBAppConfig.java Stores the feature flag.
server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/WebAppConfiguration.java Adds the configuration interface default.
Suppressed comments (1)

server/bundles/io.cloudbeaver.server/schema/service.core.graphqls:918

  • This new public mutation is missing the required @since directive.
    ): Boolean!

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@NotNull Map<String, Object> connectionConfig
) throws DBWebException;

@WebProjectAction(requireProjectPermissions = {RMConstants.PERMISSION_PROJECT_DATASOURCES_EDIT})

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes it does contradict the issue. I started implementing the shape and realized that it doesn't make sense to have a per-team pw-reset block if the user can just proceed to change their password through an SQL prompt. Reasons to block PW-Resets are for shared-connections which use service accounts (when the user doesn't have edit permission on the connection object), or when an external authentication mechanism like RADIUS or OIDC are in-use.

If the user has permission to run statements, they usually have permission to change their passwords on the DB technologies known to me.

The only narrow use-case in which this change would expose an undesired credential change is, if the database was set up with PERMISSION_PROJECT_DATASOURCES_EDIT or an analogue setting, while having no SQL execution rights. This would allow the user to change the password through the GUI while they couldn't through an SQL worksheet. However, this is extremely specific and the only rationale I could think of to have per-team PW-update settings.

I did generally not treat the issue as a hard policy or contract and deviated for these reasons. But I can change it, if that's desired.

) throws DBWebException {
DBPDataSourceContainer container = null;
try {
requireServerFlagEnabled(webSession, projectId, connectionId);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This is identical to the old @WebAction shape and not something I introduced. I can fix this with my PR, if that's desired. Framework-level permission denials appear in the server request log.

Comment on lines +816 to +819
String userName = container.getConnectionConfiguration().getUserName();
if (!CommonUtils.isEmpty(userName)) {
return userName;
}
Comment on lines +856 to +858
container.getConnectionConfiguration().setUserPassword(newPassword);
container.getActualConnectionConfiguration().setUserPassword(newPassword);
persisted = container.isTemporary() || container.persistConfiguration();
Comment on lines +758 to +764
if (newPassword.length() > MAX_PASSWORD_LENGTH) {
emitPasswordChangeAudit(webSession, container, projectId, connectionId,
WSSecurityAuditEvent.Kind.GATE_REJECTED, "PASSWORD_TOO_LONG", null);
throw new DBWebException(
"Password exceeds the maximum length of " + MAX_PASSWORD_LENGTH + " characters.");
}
if (containsBlockedPasswordChar(newPassword)) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

PasswordPolicyConfig governs CloudBeaver user account passwords, not DB user passwords. DB user password policy is the DB's concern. In this PR, I surface DB policy rejections verbatim via DBWebException. Applying the CB policy here would enforce the wrong layer.

Comment on lines +700 to +702
applyPasswordChange(webSession, container, projectId, connectionId, manager, userName, oldPassword, newPassword);
persistNewPassword(webSession, container, projectId, connectionId, newPassword);
safeDisconnect(webSession, container);
adminCredentialsSaveEnabled: Boolean!

"Defines if the change-DB-password mutation is enabled server-wide"
dbUserPasswordChangeEnabled: Boolean!
"Whether saving credentials is allowed"
adminCredentialsSaveEnabled: Boolean
"Whether the change-DB-password mutation is enabled server-wide"
dbUserPasswordChangeEnabled: Boolean
Comment on lines +684 to +685
@Override
public boolean changeConnectionUserPassword(
@LonwoLonwo LonwoLonwo linked an issue Aug 24, 2026 that may be closed by this pull request
@TobyTheHutt

Copy link
Copy Markdown
Author

I looked at the Copilot feedback and commented or reacted to it based on my personal judgement. I'll provide a follow-up commit after the human maintainer review and further instructions.

This PR should not directly close the linked issue. It only covers the DB user password change. It does not yet cover the password-change prompt upon an expired DB user password, which was the original intent of the linked issue.

If any rephrasing or re-specification of the issue is desired, let me know and I'll be on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external For external PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Introduce CloudBeaver password change UI

5 participants