Skip Navigation
Show nav
Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
View categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Developer Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Working with Node.js
      • Troubleshooting Node.js Apps
      • Node.js Behavior in Heroku
    • Ruby
      • Rails Support
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Model Context Protocol
    • Vector Database
    • Heroku Inference
      • Inference API
      • Quick Start Guides
      • AI Models
      • Inference Essentials
    • Working with AI
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
  • Databases & Data Management
  • Heroku Postgres
  • Postgres Basics
  • Heroku Postgres Credentials

Heroku Postgres Credentials

English — 日本語に切り替える

Last updated January 23, 2025

Table of Contents

  • The Default Credential
  • Creating a New Credential
  • Managing Permissions
  • Attaching Credentials to Apps
  • Managing Credentials
  • Forks and Followers
  • Best Practices
  • Caveats and Considerations
  • Limits

Postgres manages database access using the concept of roles. You can grant and revoke specific privileges to roles that define what they can do when connected to the database.

Heroku Postgres provides a management layer around these roles called credentials. Each credential corresponds to a different Postgres role and its specific set of database privileges.

You can manage credentials from data.heroku.com or from the Heroku CLI. Credentials are available only to production plans (Standard, Premium, Private, and Shield). Essential plans only have the default credential, which can’t create other credentials or manage permissions. Postgres credential passwords are dynamically generated, 65-byte alphanumeric character strings.

The Default Credential

Every newly provisioned Heroku Postgres database includes a default credential. This credential corresponds to a permissive role that is one step below the superuser. This credential is the owner of the database. It can:

  • Create new schemas and objects in the database and manage or alter any of the schemas and objects it owns.
  • GRANT privileges to other credentials.
  • Read statistics and monitoring data. The default credential is a member of pg_monitor, pg_read_all_settings, and pg_read_all_stats.
  • Cancel or terminate other non-superuser backend processes. The default credential is a member of pg_signal_backend.
  • Install supported extensions.

Creating a New Credential

To protect against CVE-2018-1058, new credentials don’t have access to the public schema for ALL users by default. You must regrant access to the public schema to any users that need access to it.

You can create credentials through the Heroku CLI and through data.heroku.com.

To create the credential through data.heroku.com:

  1. Open a Heroku Postgres database.
  2. Select the Credentials tab.
  3. Click the Create Credential button.

Creating a new credential

You can also create the credential with the pg:credentials:create CLI command:

$ heroku pg:credentials:create postgresql-sunny-1234 --name limited_user -a example-app
Creating credential limited_user... done

The name parameter must reflect the purpose of the credential. In the example, limited_user is the credential’s username when connecting to the database.

In both cases, the credential password is a dynamically generated, 65-byte alphanumeric character string.

Credentials created via the CLI can be used to log in to the database, but they can’t read from or write to any of your tables.

Managing Permissions

You can configure permissions for new and existing credentials through the Heroku CLI and through data.heroku.com.

To configure the credential through data.heroku.com, select one of the different permission levels below when creating the credential. Or, you can also go to the Credentials tab, find the credential you want to configure, and select one of the permission levels. The levels are:

  • No permissions: no access privileges on any table in the database
  • Read-only permissions: read access on every table in the database
  • Read-write permissions: read and write access on every table in the database, including the ability to delete data, and the ability to generate values from sequences

If the schema changes on your database, the display name of the permission on your credential changes to Custom permissions. To ensure you have the appropriate access levels with the changed schema, you can run additional GRANT and REVOKE statements on your default user.

Configuring permissions on an existing credential

The tables also include views, materialized views, and foreign tables. The privileges configured also apply to any tables that are created in the future until the credential is reconfigured with a different set of permissions.

All users can read the system catalogs in the information_schema and pg_catalog schemas that describe the structure of the database and basic statistics. These tables and views aren’t subject to the permission levels.

None of the built-in permissions levels have access to create tables or other database objects.

To configure privileges via the CLI, use the default credential to log in to the psql console, and run standard Postgres GRANT, REVOKE, and ALTER DEFAULT PRIVILEGES commands.

For example, you can grant the limited_user credential in the example the privileges for read-only access to the public schema. This process follows standard Postgres conventions:

$ heroku pg:psql postgresql-sunny-1234 -a example-app
--> Connecting to postgresql-sunny-1234
psql (13.2, server 11.12 (Ubuntu 11.12-1.pgdg16.04+1))
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

example-app::CYAN=> GRANT USAGE ON SCHEMA public TO limited_user;
GRANT
example-app::CYAN=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO limited_user;
GRANT
example-app::CYAN=> ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO limited_user;
ALTER PRIVILEGES
example-app::CYAN=> \q

In this example, the limited_user credential has been granted the privileges to run read-only queries on any of the tables within the public schema. At this point, limited_user can be used to log into the database and interact with the information within it.

Breaking this down step by step:

GRANT USAGE ON SCHEMA public TO limited_user;

This command allows the credential to look up tables and other database objects within the public schema.

GRANT SELECT ON ALL TABLES IN SCHEMA public TO limited_user;

This command allows the credential to run SELECT on any table, view, materialized view, or foreign table in the default public schema. If you’re using additional schemas and want to grant access to those, you can add them separated by commas:

GRANT SELECT ON ALL TABLES IN SCHEMA public, my_schema TO limited_user;

Each schema must be listed explicitly. You can’t grant access to all schemas at once. You can, however, grant access to only specific tables:

GRANT SELECT ON TABLE public.users TO limited_user;

And finally:

ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO limited_user;

This command allows the credential to automatically receive SELECT privileges on any new table, view, materialized view, or foreign table created by the default user in the public schema. The ALTER DEFAULT PRIVILEGES command allows you to pre-configure privileges for tables and other database objects that haven’t been created. Unlike the above GRANT, you can also alter the default privileges for all schemas:

ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO limited_user;

If you want to limit a role’s privileges, you must revoke existing access before granting more limited privileges. For example, to change the privileges of a user who previously had been granted SELECT and UPDATE on tables in the public schema, run:

REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM limited_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO limited_user;

For more information on how to configure credentials, see the Postgres Community Documentation on roles, privileges, and the GRANT, REVOKE, and ALTER DEFAULT PRIVILEGES commands.

Attaching Credentials to Apps

addons:attach

After credentials have been created within Heroku Postgres, you can attach them to apps as a config var via the addons:attach command. Assume that a new credential has been created:

$ heroku pg:credentials:create postgresql-sunny-1234 --name analyst -a example-app
Creating credential analyst....  done

Now that the analyst credential has been created, you can attach it to any number of applications within Heroku. The application can be the billing application or any other application that needs access:

$ heroku addons:attach postgresql-sunny-1234 --credential analyst -a example-app
Attaching analyst of postgresql-sunny-1234 to ⬢ example-app... done
Setting DATABASE config vars and restarting ⬢ example-app... done, v24

If no other Heroku Postgres exist as part of the application that the database is being attached to, the credential is assigned to the DATABASE_URL config var. If DATABASE_URL already exists on the application, the credential is attached to the application using the format HEROKU_POSTGRESQL_[COLOR]_URL.

addons:detach

If the credential on the application isn’t needed, the credential must be detached from the application. For example, to remove a credential called analyst attached to the example-app app, use the addons:detach command with the config var containing the credential:

$ heroku addons:detach DATABASE -a example-app
Detaching DATABASE from postgresql-sunny-1234 from ⬢ example-app... done
Unsetting DATABASE config vars and restarting ⬢ example-app... done, v23

Managing Credentials

The Heroku CLI provides several commands for managing your Postgres credentials. This functionality is also available through the Credentials tab on a Postgres database through data.heroku.com.

pg:credentials

Use the pg:credentials command to list the name and state of every credential that has been created for a particular database:

$ heroku pg:credentials DATABASE_URL -a example-app
Credential  State
──────────  ──────
default     active
analyst     active

