-
-
Notifications
You must be signed in to change notification settings - Fork 151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ADR about division of concerns between Perl and PL/pgSQL #8622
base: master
Are you sure you want to change the base?
Conversation
|
||
For example: the Perl layer will need to provide an entire GL transaction | ||
to be saved, in a single call. The called PL/pgSQL will then verify aspects | ||
such as balancedness and minimally required reporting units. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A way to marshall such data structures is by using JSON.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording of your example seems to imply that when adding or updating a database row, the perl layer must always provide the complete row. I think it is extremely likely that the PL/pgSQL layer can simplify the perl call in certain circumstances when data has defaults, references, etc. Or when the call is used in a lot of places. I don't agree that the perl to PL/pgSQL mapping is 1:1 (i.e. "entire transaction")
Now it may be the case that the business logic around GL Transactions implies that the entire GL transaction will be provided when it is added, but not in other cases.
In this case, I would say something along the lines of "When adding a new GL transaction, the Perl layer will provide all columns needed by PL/pgSQL layer, but when updating a GL transaction the Perl layer may only provide the needed update data."
Maybe I am not clear what the reason for this example, because I can also understand it without the example. But if you are going to have examples, I think you need more than 1 to get the point across.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording of your example seems to imply that when adding or updating a database row, the perl layer must always provide the complete row.
Actually, the example proposes something even stronger: it proposes that for a transaction, the Perl side delivers the "header" (i.e. the ar/ap/gl table record) and the journal lines. Only this way, the Pg side can validate that a complete transaction (as far as the values are applicable) is being sent by the Perl side. Obviously, it would also be possible to have the Perl side only send the modified journal lines, but then the Pg side will have to construct the entire transaction and verify that - with the changes - it's still balanced. By the way, currently, "user__save", "credit_account__save" e.a. also provide the entire saved record (just not a hierarchical structure).
I'm open to ideas on how to maintain consistency in the hierarchical structure of records that the functional concept of "journal transaction" is, because the above is what I could come up with...
These recent developments beg for clarity on the concerns to be fulfilled by | ||
the active layer in PostgreSQL (PL/pgSQL) and the Perl layer. | ||
|
||
## Decision |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The decision doesn't state what should happen on the security side of things. Should the schema enforce this way of working by granting EXECUTE on the procedural interface and revoking INSERT access on the relevant tables? Given our fine-grained security model and our use of CURRENT_USER to create audit trails, SECURITY DEFINER should only be used for bits that don't cause audit logs. (Even if the owner isn't set to a super user, it'll cause changes to CURRENT_USER and/or SESSION_USER.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with your comment. Will the database or perl enforce security? This is important to clarify.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In our current model at least the database has to enforce security: the database is what we have fallen back on until now and I think that's not such a bad principle. The question at hand is whether the user will be allowed to insert anything in the tables governed by the stored procedures. My initial idea was "no"; which then means we need separate roles for inserting data in the tables (to which the stored procedure is "escalated" using SECURITY DEFINER), however, it also means that the code triggered by the INSERTs in the stored procedure cannot trace back to the calling user, because SECURITY DEFINER overrules (both?) CURRENT_USER and SESSION_USER.
Just looked it up; https://www.postgresql.org/docs/15//sql-set-session-authorization.html : SESSION_USER isn't modified. Which is a good thing, because we could then use that for audit trail tracking... In that case, we have a trail back to the authenticated user and we may actually use SECURITY DEFINER to escalate privileges to a level only available to the stored procedure (for inserting the rows).
No description provided.