Auditlogboekregistratie voor Microsoft Entra ID principals in Azure Database for PostgreSQL flexibele server

Databasecontroles zijn een belangrijk onderdeel van de nalevingsvereisten van uw organisatie. Door gerichte activiteiten te bewaken, kunt u uw beveiligingsbasislijn bereiken. In azure Database for PostgreSQL flexibele server kunt u controles instellen met behulp van de pgaudit PG-extensie, zoals beschreven in Auditlogboekregistratie in Azure Database for PostgreSQL.

Een uitdaging is het gebruik van de controlefunctie naast Microsoft Entra ID-verificatie wanneer u Microsoft Entra-id-groepen gebruikt en de acties van afzonderlijke groepsleden wilt controleren. Deze uitdaging bestaat omdat groepsleden zich aanmelden met behulp van hun persoonlijke toegangstokens, maar de groepsnaam als gebruikersnaam gebruiken.

Kusto Query Language (KQL) is een krachtige pijplijngestuurde, alleen-lezen querytaal waarmee query's in Azure-servicelogboeken kunnen worden uitgevoerd. KQL biedt ondersteuning voor het uitvoeren van query's op Azure-logboeken om snel een groot aantal gegevens te analyseren. Gebruik voor dit artikel KQL om query's uit te voeren op Azure Postgres-logboeken en gebruikersgegevens van Microsoft Entra ID uit auditlogboeken te extraheren.

Vereiste voorwaarden

  1. Auditlogboekregistratie inschakelen - Auditlogboekregistratie in Azure Database for PostgreSQL
  2. Instellen dat de Azure Postgres-logboeken worden verzonden naar Azure Log Analytics - Logboeken configureren en raadplegen
  3. Pas de parameter log_line_prefix aan: Stel in de blade Parameters log_line_prefix zo in dat deze de escapetekens user=%u,db=%d,session=%c,sess_time=%s in dezelfde volgorde bevat om de gewenste resultaten te krijgen.
    • Voordat: log_line_prefix = %t-%c-
    • Na: log_line_prefix = %t-%c-user=%u,db=%d,session=%c,sess_time=%s

Kusto-query

De volgende Kusto-query bevraagt de AzureDiagnostics twee keer.
De eerste subquery vindt alle regels die de tekenreeks Microsoft Entra ID connection authorized bevatten en extraheert de PrincipalName samen met de SessionId uit deze logregels.
Met de tweede subquery worden alle auditlogboeken gevonden.
Ten slotte worden deze twee subquery's toegevoegd aan de SessionId.

let lookbackTime = ago(3d);
let opindex = 3;
let startIndex = toscalar(range thirdIndex from opindex to opindex step 1
    | project thirdIndex);
AzureDiagnostics
| where ResourceProvider == 'MICROSOFT.DBFORPOSTGRESQL'
| where TimeGenerated >= lookbackTime
| where Message contains 'Microsoft Entra ID connection authorized'
| extend SessionId = tostring(split(tostring(split(Message, 'session=')[-1]), ',sess_time')[-2])
| extend UPN = iff(Message contains 'UPN',tostring(split(tostring(split(Message, 'UPN=')[-1]), 'oid=')[-2]), '')
| extend appId = iff(Message contains 'appid', tostring(split(tostring(split(Message, 'appid=')[-1]), 'oid=')[-2]), '')
| extend PrincipalName = strcat(UPN, appId)
| project SessionId, PrincipalName
| join kind=leftouter
    (
    AzureDiagnostics
    | where ResourceProvider == 'MICROSOFT.DBFORPOSTGRESQL'
    | where TimeGenerated >= lookbackTime
    | where Message contains 'AUDIT: SESSION'
    | extend RoleName = tostring(split(tostring(split(Message, 'user=')[-1]), ',db')[-2])
    | where RoleName !in ('azuresu', '[unknown]', 'postgres', '')
    | extend SessionId = tostring(split(tostring(split(Message, 'session=')[-1]), ',sess_time')[-2])
    | extend SubMessage = tostring(split(Message, 'SESSION,')[-1])
    | extend splitArray = split(SubMessage, ',')
    | extend SqlQueryP1 = tostring(split(tostring(split(Message, ',,,')[-1]), ',<')[-2])
    | extend SqlQueryP2 = replace_string(tostring(split(SqlQueryP1, ',\"')[-1]), '"', '')
    | extend SqlQueryP3 = tostring(split(Message, ',,,')[1])
    | extend OperationType = tostring(splitArray[startIndex])
    | extend SqlQuery = trim('"', case(OperationType == 'EXECUTE', SqlQueryP2, SqlQueryP1 == '', SqlQueryP3, SqlQueryP1))
    )
    on $left.SessionId == $right.SessionId
| project TimeGenerated, PrincipalName, RoleName, OperationType, SqlQuery

Voorbeeld van resultaten

De resulterende tabel ziet er als volgt uit:

TijdstipGenereerd Primaire naam RolNaam Type operatie SqlQuery
2025-12-12T16:25:05.104Z user@example.com ExampleGroupName SELECT select * from pg_seclabels;
2025-12-12T16:25:04.000Z user@example.com user@example.com SELECT select * from pg_seclabels;

Als de gebruiker zich aanmeldt als een groepsrol, geven de PrincipalName en RoleName kolommen verschillende waarden weer, zoals in de eerste rij van het voorbeeld.
De PrincipalName waarde identificeert de gebruiker die zich heeft aangemeld. De RoleName waarde identificeert de rol in PostgreSQL waartoe de gebruiker toegang heeft nadat deze zich heeft aangemeld.

PrincipalName is de UPN (User Principal Name) ofwel AppId, afhankelijk van of de gebruikers-principal of service-principal zich aanmeldt.