If you need to know who did what to the data and when it was done, one way to do that is to log every action that is performed on an important table.
There are at least two equally valid ways of doing the auditing:
Here, we will take a look at minimal examples of both the approaches.
First, let's create the tables:
You don't generally want your users to be able to change audit logs, so grant only the managers the right to access these. If you plan to let users access the salary table directly, you should put a trigger on it for auditing:
Now, let's test out some salary management:
Each one of those changes is saved into the salary change log table for auditing purposes:
On the other hand, you may not want anybody to have direct access to the salary table, in which case you can perform the following:
Also, give users access to only two functions: the first is for any user looking at salaries and the other is for changing salaries, which is available only to managers.
The functions themselves will have all the access to underlying tables because they are declared as SECURITY DEFINER
, which means they run with the privileges of the user who created them.
The salary lookup function will look like the following:
Notice that we implemented a "soft security" approach, where you can look up for other people's salaries, but you have to do it responsibly, that is, only when you need to as your manager will know that you have checked.
The set_salary()
function abstracts away the need to check if the user exists; if the user does not, it is created. Setting someone's salary to 0
will remove him from the salary table. Thus, the interface is much simplified and the client application of these functions needs to know and do less:
Now, drop the audit
trigger (or the changes will be logged twice) and test the new functionality: