From 674d1398a9f3555d14601a75c10187f057581700 Mon Sep 17 00:00:00 2001
From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com>
Date: Wed, 15 Jul 2026 02:21:51 +0000
Subject: [PATCH] Document dynamic database credentials with connection
functions
Add section explaining Knex connection function pattern for short-lived
credentials (AWS RDS IAM, GCP Cloud SQL, Vault rotation). Includes
MySQL/MariaDB example with AWS RDS IAM auth, now supported as of v5.50.3.
---
.../docs/cms/configurations/database.md | 91 +++++++++++++++++++
1 file changed, 91 insertions(+)
diff --git a/docusaurus/docs/cms/configurations/database.md b/docusaurus/docs/cms/configurations/database.md
index 92f13a67e5..7461e98ec4 100644
--- a/docusaurus/docs/cms/configurations/database.md
+++ b/docusaurus/docs/cms/configurations/database.md
@@ -293,6 +293,97 @@ export default ({ env }) => ({
+## Dynamic database credentials
+
+Some cloud providers issue short-lived database credentials that expire after a fixed period. For example, AWS RDS IAM tokens are valid for 15 minutes; GCP Cloud SQL IAM tokens expire similarly; HashiCorp Vault can rotate secrets on a schedule. Using a static password in `.env` causes intermittent connection failures when the connection pool recycles idle connections after the token has expired.
+
+Strapi supports dynamic credentials through Knex's connection function pattern. Instead of a plain connection object, you can pass a synchronous or asynchronous function to `connection.connection`. Knex calls this function whenever it needs to open a new database connection, ensuring the pool always receives fresh credentials. This pattern works for PostgreSQL and MySQL/MariaDB. TypeScript types officially accept sync and async functions for `connection.connection` as of Strapi v5.50.3.
+
+:::tip
+Include an `expirationChecker` property in the object returned by your function. Knex calls this before reusing a connection from the pool; if it returns `true`, Knex discards the existing connection and calls your function again to obtain fresh credentials.
+:::
+
+### MySQL/MariaDB with AWS RDS IAM authentication
+
+The following example mints a fresh IAM auth token from the AWS SDK each time the pool opens a new MySQL connection. For a PostgreSQL equivalent, see the [PostgreSQL + AWS RDS IAM authentication example](#configuration-examples) in the configuration examples above.
+
+
+
+
+```js title="./config/database.js"
+const { Signer } = require('@aws-sdk/rds-signer');
+
+module.exports = ({ env }) => {
+ const signer = new Signer({
+ hostname: env('DATABASE_HOST', '127.0.0.1'),
+ port: env.int('DATABASE_PORT', 3306),
+ username: env('DATABASE_USERNAME', 'strapi'),
+ });
+
+ return {
+ connection: {
+ client: 'mysql',
+ connection: async () => {
+ const token = await signer.getAuthToken();
+ const expiresAt = Date.now() + 15 * 60 * 1000;
+
+ return {
+ host: env('DATABASE_HOST', '127.0.0.1'),
+ port: env.int('DATABASE_PORT', 3306),
+ database: env('DATABASE_NAME', 'strapi'),
+ user: env('DATABASE_USERNAME', 'strapi'),
+ password: token,
+ ssl: true,
+ expirationChecker: () => expiresAt - Date.now() <= 5 * 60 * 1000,
+ };
+ },
+ },
+ };
+};
+```
+
+
+
+
+```ts title="./config/database.ts"
+import { Signer } from '@aws-sdk/rds-signer';
+
+export default ({ env }) => {
+ const signer = new Signer({
+ hostname: env('DATABASE_HOST', '127.0.0.1'),
+ port: env.int('DATABASE_PORT', 3306),
+ username: env('DATABASE_USERNAME', 'strapi'),
+ });
+
+ return {
+ connection: {
+ client: 'mysql',
+ connection: async () => {
+ const token = await signer.getAuthToken();
+ const expiresAt = Date.now() + 15 * 60 * 1000;
+
+ return {
+ host: env('DATABASE_HOST', '127.0.0.1'),
+ port: env.int('DATABASE_PORT', 3306),
+ database: env('DATABASE_NAME', 'strapi'),
+ user: env('DATABASE_USERNAME', 'strapi'),
+ password: token,
+ ssl: true,
+ expirationChecker: () => expiresAt - Date.now() <= 5 * 60 * 1000,
+ };
+ },
+ },
+ };
+};
+```
+
+
+
+
+:::note
+AWS RDS IAM authentication requires SSL and IAM database authentication to be enabled on the RDS instance. Refer to the for the required certificate bundle and setup instructions.
+:::
+
## Configuration in database
Configuration files are not multi-server friendly. To update configurations in production you can use a data store to get and set settings.