Redshift IAM authentication replaces a stored database password with a temporary one that AWS issues to an IAM role. The job calls GetClusterCredentials. Redshift returns a database user name and a password that expires in minutes. The connection uses those values over SSL, runs the load, and the password dies. There is no row in Secrets Manager that can log on next month. AWS documents the flow in using IAM authentication to generate database user credentials.
Rutagon builds the cutover for pipelines and admin paths that still connect to a provisioned cluster with a user and a password. The password is usually in Secrets Manager, rotated on a calendar, and copied into a BI tool that nobody wants to reconfigure on a Friday. Rotation keeps a long-lived secret. IAM authentication removes it for every caller that can hold a role. Human access to production tables is a separate review, covered in production database access review. This article is the credential the job presents at connect time.
How Redshift IAM authentication issues the password
GetClusterCredentials takes the cluster, a database user, an optional database name, optional database groups, and a duration. The API allows a duration from 900 seconds to 3600 seconds. The default is 900. We set 900 unless a single statement truly runs longer, and we do not set the maximum out of habit. A 15-minute password that leaks in a log line dies. A password stored in a secret does not.
The user name Redshift returns is not always the name you sent. The API prefixes IAM: when AutoCreate is false and IAMA: when AutoCreate is true. The driver has to connect as that returned name. A client that calls the API and then logs in as the original user with the temporary password will fail, and the failure mode we have seen is someone "fixing" it by putting the permanent password back. We log the returned user name in the job's structured log, without the password, so the next failure is diagnosable.
AutoCreate and DbGroups are the sharp edges on the IAM policy, not on the SQL. If the caller may set AutoCreate true, the policy must allow redshift:CreateClusterUser, and a job can create a database user by connecting. If the caller may pass DbGroups, the policy must allow redshift:JoinGroup on those groups. A group in Redshift is how grants are bundled. A pipeline allowed to join a powerful group has those grants for the session even when the database user looks ordinary. We pin both. AutoCreate stays false for jobs whose user already exists. DbGroups lists the one group the load needs. The IAM action is restricted to that cluster and that group. A policy that allows GetClusterCredentials on * with JoinGroup on * is a standing admin path wearing a temporary password.
SSL is required on this connection. A client configured for IAM auth and cleartext will not negotiate the session you think it negotiated. We set the driver flag in the same change as the authenticator. The JDBC and ODBC drivers can call GetClusterCredentials themselves when they are given the cluster and the role. That is the configuration we prefer for a BI tool that can use it, because the tool never handles a password we stored. A tool that can only accept a username and password field is a leftover secret, and it belongs on the inventory until it is replaced or fronted by a job that uses the driver.
Redshift Serverless is a different API on the workgroup. We do not copy a provisioned cluster's IAM policy onto a workgroup and call the migration done. The workgroup cutover reads the Serverless credential action and uses the workgroup ARN. The idea is the same: the role receives a temporary database credential, and the static password comes out of the client. The policy document is not the same document.
What we remove, and in what order
The inventory is every secret whose value is a Redshift password, plus every task definition and BI connection that references it. Each row gets the database user, the cluster, and the IAM role the compute should use. Users that are people stay on a human path: a role assumed through Identity Center, still calling the same credential API, still without a password in a note. Users that are pipelines get a task role.
cluster: warehouse
db_user: etl_loader
duration_seconds: 900
auto_create: false
db_groups:
- etl
iam_actions:
- redshift:GetClusterCredentials
- redshift:JoinGroup on group etl
secret_arn: removed after the second successful run
connect_user: value returned by the API (IAM: prefix)
ssl: required The database user is created, or altered, so password login is disabled once the IAM path works. In Redshift that is PASSWORD DISABLE on the user. A disabled password means a stolen copy of last quarter's secret cannot open a session. We disable it after two successful scheduled runs on IAM auth, not after a one-off manual connect from a laptop. The manual connect proves the policy. The scheduled run proves the task role, the network path, and the secret removal together.
Order is deliberate. First the IAM policy, scoped as above. Then the driver change in one environment, secret still present and unused. Then two green runs. Then delete the secret and disable the password. Reversing the last two steps produces an outage and a request to recreate the password, which recreates the secret. We would rather fail a deploy with the secret still in reserve than succeed a ticket that puts a new permanent password in place.
RDS IAM database authentication is the sibling cutover for MySQL and PostgreSQL. The token source is different. The habit is the same, and the secret inventory we already maintain in secrets management for production is where the Redshift password shows up next to the RDS one. We migrate one engine at a time so a failure has an obvious caller. We do not build a framework that "does all databases." Each engine's API is small. The work is the inventory and the order.
The BI exception is named. A tool that cannot call the API gets a reader role with a temporary credential issued by a small broker we run, or it gets a dated exception and stays on the inventory. An unnamed exception is how the finance extract keeps a password for a year after the pipeline moved. The exception has an owner and an end date. The end date creates a review item. It does not renew itself.
What the evidence shows
The credential evidence is three checks. The IAM policy for the task role allows GetClusterCredentials on this cluster and denies a broader join. The database user has password login disabled. The secret inventory has no secret for that user's password. Connection logs on the cluster show the IAM: user for the scheduled job. Those checks are queryable. We write them to the evidence bucket on a schedule so the quarter's file is not a screenshot of the console.
A temporary password in an application log is still a bug. Fifteen minutes is enough to matter if the log is copied into a ticket. We keep driver logging off for the credential exchange, and we scrub connection strings in the job logger. The IAM path reduces the lifetime. It does not make log hygiene optional.
Grants on etl remain a data-access question. IAM authentication does not review them. If the group can read schemas outside the load, that shows up in the production database review. Coupling that review to the password removal is how the password stays for another quarter. We remove the password first, with the group pinned to what the job uses today. Narrowing the group is a follow-on grant change with a reader who knows the tables.
Data analytics is where this cluster usually sits in the account, next to the jobs that load it. Security automation is the secret removal and the evidence file. The cluster stays. The long-lived password does not.
Rutagon's deliverable is the scoped IAM policy, the driver configuration that uses the returned user name, the password disable after repeated success, and the evidence that the secret is gone. Duration stays at the short end of the API's range unless a measured statement needs longer, and even then it stays inside the 3600-second cap the API enforces.
Frequently Asked Questions
How long does the Redshift IAM password last?
GetClusterCredentials allows 900 to 3600 seconds, and it defaults to 900. We set 900 unless a real statement exceeds that, and we keep any extension inside the API maximum. The password is not written to Secrets Manager.
Why does the login user not match the user we requested?
The API returns a prefixed name, IAM: when it does not auto-create the user and IAMA: when it does. The driver has to use the returned name. Connecting as the unprefixed user with the temporary password fails. We log the returned name and not the password.
What does AutoCreate change?
If the IAM caller can set AutoCreate true, that caller can create a database user. We leave it false for pipelines whose user already exists, and we do not grant redshift:CreateClusterUser on those roles. DbGroups is similarly pinned, because joining a group is how the session receives grants.
When do we disable the permanent password?
After two successful scheduled runs on the IAM path. A single manual connection is not enough. Disabling the password before those runs is how the team asks for the permanent password to be put back. The secret is deleted in the same window, once the runs are green.
Does this cover Redshift Serverless?
Serverless workgroups use their own credential API. The temporary-credential idea matches, and the IAM policy does not. We read the workgroup action and bind the workgroup ARN. We do not reuse the provisioned cluster policy as if it applied.
Ask for a credential diagnostic of Redshift users that still have a stored password on a pipeline or a BI connection. Contact Rutagon at rutagon.com/contact, 907-841-8407, or contact@rutagon.com.