teleport
teleport copied to clipboard
Record PostgreSQL queries/command results
Part of RFD 0171 implementation.
Adds the DatabaseSessionCommandResult
audit event and records it on the server response. PostgreSQL uses CommandResult
(for success) and ErrorResponse
(for failure) for all actions, so the handler needs to cover both cases to identify the command completion. (A single user action might return more than one message. Those are discarded, as we can rely on the last one).
Example of session recording (with metadata shortened)
[
{
"ei": 0,
"event": "db.session.user.create",
"code": "TDB08I",
"time": "2024-06-26T14:22:25.409Z",
"success": true,
"username": "alice",
"roles": [
"editor"
]
},
{
"ei": 1,
"event": "db.session.start",
"code": "TDB00I",
"time": "2024-06-26T14:22:25.424Z",
"db_type": "self-hosted",
"db_origin": "config-file"
},
{
"ei": 2,
"event": "db.session.query",
"code": "TDB02I",
"time": "2024-06-26T14:22:29.414Z",
"db_query": "select 1;",
"success": true
},
{
"ei": 3,
"event": "db.session.result",
"code": "TDB10I",
"time": "2024-06-26T14:22:29.418Z",
"success": true,
"affected_records": 1
},
{
"ei": 4,
"event": "db.session.query",
"code": "TDB02I",
"time": "2024-06-26T14:22:33.42Z",
"db_query": "select * from event;",
"success": true
},
{
"ei": 5,
"event": "db.session.result",
"code": "TDB10I",
"time": "2024-06-26T14:22:33.423Z",
"success": true,
"affected_records": 11
},
{
"ei": 6,
"event": "db.session.query",
"code": "TDB02I",
"time": "2024-06-26T14:22:43.39Z",
"db_query": "select greet('hello');",
"success": true
},
{
"ei": 7,
"event": "db.session.result",
"code": "TDB10I",
"time": "2024-06-26T14:22:43.399Z",
"success": true,
"affected_records": 1
},
{
"ei": 8,
"event": "db.session.query",
"code": "TDB02I",
"time": "2024-06-26T14:22:48.237Z",
"db_query": "call greet_procedure('hello', '');",
"success": true
},
{
"ei": 9,
"event": "db.session.result",
"code": "TDB10I",
"time": "2024-06-26T14:22:48.245Z",
"success": true
},
{
"ei": 10,
"event": "db.session.query",
"code": "TDB02I",
"time": "2024-06-26T14:22:51.397Z",
"db_query": "call error_procedure();",
"success": true
},
{
"ei": 11,
"event": "db.session.result",
"code": "TDB10I",
"time": "2024-06-26T14:22:51.399Z",
"success": false,
"error": "ERROR: procedure error_procedure() does not exist (SQLSTATE 42883)"
},
{
"ei": 12,
"event": "db.session.query",
"code": "TDB02I",
"time": "2024-06-26T14:22:54.621Z",
"db_query": "select err;",
"success": true
},
{
"ei": 13,
"event": "db.session.result",
"code": "TDB10I",
"time": "2024-06-26T14:22:54.624Z",
"success": false,
"error": "ERROR: column \"err\" does not exist (SQLSTATE 42703)"
},
{
"ei": 14,
"event": "db.session.query",
"code": "TDB02I",
"time": "2024-06-26T14:23:01.589Z",
"db_query": "insert into event (name) values ('abc');",
"success": true
},
{
"ei": 15,
"event": "db.session.result",
"code": "TDB10I",
"time": "2024-06-26T14:23:01.61Z",
"success": true,
"affected_records": 1
},
{
"ei": 16,
"event": "db.session.query",
"code": "TDB02I",
"time": "2024-06-26T14:23:04.939Z",
"db_query": "insert into event (name) values ('abc'), ('123'), ('456');",
"success": true
},
{
"ei": 17,
"event": "db.session.result",
"code": "TDB10I",
"time": "2024-06-26T14:23:04.952Z",
"success": true,
"affected_records": 3
},
{
"ei": 18,
"event": "db.session.query",
"code": "TDB02I",
"time": "2024-06-26T14:23:11.071Z",
"db_query": "insert into event (banana) values ('abc');",
"success": true
},
{
"ei": 19,
"event": "db.session.result",
"code": "TDB10I",
"time": "2024-06-26T14:23:11.078Z",
"success": false,
"error": "ERROR: column \"banana\" of relation \"event\" does not exist (SQLSTATE 42703)"
},
{
"ei": 20,
"event": "db.session.end",
"code": "TDB01I",
"time": "2024-06-26T14:23:17.226Z",
},
{
"ei": 21,
"event": "db.session.user.deactivate",
"code": "TDB09I",
"time": "2024-06-26T14:23:17.262Z",
"success": true,
"username": "alice",
"delete": false
}
]
changelog: Add a new event to the database session recording with query/command result information.
Note: Now that we have a proper audit event for queries/command results, we might want to update MongoDB auth failure handling. This is outside the scope of this PR.