You can create a read-only
Cloud SQL for PostgreSQL
session using the
cloudsql_session_read_only session parameter. This approach is a more robust
way to prevent data modification during a session than the standard PostgreSQL
read-only options. Using the cloudsql_session_read_only parameter, you can
make the session read-only temporarily, or permanently for the duration of
the session. You can use read-only sessions of this kind
to help protect data integrity in various contexts, including sessions where
you're using Model Context Protocol (MCP) tools, reporting tools, and auditing
tools.
By default, cloudsql_session_read_only is set to off, which allows
data modification.
What read-only mode prevents
In a read-only session, the database can't modify any data. Specifically, read-only mode prevents the following:
Read-only mode prevents the generation of new transaction IDs. No writable transactions can be started, and as a result no data manipulation language (DML) or data definition language (DDL) instructions can be executed. However, if the flag is set in the middle of an active writable transaction, then basic DML and DDL instructions can be executed until the transaction terminates.
Read-only mode prevents the following kinds of statements and calls:
- Statements like
VACUUMandNOTIFY. - Functions with side effects. This means that you can't call a
FUNCTIONor execute aPROCEDUREthat is defined as bothVOLATILEandLANGUAGE CorLANGUAGE internal, because some of their side effects don't require a transaction ID. Examples arepg_promote(),pg_cancel_backend(), andpg_terminate_backend(). - Foreign data wrappers.
- Any function or procedure that you created in a SQL procedural language (PL).
- Statements like
Configure read-only status
During a
Cloud SQL for PostgreSQL
session, you can use the SET statement to
change the value of the cloudsql_session_read_only flag as follows:
SET cloudsql_session_read_only = 'on'This statement makes the session read-only, preventing anyone from modifying data for as long as the flag remains set to
on. To resume modifying data later in the session, change the value back tooff:SET cloudsql_session_read_only = 'off'Setting the flag back to
offrestores write access in the session except when the flag is set tolocked.SET cloudsql_session_read_only = 'locked'Setting the flag to
lockedmakes the session permanently read-only. After the flag is set tolocked, you can't change the flag to any other value for the duration of the session.
To make a session permanently read-only as soon as you connect to the database,
embed the cloudsql_session_read_only flag in the session's connection string:
postgresql://USER:PASSWORD@HOST:PORT/DATABASE?options=-ccloudsql_session_read_only=locked
Make the following replacements:
- USER: the username of the user creating the session.
- PASSWORD: the user's password.
- HOST: the host URL.
- PORT: the port number.
- DATABASE: the database name.
This approach has the added advantage that if you're trying to connect to an older version of Cloud SQL that lacks support for read-only sessions, then the connection fails.
You can also deny write access to a specific database user for all future connections, like this:
ALTER USER USERNAME SET cloudsql_session_read_only = 'locked';
Replace USERNAME with the username of the user whose access you want to restrict to read-only.
Enable specific functions in read-only sessions
- You can enable use of a particular
FUNCTIONorPROCEDUREdefined as bothVOLATILEandLANGUAGE CorLANGUAGE internal. Do this by attaching aSECURITY LABELto the function or procedure that is set toallow. - To disallow a particular function in the session, set a
SECURITY LABELstatement todeny. To allowlist functions that don't affect global state, create a predefined group of security labels:
CREATE EXTENSION "google_read_only_session"The
google_read_only_sessionextension enables the following:- All built-in volatile C functions that are allowed for read-only mode.
- All functions allowed for read-only mode that are from extensions
loaded in the database, including the handler functions for
pl/pgsqlandpl/v8languages.
If you install one or more new extensions afterwards, then to apply group labels, drop and recreate the
google_read_only_sessionextension:> DROP EXTENSION google_read_only_session; > CREATE EXTENSION google_read_only_session;The
DROPcommand doesn't remove any existing labels. The secondCREATEcommand just adds labels for the volatile C functions in the new extension.
What's next
- Learn more about Cloud SQL for PostgreSQL flags.
- Learn more about Cloud SQL for PostgreSQL extensions.