Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Hello everyone,
Can someone explain how QMC>Audit section works? I mean is it querying aganist to postgresql to get authorization infos?
If yes is it available to get that query?
We want to audit authorization user by user to see who is granted on which stream/data conn. etc. and export it to excel.
I just gathered an app, parsed rows from SystemRule table on QSR and able to get this info. but i want to know if there is a better way to do this and how it works :)?
Have a nice day!
@BTIZAG_OA wrote:Hello everyone,
Can someone explain how QMC>Audit section works? I mean is it querying aganist to postgresql to get authorization infos?
If yes is it available to get that query?
Not really. The PostgreSQL layer is used, but it's not going to be useful for your analysis. At the PostgreSQL layer, it'll just be a list of rules that are involved. Let's take an example rule
That's exactly what would be stored in PostgreSQL.
The audit performs an inventory of the assets (e.g. apps, streams, etc) and then evaluates all relevant rules for all selected users to see who could access the asset. This counter-factual analysis is not stored in the PostgreSQL layer and is done on demand when performing the audit.
As for something more programmatically, unfortunately I am not aware of anything ready made for this purpose. You can query the relevant QRS API endpoints, but in the interest of full disclosure they are complex.
I took a stab at building something a while ago and came up with this using Qlik-Cli-Windows (https://github.com/ahaydon/Qlik-Cli-Windows😞
$auditStreams = $true
$auditApps = $true
$auditDataConnections = $true
Connect-Qlik
# Get the Archived Logs folder
$rootFolder = (Get-QlikServiceCluster -full).settings.sharedPersistenceProperties.archivedLogsRootFolder
# Check for the store folder, create if needed
$storeDir = $rootFolder + '\qs-security-audit-csv'
if (!(Test-Path $storeDir)){
Set-Location $rootFolder
New-Item -path $storeDir -type directory | Out-Null
}
if ($auditStreams -eq $true){
$streamAuditBody = '{"resourceType":"Stream","resourceRef":{},"subjectRef":{"resourceFilter":""},"actions":2,"environmentAttributes":"context=AppAccess;","subjectProperties":["id","name","userId","userDirectory"],"auditLimit":100000,"outputObjectsPrivileges":4,"resourceProperties":["name"]}'
$streamAudit = Invoke-QlikPost -path /qrs/systemrule/security/audit/matrix -body $streamAuditBody
$streamAudit.matrix | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\streamsAudit.csv" -NoTypeInformation
$streams = Get-QlikStream
$streams | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\streams.csv" -NoTypeInformation
}
if ($auditApps-eq $true){
$appAuditBody = '{"resourceType":"App","resourceRef":{},"subjectRef":{"resourceFilter":""},"actions":2,"environmentAttributes":"context=AppAccess;","subjectProperties":["id","name","userId","userDirectory"],"auditLimit":100000,"outputObjectsPrivileges":4,"resourceProperties":["name"]}'
$appAudit = Invoke-QlikPost -path /qrs/systemrule/security/audit/matrix -body $appAuditBody
$appAudit.matrix | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\appsAudit.csv" -NoTypeInformation
$apps = Get-QlikApp
$apps | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\apps.csv" -NoTypeInformation
}
if ($auditDataConnections-eq $true){
$dataConnectionAuditBody = '{"resourceType":"DataConnection","resourceRef":{},"subjectRef":{"resourceFilter":""},"actions":2,"environmentAttributes":"context=AppAccess;","subjectProperties":["id","name","userId","userDirectory"],"auditLimit":100000,"outputObjectsPrivileges":4,"resourceProperties":["name"]}'
$dataConnectionAudit = Invoke-QlikPost -path /qrs/systemrule/security/audit/matrix -body $dataConnectionAuditBody
$dataConnectionAudit.matrix | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\dataConnectionsAudit.csv" -NoTypeInformation
$dataConnections = Get-QlikDataConnection
$dataConnections | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\dataConnections.csv" -NoTypeInformation
}
$user = Get-QlikUser
$user | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\users.csv" -NoTypeInformation
The action value of 2 is the action of read. It's on my to-do to make it more dynamic on the actions and load test it since doing this operation is expensive for the Repository Service.
@BTIZAG_OA wrote:Hello everyone,
Can someone explain how QMC>Audit section works? I mean is it querying aganist to postgresql to get authorization infos?
If yes is it available to get that query?
Not really. The PostgreSQL layer is used, but it's not going to be useful for your analysis. At the PostgreSQL layer, it'll just be a list of rules that are involved. Let's take an example rule
That's exactly what would be stored in PostgreSQL.
The audit performs an inventory of the assets (e.g. apps, streams, etc) and then evaluates all relevant rules for all selected users to see who could access the asset. This counter-factual analysis is not stored in the PostgreSQL layer and is done on demand when performing the audit.
As for something more programmatically, unfortunately I am not aware of anything ready made for this purpose. You can query the relevant QRS API endpoints, but in the interest of full disclosure they are complex.
I took a stab at building something a while ago and came up with this using Qlik-Cli-Windows (https://github.com/ahaydon/Qlik-Cli-Windows😞
$auditStreams = $true
$auditApps = $true
$auditDataConnections = $true
Connect-Qlik
# Get the Archived Logs folder
$rootFolder = (Get-QlikServiceCluster -full).settings.sharedPersistenceProperties.archivedLogsRootFolder
# Check for the store folder, create if needed
$storeDir = $rootFolder + '\qs-security-audit-csv'
if (!(Test-Path $storeDir)){
Set-Location $rootFolder
New-Item -path $storeDir -type directory | Out-Null
}
if ($auditStreams -eq $true){
$streamAuditBody = '{"resourceType":"Stream","resourceRef":{},"subjectRef":{"resourceFilter":""},"actions":2,"environmentAttributes":"context=AppAccess;","subjectProperties":["id","name","userId","userDirectory"],"auditLimit":100000,"outputObjectsPrivileges":4,"resourceProperties":["name"]}'
$streamAudit = Invoke-QlikPost -path /qrs/systemrule/security/audit/matrix -body $streamAuditBody
$streamAudit.matrix | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\streamsAudit.csv" -NoTypeInformation
$streams = Get-QlikStream
$streams | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\streams.csv" -NoTypeInformation
}
if ($auditApps-eq $true){
$appAuditBody = '{"resourceType":"App","resourceRef":{},"subjectRef":{"resourceFilter":""},"actions":2,"environmentAttributes":"context=AppAccess;","subjectProperties":["id","name","userId","userDirectory"],"auditLimit":100000,"outputObjectsPrivileges":4,"resourceProperties":["name"]}'
$appAudit = Invoke-QlikPost -path /qrs/systemrule/security/audit/matrix -body $appAuditBody
$appAudit.matrix | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\appsAudit.csv" -NoTypeInformation
$apps = Get-QlikApp
$apps | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\apps.csv" -NoTypeInformation
}
if ($auditDataConnections-eq $true){
$dataConnectionAuditBody = '{"resourceType":"DataConnection","resourceRef":{},"subjectRef":{"resourceFilter":""},"actions":2,"environmentAttributes":"context=AppAccess;","subjectProperties":["id","name","userId","userDirectory"],"auditLimit":100000,"outputObjectsPrivileges":4,"resourceProperties":["name"]}'
$dataConnectionAudit = Invoke-QlikPost -path /qrs/systemrule/security/audit/matrix -body $dataConnectionAuditBody
$dataConnectionAudit.matrix | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\dataConnectionsAudit.csv" -NoTypeInformation
$dataConnections = Get-QlikDataConnection
$dataConnections | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\dataConnections.csv" -NoTypeInformation
}
$user = Get-QlikUser
$user | Export-Csv -path "$($rootFolder)\qs-security-audit-csv\users.csv" -NoTypeInformation
The action value of 2 is the action of read. It's on my to-do to make it more dynamic on the actions and load test it since doing this operation is expensive for the Repository Service.