The database in the example has one custom credential (analyst), along with the default credential. Possible credential states, such as active in the example, are covered in Credential Rotation State Details.

pg:credentials:create

Use the pg:credentials:create command to create a credential for the database:

$ heroku pg:credentials:create DATABASE_URL --name analyst -a example-app
Creating credential analyst....  done

The --name parameter is the name of the credential within the database.

When a credential is first created, it only has the CONNECT privilege. To learn how to configure access for a new credential, see Managing Permissions.

pg:credentials:destroy

Remove a credential from Postgres with the pg:credentials:destroy command:

$ heroku pg:credentials:destroy DATABASE --name analyst -a example-app
 ▸    WARNING: Destructive action
 ▸    To proceed, type example-app or re-run this command with --confirm example-app
> example-app
Destroying credential analyst... done
The credential has been destroyed within postgresql-solid-58569 and detached from all apps.
Database objects owned by analyst will be assigned to the default credential

Confirmation is required to remove credentials from the database. If the credential has any attachments, you must detach it from those applications before destroying it. See the Help article on heroku addons:detach for more information on how to remove a credential from a secondary application.

pg:credentials:rotate

In some cases, you must replace the passwords associated with your credentials. In general, rotating credentials on a regular basis is a good security practice.

The pg:credentials:rotate command lets you change some or all of the credential passwords within the database at one time. When a credential rotation occurs, Heroku Postgres notifies all affected apps and triggers an app restart to get the new credentials. To rotate a single credential:

$ heroku pg:credentials:rotate DATABASE --name analyst -a example-app
 ▸    WARNING: Destructive action
 ▸    To proceed, type example-app or re-run this command with --confirm example-app
> example-app
Rotating analyst on postgresql-solid-58569... done

If you don’t provide a credential name for the --name argument, the default credential is rotated:

$ heroku pg:credentials:rotate DATABASE -a example-app
 ▸    WARNING: Destructive action
 ▸    To proceed, type example-app or re-run this command with --confirm example-app
> example-app
Rotating default on postgresql-solid-58569... done

To rotate all credentials, pass the --all flag into the command:

$ heroku pg:credentials:rotate DATABASE --all -a example-app
 ▸    WARNING: Destructive action
 ▸    To proceed, type example-app or re-run this command with --confirm example-app
> example-app
Rotating all credentials on postgresql-solid-58569... done

Credential Rotation State Details

When a credential rotation is requested, applications can still have open connections to the database. The old credential expires as soon as there are no existing connections using it. If there are in-progress transactions, Heroku Postgres waits up to 30 minutes before killing existing connections and requiring clients to use new login details.

If in-progress transactions exist during a credential rotation, Heroku Postgres provisions temporary “rotating” usernames alongside the usernames currently in use. During the rotation, the pg:credentials command displays these usernames, which all end with -rotating to indicate that they’re temporary:

$ heroku pg:credentials:rotate DATABASE --name analyst -a example-app --confirm
Rotating analyst on postgresql-solid-58569... done
$ heroku pg:credentials -a example-app
Credential                                    State
────────────────────────────────────────────  ──────────
default                                       created
analyst                                       rotating
       Usernames currently active for this credential:
       analyst-rotating  active                                    0 connections
       analyst           waiting for no connections to be revoked  0 connections

After these in-progress transactions are complete and their associated connections are closed, the “rotating” username is renamed to the original username. Any connections that were created during the rotation are allowed to stop before this rename occurs.

Force Rotation

In some cases, waiting for 30 minutes for connections to close can be too long. In those circumstances, you can use the --force flag. --force immediately kills all connections to the credential and performs the rotation.

$ heroku pg:credentials:rotate DATABASE --name analyst --force -a example-app --confirm
Rotating analyst on postgresql-solid-58569... done

pg:credentials:url

The pg:credentials:url command provides convenient access to your database’s location and login credentials so you can access it with any number of visualization tools:

$ heroku pg:credentials:url DATABASE --name analyst -a example-app
Connection information for analyst credential

