The information contained in this article has been verified as up-to-date on the date of the original publication of the article. HashiCorp endeavors to keep this information up-to-date and correct, but it makes no representations or warranties of any kind, express or implied, about the ongoing completeness, accuracy, reliability, or suitability of the information provided.
All information contained in this article is for general information purposes only. Any reliance you place on such information as it applies to your use of your HashiCorp product is therefore strictly at your own risk.
Introduction
Vault's Database Secret Engine can dynamically generate short-lived credentials on demand, automatically expires them when their time-to-live (TTL) is reached, and, in theory, cleans up those credentials in the database so they cannot be reused.
Problem
Teams using the database secret engine may find that their dynamic credentials are being created, but are not being removed from the database. Over time, this can cause a large number of stale users to accumulate and the database to grow in size. This could cause performance degradation.
Cause
If revocation_statements are not defined in the Vault role used for generating dynamic credentials, Vault will instead insert generic SQL statements. As mentioned in the Create a role of Vault's dynamic secret documentation. These generic statements are not recommended in production deployments as they may be unsuitable.
Important: when you define the role in a production deployment, you must create user creation_statements, revocation_statements, renew_statements, and rotation_statements which are valid for the database you've configured. If you do not specify statements appropriate to creating, revoking, or rotating users, Vault inserts generic statements which can be unsuitable for your deployment.
For example, the code snippet below shows the default generic statement for the MySQL plugin.
REVOKE ALL PRIVILEGES, GRANT OPTION FROM '{{name}}'@'%';
DROP USER '{{name}}'@'%'Prerequisites
- Vault Enterprise or Vault OSS with the Database Secrets Engine enabled
- Integrated Storage (Raft) deployments
- Familiarity with your database's authentication patterns (e.g., required host patterns, user naming conventions)
- (Recommended) A non‑production environment where you can safely test custom
revocation_statementsbefore applying them in production
Overview of Solution
If the users are not being deleted even after the dynamic secrets have expired, the default revocation_statements is likely insufficient for your database setup. This can be resolved by defining a custom revocation_statements. As shown below, this can be as simple as specifying the host or including additional conditions to better target the database credentials. The following is an example and should not be used as your actual revocation_statements unless it matches your environment.
DROP USER '{{name}}'@'1.123.12.%';Outcome
Once implemented, you can verify the revocation_statements is working by either waiting until the TTL expires on the dynamic secret or manually revoking with the lease ID and seeing if the credentials are removed in the database as expected. If this is not working, it’s possible that the current custom revocation statement is not sufficient for removing the credentials from the database. This may require additional testing to figure out what fields are needed to remove the credentials from your database.
Additional Information
Default revocation_statement - Example of the default MySQL
revocation_statement. Other database types are available under similar paths in the same repository, e.g.,vault/plugins/database/postgresql/postgresql.goCreating a role for dynamic secrets - Tutorial on configuring a database secret engine role, including best practices for defining revocation statements in production.
Understanding static and dynamic secrets - Overview of static and dynamic secrets and their use with database secret engines.