Safeguard
Security Guides•

What is the PUBLIC role in PostgreSQL grants and why does it matter?

PUBLIC is an implicit group that includes every role. Privileges granted to it apply to all users, and new functions give it EXECUTE by default.

Safeguard Security Team
4 min read

PUBLIC is an implicit group in PostgreSQL that always includes every role. Any privilege granted to PUBLIC applies to all users, present and future. Because newly created functions grant EXECUTE to PUBLIC by default, a locked down role design can still have open doors until you revoke from it.

What the documentation says

The GRANT reference says PUBLIC can be thought of as an implicitly defined group that always includes all roles. A role's effective privileges are the sum of three things: privileges granted directly to it, privileges granted to any role it is a member of, and privileges granted to PUBLIC.

The privileges chapter describes the special role name PUBLIC as a way to grant a privilege to every role on the system. It also shows the reverse, using a REVOKE command naming PUBLIC.

Two limits are worth knowing. Grant options cannot be granted to PUBLIC, and role membership cannot be granted to PUBLIC.

The default that surprises people

The CREATE FUNCTION reference notes that by default, execute privilege is granted to PUBLIC for newly created functions. If you create a function that does something sensitive, every role can call it unless you change that.

What to check

AreaQuestionHow PUBLIC fits
FunctionsWho can call this?New functions start with EXECUTE for PUBLIC
TablesWho can read this?Check for grants to PUBLIC
SchemasWho can create or use objects?PUBLIC grants widen it for all roles
Role membershipCan anyone join this role?Not grantable to PUBLIC
Least privilege designDoes my role list match reality?PUBLIC adds to every role silently

The last row is the important one. You can design careful roles and then find that PUBLIC gives every role access you did not intend. Auditing the roles alone will miss it.

How to revoke safely

REVOKE ALL ON FUNCTION audit_write(text) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION audit_write(text) TO app_runtime;

The PostgreSQL docs recommend doing the create, revoke and grant in a single transaction for sensitive functions, so there is no window where the new function is callable by all.

An audit routine

  1. Query the catalog for grants to PUBLIC on tables, functions and schemas. Check how your version represents it, since the grant lists are stored on each object.
  2. For each, decide whether every current and future role should have that access.
  3. Revoke what should not be open, and grant to named roles instead.
  4. Test by connecting as a low privilege role and trying the action.
  5. Add the revoke step to your migration template so new functions do not start open.
  6. Review again after major upgrades or when you add extensions.

Compare this with the earlier post on the public schema CREATE privilege, which covers a related widely open default. For function owners, see SECURITY DEFINER functions and search_path.

How this connects to role design

PUBLIC is part of why a role list alone is not a complete picture of access. The same idea appears in cloud IAM, where a wildcard principal grants to everyone. For another view of roles, see predefined roles in PostgreSQL.

Safeguard scans dependencies and infrastructure code in your repositories and can enforce policy on pull requests. A free scan is at gold.safeguard.sh/scan.

Quick check

Does PUBLIC include roles created later?

Yes. The docs describe it as an implicit group that always includes all roles.

Can I give someone the right to grant a privilege to PUBLIC?

No. The docs say grant options cannot be granted to PUBLIC.

What does a new function allow by default?

The CREATE FUNCTION docs say execute privilege is granted to PUBLIC for newly created functions.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.