Postgres Large Objects & Multiple Users

One option is to use SET ROLE command after you open a connection from your application to the databaserole:

SET ROLE databaserole;

In such way any object (including large objects) created within this session will be owned by databaserole instead of token-XXX.

Another option is to use LOCAL and make it work only within the transaction used to create the large object:

BEGIN;
SET LOCAL ROLE databaserole;
-- create and insert the large object
COMMIT;

Alternatively, you could just set the role directly as the user setting:

ALTER ROLE "{{name}}" SET role TO 'databaserole';

I kind of dislike that option as it can become a bit obscure to others how it is working, and if you manage other roles to your user it won't inherit them (although that doesn't seem like a problem to you, as with dynamically created user you should have a single role that it directs inherit from).


How can I setup Postgres so that the Large Objects always have the ownership of the role's member parent

There's no way to do that. But if you have control over the program's code, it could issue

GRANT SELECT ON LARGE OBJECT :objid TO databaserole;

immediately after each object is created.


Otherwise, a drastic solution would be switching the database to pre-9.0 large object permissions:

ALTER DATABASE dbname SET lo_compat_privileges TO on;

Documentation:

lo_compat_privileges (boolean)

In PostgreSQL releases prior to 9.0, large objects did not have access privileges and were, therefore, always readable and writable by all users. Setting this variable to on disables the new privilege checks, for compatibility with prior releases. The default is off. Only superusers can change this setting.

Setting this variable does not disable all security checks related to large objects — only those for which the default behavior has changed in PostgreSQL 9.0. For example, lo_import() and lo_export() need superuser privileges regardless of this setting.

This might make sense because the logic of "extending rows" by large objects is at odds with the post-9.0 large object permissions logic. The difference is that future rows in a table have access rights predetermined by GRANTS to the table, whereas the concept of access rights applying to not-yet-created large objects does not exist.

Lastly, if there is a way to reconfigure your application so that it uses bytea fields instead of large objects, that would be an ideal solution.