Connection info string:
   "dbname=dee932clc3mg8h host=ec2-123-73-145-214.compute-1.amazonaws.com port=6212 user=analyst password=98kd8a9 sslmode=require"
Connection URL:
   postgres://analyst:[email protected]:6212/dee932clc3mg8h

If you don’t provide a credential name for the --name argument, the connection details for the default credential are printed to stdout.

pg:credentials:repair-default

Use the pg:credentials:repair-default command to restore your database’s default credential in the event that default permissions or database object ownership are accidentally altered. This command makes the default credential the owner of all objects in the database, restores default permissions, and grants the default credential admin option on all additional credentials in the database.

$ heroku pg:credentials:repair-default DATABASE -a example-app
Resetting permissions and object ownership for default role to factory settings... done

Forks and Followers

Follower databases on Heroku Postgres are (almost) exact copies of their corresponding primary database. As changes are made to the primary database, those changes are streamed to the follower in real-time. Consequently, any credentials created on a primary database automatically cascade to the follower.

Follower database credentials match primary database credentials, but followers are inherently read-only and can’t be written to by any role, even if it has write permissions. If you run the unfollow command, the follower becomes a fork, and any credentials with appropriate permissions are able to write.

If credential commands like create, destroy, or rotate are run against a follower, an error message is given indicating the command can’t run against the database:

$ heroku pg:credentials:create postgresql-moonlight-5678 -a example-app
This operation is not supported for follower databases.

A fork is an entirely new database that contains a snapshot of the data from another existing Heroku Postgres database. Unlike a follower database, a fork doesn’t stay up to date with the primary database and is therefore writeable.

When a fork is created, any credentials in the primary database at the time of the fork are included in the fork. However, future modifications to primary database credentials aren’t reflected in the fork.

Best Practices

Using the Default Credential

Applications that use Heroku Postgres as their data store must use the default credential when creating connections to the database. This goes for any schema modifications as well. The default credential is meant to work seamlessly with the entirety of the Heroku platform.

Read-Only Users

A common pattern for credentials within Postgres is to give a user read-only access to all of the information within the schema. This means the credential isn’t able to INSERT, UPDATE, or DELETE data or make schema changes. You can create read-only users via the Heroku Data Dashboard Credentials tab, or via the CLI.

To add a read-only user through the CLI, first, create the credential. Then, using the default credential, log in to the Postgres console for the database:

$ heroku pg:psql postgresql-sunny-1234 -a example-app
--> Connecting to postgresql-sunny-1234
psql (13.2, server 11.12 (Ubuntu 11.12-1.pgdg16.04+1))
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
example-app::CYAN=> GRANT USAGE ON SCHEMA public TO analyst;
GRANT
example-app::CYAN=> GRANT SELECT ON ALL TABLES IN SCHEMA public
  TO analyst; -- give access to the existing tables
GRANT
example-app::CYAN=> ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO analyst; -- give access to future tables
ALTER PRIVILEGES

See Managing Permissions earlier for more information about the details of the statements and the permissions granted.

Caveats and Considerations

  • Permissions configuration isn’t permanent. You can update them at any time by the default credential or any other credential that has WITH GRANT OPTION privileges.
  • The permissions management in data.heroku.com assumes the default credential creates all tables and other database objects. Creating objects with other credentials can mean users aren’t automatically granted the access their permissions configuration dictates.
  • Credentials must be created and destroyed via the CLI or data.heroku.com instead of using CREATE ROLE and associated DDL statements directly, but otherwise behave like standard Postgres credentials.
  • Credential names are restricted to alphanumeric characters (- and _ are also supported) and can’t be longer than 50 characters.
  • Credentials aren’t backed up by PGBackups and aren’t available when restoring from those backups.

Limits

The maximum number of credentials Heroku Postgres supports is 120.

We strongly recommend that you use as few credentials as possible for security and operational reasons. Be sure to track where you’re using the credentials.

Keep reading

  • Postgres Basics

Feedback

Log in to submit feedback.

Upgrading the Version of a Heroku Postgres Database Heroku Postgres Follower Databases

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices