How to allow create extension without superuser privilege? - postgresql

I went through the question/answers cannot create extension without superuser role and other related, which tells that I cannot avoid that issue without being a superuser.
But I am working with an AWS server now, in which I am able to install extension tablefunc without being a superuser, but I cannot do the same on a new postgres server. I am attaching a screenshot here of the roles present in the AWS database, here you will see, role pgadmin is not a superuser (and also none of the role group it's attached to are superuser, though it doesn't matter anyhow), but I can create the extension with it.
I understand the other workarounds, but just need a clarification for this. How is it working in AWS and why can't I replicate the same on a new Postgres server.

If you have access to and can update the extension control file, do this:
echo 'superuser = false' >> /usr/share/postgresql/14/extension/pg_cron.control
That example is for pg_cron but the same approach should work for any extension.

Related

Enabling pg_cron extension on postgres database without rds_superuser

I'm trying to follow this article to enable the pg_cron extension on my postgres RDS instance on AWS:
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html
it says to run on the rds_superuser
CREATE EXTENSION pg_cron;
However, I'm logged in under a different user, I don't currently have access to the rds_superuser account. The message I get is:
SQL Error [42501]: ERROR: permission denied to create extension "pg_cron"
Hint: Must be superuser to create this extension.
Can anyone please tell me a work-around for this without having to contact a DBA? Can I grant superuser or create a new user with superuser to get around this?
it looks like the current user I have access to only shows on the pg_tables access to:
rolinherit - X
rolcanlogin - X
Ok I found out that if you go to your RDS database instance on AWS, you can "Modify" the RDS instance, and change the master password for the sysadmin user. I was then able sign in with this user and do what I needed to do.

Setting session_replication_role for GCP Cloud SQL

I am trying to run SET session_replication_role = 'replica'; in a GCP Cloud SQL Postgres 9.6 instance, however I'm encountering this error ERROR: permission denied to set parameter "session_replication_role" even if the postgres user is a cloudsql admin user. Do I have to spin up my own self managed instance to solve the problem or is there a way around it?
Unfortunately, it is not connected with the service is in Beta or not, you can't set session_replication_role in GCP Cloud SQL.
You need to have superuser privileges to do that operation, but GCP Cloud only allows to cloudsqlsuperuser privileges. It's features as follows:
When you create a new Cloud SQL for PostgreSQL instance, the default postgres user is already created for you, though you must set its password.
The postgres user is part of the cloudsqlsuperuser role, and has the following attributes (privileges): CREATEROLE, CREATEDB, and LOGIN. It does not have the SUPERUSER or REPLICATION attributes.
You can find much more information in this blog post.
From what I was looking at, since the service is currently in Beta, there are still some features that are not available, such as that. Therefore we would need to wait a bit more for Google to realease the final version of their product.
We also encountered same issue . This is because postgres user does not have Replication permission.
To resolve this issue:
a) Login with postgres user
b) Since postgres user has Create role permission. Now create a new user with below command:
CREATE USER <YOUR_USER> WITH PASSWORD '<YOUR_PASSWORD>' CREATEDB CREATEROLE REPLICATION IN GROUP cloudsqlsuperuser;
replace <YOUR_USER> with your user name and <YOUR_PASSWORD> with password.
c) Login with newly created user and run
SET session_replication_role = 'replica';
if you see response SET then you are good to go

Using Postgres PGCrypto encryption requires superuser to run view queries

Using: Postgres 9, CentOS 7,
Postgres Data directory not in default location but used RSync to make sure permissions were correct. And yes appropriate .config files were changed.
When I try to query a view containing an encrypted item as a NON superuser (Testuser), I get this error:
ERROR: must be superuser to read files CONTEXT: PL/pgSQL function
decrypt_data(bytea) line 13 at assignment
If I run that same query using POSTGRES superuser, the query completes fine.
This seems to be a file system read permission error when trying to read the Key files. Everything I see using encryption seem to not mention how to run without being superuser.
I have already run the following grants for Testuser:
GRANT ALL PRIVILEGES ON DATABASE xxx_db to Testuser;
GRANT SELECT ON ALL TABLES IN SCHEMA xxxxx TO Testuser;
GRANT ALL ON ALL TABLES IN SCHEMA xxxxx TO Testuser;
The test user can create tables, views, basically anything within that db.. just not read encryption keys.
The permissions on the keys are 775 right now, I even tried 777 without luck.
Any Ideas?
pgcrypto is a PostgreSQL extension described here:
https://www.postgresql.org/docs/current/static/pgcrypto.html
but it doesn't provide a decrypt_data(bytea) function.
This function seems to be custom code that happens to open a server-side file, with pg_read_file() or a similar method.
These methods are restricted to superusers to avoid normal users to read on the server's filesystem, no matter what are the Unix rights of the particular file they want to read.
You can verify this in the source of decrypt_data(bytea), which can be obtained with:
select pg_get_functiondef('decrypt_data(bytea)'::regprocedure);
or \df+ decrypt_data(bytea) from within psql.
I found the issue. I need to grant the user with function permissions.
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA xxxxx TO yyyyyyyyy;

Install extension in PostgreSQL database via migration without superuser role?

We are using migrations (via Sequelize, in JavaScript) to maintain changes to our database. I have a need to add a CREATE EXTENSION call but since I am running as the database creator, and not superuser, I get a permission denied to create extension.
Is there a way to modify security on a single database to allow a user to install an extension via a migration file? IOW, when I create the "naked" database and apply my permissions, can I set security up to allow CREATE EXTENSION and DROP EXTENSION for a specific user?
No, there is no setting for CREATE ROLE for granular CREATE/DROP EXTENSION control. I assume, it depends on the extension you use, but you based on the documentation:
Loading an extension requires the same privileges that would be
required to create its component objects. For most extensions this
means superuser or database owner privileges are needed. The user who
runs CREATE EXTENSION becomes the owner of the extension for purposes
of later privilege checks, as well as the owner of any objects created
by the extension's script.
I was running into the same issue with pg_trgm extension, but even setting role to database owner did not resolve the issue.
Could not find a way to do this inside a migration file.
The technique we ended up using was to have a subfolder in the migration folder, called postgres to hold anything that must be run as superuser. The subfolder contained the migrations and a config file for running things as a superuser. So, the command-line becomes:
$ sequelize db:migrate --migrations-path "migrations/postgres" --config "migrations/postgres"
$ sequelize db:migrate
The inconvenience of a more complex command-line was mitigated by the fact that the "special" migrations that required this isolation also made them more evident.
For anyone still looking, here is how to create an extension via a sequelize migration. It doesn't address the secondary question of user roles however. But this works for me.
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.query('CREATE EXTENSION extensionName;');
},
down: (queryInterface, Sequelize) => {
return queryInterface.sequelize.query('DROP EXTENSION extensionName;');
}
};

Why can only a superuser CREATE EXTENSION hstore, but not on Heroku?

When I attempt to enable hstore on my database:
=> CREATE EXTENSION IF NOT EXISTS hstore;
ERROR: permission denied to create extension "hstore"
HINT: Must be superuser to create this extension.
My user is not a superuser, but is the owner of the database.
According to the CREATE EXTENSION docs:
Loading an extension requires the same privileges that would be required to create its component objects. For most extensions this means superuser or database owner privileges are needed. The user who runs CREATE EXTENSION becomes the owner of the extension for purposes of later privilege checks, as well as the owner of any objects created by the extension's script.
What is hstore doing that requires superuser privileges? Is it affecting parts of the cluster outside the database I'm adding it to?
Further confundity:
The DB user Heroku Postgres provides is not a superuser:
Heroku Postgres users are granted all non-superuser permissions on their database. These include SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER, CREATE, CONNECT, TEMPORARY, EXECUTE, and USAGE.
However, that user is able to CREATE EXTENSION hstore:
To create any supported extension, open a session with heroku pg:psql and run the appropriate command:
$ heroku pg:psql
Pager usage is off.
psql (9.2.4)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.
ad27m1eao6kqb1=> CREATE EXTENSION hstore;
CREATE EXTENSION
ad27m1eao6kqb1=>
(For context, I'm attempting to set up a Dokku deployment, so the comparison to Heroku is especially important.)
The hstore extension creates functions that call code from an external dynamic object, which requires superuser privilege. That's why creating the hstore extension requires superuser privilege.
As for Heroku, it is my understanding that they are running with a special extension whitelisting module, which allows users to create certain extensions even though they are not superusers. I believe it is based on this code: https://github.com/dimitri/pgextwlist. You can try to install that code yourself if you want the same functionality in your databases.
ALTER USER myuser WITH SUPERUSER;
If you run this command from a superuser, this solves your CREATE EXTENSION issue. You may check your available users with \du to find a superuser.
This is not related to heroku.
This is how I solved this issue in ubuntu 18.04.
Provide postgres super user access.
sudo su postgres
Then I run:
psql -U postgres your_database_name -c 'create extension hstore;'
Now I can alter table your_database_name and add hstore type columns in it.
Connect to your database
psql -d your_database_name -U your_user_role
And
alter table your_table_name add your_column_name HSTORE;
Though there might be saveral different ways to do it, but I solve it in this way.
Hope this will help novice users like me.