Query audit logs over REST
Query and read operations on the /audit API endpoint are deprecated and will be removed in a future release of IDM. Use the JSON audit event handler or similar to export your data to a third-party audit framework, such as Elastic Stack.
|
Regardless of where audit events are stored, they are accessible over REST on the /audit
endpoint. The following sections describe how to query audit logs over REST.
Queries on the audit endpoint must use queryFilter syntax. If you get no REST output on the correct endpoint, the corresponding audit file or JDBC table may not have audit data. Some examples in this section use client-assigned IDs (such as |
Query the Reconciliation Audit Log
With the default audit configuration, reconciliation operations are not audited. To enable reconciliation logging, add recon
to the list of audit topics for your event handler in conf/audit.json
. For example:
"eventHandlers" : [
{
"class" : "org.forgerock.audit.handlers.json.JsonAuditEventHandler",
"config" : {
"name" : "json",
"logDirectory" : "&{idm.data.dir}/audit",
"buffering" : {
"maxSize" : 100000,
"writeInterval" : "100 millis"
},
"topics" : [
"access",
"activity",
"recon",
"sync",
"authentication",
"config"
]
}
},
{
"class": "org.forgerock.openidm.audit.impl.RepositoryAuditEventHandler",
"config": {
"name": "repo",
"enabled": true,
"topics": [
"access",
"activity",
"recon",
"sync",
"authentication",
"config"
]
}
}
],
When enabled, the above example logs reconciliation operations in the file /path/to/openidm/audit/recon.audit.json
, and in the repository. You can read and query the reconciliation audit logs over the REST interface, as outlined in the following examples.
To return all reconciliation operations logged in the audit log, query the audit/recon
endpoint, as follows:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/audit/recon?_queryFilter=true"
The following code extract shows the reconciliation audit log after the first reconciliation operation in the sync-with-csv
sample. The output has been truncated for legibility.
{
"result": [
{
"_id": "49bdb7cb-79a4-429d-856d-a7154005e41a-182",
"transactionId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177",
"timestamp": "2017-02-28T13:07:20.487Z",
"eventName": "recon",
"userId": "openidm-admin",
"exception": null,
"linkQualifier": null,
"mapping": "systemCsvfileAccounts_managedUser",
"message": "Reconciliation initiated by openidm-admin",
"sourceObjectId": null,
"targetObjectId": null,
"reconciling": null,
"ambiguousTargetObjectIds": null,
"reconAction": "recon",
"entryType": "start",
"reconId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177"
},
{
"_id": "49bdb7cb-79a4-429d-856d-a7154005e41a-192",
"transactionId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177",
"timestamp": "2017-02-28T13:07:20.934Z",
"eventName": "recon",
"userId": "openidm-admin",
"action": "CREATE",
"exception": null,
"linkQualifier": "default",
"mapping": "systemCsvfileAccounts_managedUser",
"message": null,
"situation": "ABSENT",
"sourceObjectId": "system/csvfile/account/scarter",
"status": "SUCCESS",
"targetObjectId": "managed/user/scarter",
"reconciling": "source",
"ambiguousTargetObjectIds": "",
"entryType": "entry",
"reconId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177"
},
...
}
Most of the fields in the reconciliation audit log are self-explanatory. Each distinct reconciliation operation is identified by its reconId
. Each entry in the log is identified by a unique _id
. The first log entry indicates the status for the complete reconciliation operation. Successive entries indicate the status for each entry affected by the reconciliation.
To obtain information about a specific log entry, include its entry _id
in the URL. For example:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/audit/recon/414a4921-5d9d-4398-bf86-7d5312a9f5d1-146"
The following sample output shows the results of a read operation on a specific reconciliation audit entry. The entry shows the creation of scarter’s account in the managed user repository, as the result of a reconciliation operation.
{
"_id": "49bdb7cb-79a4-429d-856d-a7154005e41a-192",
"transactionId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177",
"timestamp": "2017-02-28T13:07:20.934Z",
"eventName": "recon",
"userId": "openidm-admin",
"action": "CREATE",
"exception": null,
"linkQualifier": "default",
"mapping": "systemCsvfileAccounts_managedUser",
"message": null,
"situation": "ABSENT",
"sourceObjectId": "system/csvfile/account/scarter",
"status": "SUCCESS",
"targetObjectId": "managed/user/scarter",
"reconciling": "source",
"ambiguousTargetObjectIds": "",
"entryType": "entry",
"reconId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177"
}
To obtain information for a specific reconciliation operation, include the reconId
in the query. You can filter the log so that the query returns only the fields you want to see, by adding the _fields
parameter.
The following query returns the mapping
, timestamp
, and entryType
fields for a specific reconciliation operation:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'http://localhost:8080/openidm/audit/recon?_queryFilter=/reconId+eq+"4261227f-1d44-4042-ba7e-1dcbc6ac96b8"&_fields=mapping,timestamp,entryType' { "result": [ { "_id": "49bdb7cb-79a4-429d-856d-a7154005e41a-182", "mapping": "systemCsvfileAccounts_managedUser", "timestamp": "2017-02-28T13:07:20.487Z", "entryType": "start" }, { "_id": "49bdb7cb-79a4-429d-856d-a7154005e41a-192", "mapping": "systemCsvfileAccounts_managedUser", "timestamp": "2017-02-28T13:07:20.934Z", "entryType": "entry" }, { "_id": "49bdb7cb-79a4-429d-856d-a7154005e41a-191", "mapping": "systemCsvfileAccounts_managedUser", "timestamp": "2017-02-28T13:07:20.934Z", "entryType": "entry" }, { "_id": "49bdb7cb-79a4-429d-856d-a7154005e41a-193", "mapping": "systemCsvfileAccounts_managedUser", "timestamp": "2017-02-28T13:07:20.943Z", "entryType": "summary" } ], ... }
To query the reconciliation audit log for a particular reconciliation situation, include the reconId
and the situation
in the query. For example, the following query returns all ABSENT entries that were found during the specified reconciliation operation:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'http://localhost:8080/openidm/audit/recon?_queryFilter=/reconId+eq+"414a4921-5d9d-4398-bf86-7d5312a9f5d1-135"and+situation+eq"ABSENT"' { "result": [ { "_id": "49bdb7cb-79a4-429d-856d-a7154005e41a-192", "situation": "ABSENT", "reconId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177", "transactionId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177", "timestamp": "2017-02-28T13:07:20.934Z", "eventName": "recon", "userId": "openidm-admin", "action": "CREATE", "exception": null, "linkQualifier": "default", "mapping": "systemCsvfileAccounts_managedUser", "message": null, "sourceObjectId": "system/csvfile/account/scarter", "status": "SUCCESS", "targetObjectId": "managed/user/scarter", "reconciling": "source", "ambiguousTargetObjectIds": "", "entryType": "entry" }, { "_id": "49bdb7cb-79a4-429d-856d-a7154005e41a-191", "situation": "ABSENT", "reconId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177", "transactionId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177", "timestamp": "2017-02-28T13:07:20.934Z", "eventName": "recon", "userId": "openidm-admin", "action": "CREATE", "exception": null, "linkQualifier": "default", "mapping": "systemCsvfileAccounts_managedUser", "message": null, "sourceObjectId": "system/csvfile/account/bjensen", "status": "SUCCESS", "targetObjectId": "managed/user/bjensen", "reconciling": "source", "ambiguousTargetObjectIds": "", "entryType": "entry" } ], ... }
Query the Activity Audit Log
The activity logs track all operations on internal (managed) and external (system) objects. Entries in the activity log contain identifiers for the reconciliation or synchronization action that triggered an activity, and for the original caller and the relationships between related actions.
You can access the activity logs over REST with the following call:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/audit/activity?_queryFilter=true"
The following excerpt of the activity log shows the entries that created user scarter
, with ID 42f8a60e-2019-4110-a10d-7231c3578e2b
:
{
"result": [
{
"_id": "49bdb7cb-79a4-429d-856d-a7154005e41a-190",
"transactionId": "49bdb7cb-79a4-429d-856d-a7154005e41a-177",
"timestamp": "2017-02-28T13:07:20.894Z",
"eventName": "activity",
"userId": "openidm-admin",
"runAs": "openidm-admin",
"operation": "CREATE",
"before": null,
"after": {
"mail": "scarter@example.com",
"givenName": "Steven",
"sn": "Carter",
"description": "Created By CSV",
"userName": "scarter",
"password": {
"$crypto": {
"type": "x-simple-encryption",
"value": {
"cipher": "AES/CBC/PKCS5Padding",
"salt": "tdrE2LZ+nBAnE44QY1UrCA==",
"data": "P/z+OXA1x35aVWMRbOHMUQ==",
"iv": "GACI5q4qZUWZRHzIle57TQ==",
"key": "openidm-sym-default",
"mac": "hqLmhjv67dxcmX8L3xxgZg=="
}
}
},
"telephoneNumber": "1234567",
"accountStatus": "active",
"effectiveRoles": [],
"effectiveAssignments": [],
"_rev": "00000000dc6160c8",
"_id": "42f8a60e-2019-4110-a10d-7231c3578e2b"
},
"changedFields": [],
"revision": "00000000bad8e88e",
"message": "create",
"objectId": "managed/user/42f8a60e-2019-4110-a10d-7231c3578e2b",
"passwordChanged": true,
"status": "SUCCESS"
},
...
}
To return the activity information for a specific action, include the _id
of the action in the URL, for example:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'http://localhost:8080/openidm/audit/activity/414a4921-5d9d-4398-bf86-7d5312a9f5d1-145'
Each action in the activity log has a transactionId
that is the same as the transactionId
that was assigned to the incoming or initiating request. So, for example, if an HTTP request invokes a script that changes a user’s password, the HTTP request is assigned a transactionId
. The action taken by the script is assigned the same transactionId
, which enables you to track the complete set of changes resulting from a single action. You can query the activity log for all actions that resulted from a specific transaction, by including the transactionId
in the query.
The following command returns all actions in the activity log that occurred as a result of the reconciliation with the specified transactionId
. The query results are restricted to only the objectId
and the resourceOperation
. You can see from the output that the reconciliation with this transactionId
resulted in two CREATEs and two UPDATEs in the managed repository:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'http://localhost:8080/openidm/audit/activity?_queryFilter=/transactionId+eq+"414a4921-5d9d-4398-bf86-7d5312a9f5d1-135"&_fields=objectId,operation'
The following sample output shows the result of a query that created users scarter (with ID 42f8a60e-2019-4110-a10d-7231c3578e2b
) and bjensen (with ID 9dce06d4-2fc1-4830-a92b-bd35c2f6bcbb
).
{
"result" : [ {
"_id" : "414a4921-5d9d-4398-bf86-7d5312a9f5d1-144",
"objectId" : "managed/user/42f8a60e-2019-4110-a10d-7231c3578e2b",
"operation" : "CREATE"
}, {
"_id" : "414a4921-5d9d-4398-bf86-7d5312a9f5d1-145",
"objectId" : "managed/user/9dce06d4-2fc1-4830-a92b-bd35c2f6bcbb",
"operation" : "CREATE"
} ],
"resultCount" : 2,
"pagedResultsCookie" : null,
"totalPagedResultsPolicy" : "NONE",
"totalPagedResults" : -1,
"remainingPagedResults" : -1
}
Query the Synchronization Audit Log
LiveSync and implicit sync operations are logged in the file /path/to/openidm/audit/sync.audit.json
and in the repository. You can read the synchronization audit logs over the REST interface, as outlined in the following examples.
To return all operations logged in the synchronization audit log, query the audit/sync
endpoint, as follows:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/audit/sync?_queryFilter=true" { "result" : [ { "_id" : "53709f21-5b83-4ea0-ac35-9af39c3090cf-95", "transactionId" : "53709f21-5b83-4ea0-ac35-9af39c3090cf-85", "timestamp" : "2015-11-23T05:07:39.376Z", "eventName" : "sync", "userId" : "openidm-admin", "action" : "UPDATE", "exception" : null, "linkQualifier" : "default", "mapping" : "managedUser_systemLdapAccounts", "message" : null, "situation" : "CONFIRMED", "sourceObjectId" : "managed/user/128e0e85-5a07-4e72-bfc8-4d9500a027ce", "status" : "SUCCESS", "targetObjectId" : "uid=jdoe,ou=People,dc=example,dc=com" }, { ...
Most of the fields in the synchronization audit log are self-explanatory. Each entry in the log synchronization operation is identified by a unique id
. Each _synchronization operation is identified with a transactionId
. The same base transactionId
is assigned to the incoming or initiating request — so if a modification to a user entry triggers an implicit synchronization operation, both the sync operation and the original change operation have the same transactionId
. You can query the sync log for all actions that resulted from a specific transaction, by including the transactionId
in the query.
To obtain information on a specific sync audit log entry, include its entry _id
in the URL. For example:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/audit/sync/53709f21-5b83-4ea0-ac35-9af39c3090cf-95" { "_id" : "53709f21-5b83-4ea0-ac35-9af39c3090cf-95", "transactionId" : "53709f21-5b83-4ea0-ac35-9af39c3090cf-85", "timestamp" : "2015-11-23T05:07:39.376Z", "eventName" : "sync", "userId" : "openidm-admin", "action" : "UPDATE", "exception" : null, "linkQualifier" : "default", "mapping" : "managedUser_systemLdapAccounts", "message" : null, "situation" : "CONFIRMED", "sourceObjectId" : "managed/user/128e0e85-5a07-4e72-bfc8-4d9500a027ce", "status" : "SUCCESS", "targetObjectId" : "uid=jdoe,ou=People,dc=example,dc=com" }
Query the Authentication Audit Log
The authentication log includes details of all successful and failed authentication attempts. The output could be long. The following example is one record from hundreds of entries. To get the complete audit log over REST, use the following query:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/audit/authentication?_queryFilter=true" ... { "_id": "0cf07194-d4d8-4146-8445-87c0a97821de-552", "timestamp": "2025-01-10T21:12:18.506Z", "eventName": "SESSION", "transactionId": "0cf07194-d4d8-4146-8445-87c0a97821de-549", "trackingIds": [ "2929d3a9-cfce-4d68-8e25-7ad5fdab2d15", "d39a005c-6ece-4649-a9f8-989a40d11f69" ], "userId": "openidm-admin", "principal": [ "openidm-admin" ], "entries": [ { "moduleId": "JwtSession", "result": "SUCCESSFUL", "info": { "org.forgerock.authentication.principal": "openidm-admin" } } ], "result": "SUCCESSFUL", "provider": null, "method": "JwtSession" } ...
The output depicts a successful login of the openidm-admin
user. From the information shown, you can derive the following information:
-
The
userId
, also known as the authenticationprincipal
, isopenidm-admin
. In the REST call that follows, you’ll refer to how to use this information to filter authentication attempts made by that specific user. -
The login used the
JwtSession
session module. Learn more in Authentication and session modules.
Login failures can also be instructive, as you’ll refer to consecutive moduleId
modules that correspond to the order of modules shown in your project’s authentication.json
file.
You can filter the results to return only those audit entries you’re interested in. For example, the following query returns all authentication attempts made by a specific user (openidm-admin
) but displays only the security context and the result of the authentication attempt:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'http://localhost:8080/openidm/audit/authentication?_queryFilter=/principal+eq+"johndoe"&_fields=context,result' { "result": [ { "_id": "c736f1c8-b522-4d18-83d2-9058e3288e3b-632", "result": "SUCCESSFUL" }, { "_id": "c736f1c8-b522-4d18-83d2-9058e3288e3b-638", "result": "SUCCESSFUL" }, ... ], ... }
Query the Configuration Audit Log
This audit log lists changes made to the configuration in the audited server. You can read through the changes in the config.extension
file in the openidm/audit
directory.
You can also read the complete audit log over REST with the following query:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/audit/config?_queryFilter=true" { "result" : [ { "_id" : "414a4921-5d9d-4398-bf86-7d5312a9f5d1-73", "operation" : "CREATE", "userId" : "openidm-admin", "runAs" : "openidm-admin", "transactionId" : "414a4921-5d9d-4398-bf86-7d5312a9f5d1-58", "revision" : null, "timestamp" : "2015-11-23T00:18:17.808Z", "objectId" : "ui", "eventName" : "CONFIG", "before" : "", "after" : "{ \"icons\": ... } ], "resultCount" : 3, "pagedResultsCookie" : null, "totalPagedResultsPolicy" : "NONE", "totalPagedResults" : -1, "remainingPagedResults" : -1 }
The output includes before
and after
entries, which represent the changes made to the configuration files.