Admin audit log
The admin_audit app records security and compliance relevant actions, for example logins, file access, sharing, and user and group management. It answers the question who did what, and when. The audit log is kept separate from the regular Nextcloud log, which is meant for debugging and system status.
Apps other than the ones shipped with Nextcloud can write to the audit log too. Which actions are recorded therefore depends on the apps installed on your server.
This page describes how to read and maintain the audit log. To enable and configure it, see Admin audit log configuration.
Viewing the audit log
The logreader app (Administration settings → Logging) only shows the regular Nextcloud log. To show audit entries there as well, see Admin audit log configuration.
For most purposes, read the audit log with command line tools, or forward it to a log management or SIEM system. Each
entry is a single line of JSON, so it can be filtered with a tool such as jq.
Show all groups that were deleted:
jq -c 'select(.data.operation == "groups.group.deleted")' /var/www/html/data/audit.log
List time, action and message of everything the user alice did:
jq -r 'select(.user == "alice") | [.time, .data.operation, .message] | @tsv' /var/www/html/data/audit.log
Follow the actions of a single request:
jq -c 'select(.reqId == "eB2rT9vXqN4kLm8sP0aZ")' /var/www/html/data/audit.log
Record format
With the file backend, the audit log is a JSON Lines file: every line is one
complete JSON object describing one action. The syslog and systemd backends write the same JSON object as the
message. The errorlog backend prefixes it with [<tag>][admin_audit][1].
Example entry, written when the administrator alice created the group marketing (formatted for readability):
{
"reqId": "eB2rT9vXqN4kLm8sP0aZ",
"level": 1,
"time": "2026-10-12T14:26:05+00:00",
"remoteAddr": "192.0.2.10",
"user": "alice",
"userDisplayName": "Alice Auditor",
"app": "admin_audit",
"method": "POST",
"url": "/ocs/v2.php/cloud/groups",
"scriptName": "/ocs/v2.php",
"message": "Group created: \"marketing\"",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0",
"version": "36.0.0.0",
"data": {
"app": "admin_audit",
"operation": "groups.group.created",
"params": {
"group": "marketing"
}
}
}
Example entry for an action performed with occ:
{
"reqId": "EVhhZeg6hZ6mT7oEwtM3",
"level": 1,
"time": "2026-10-12T14:31:17+00:00",
"remoteAddr": "",
"user": "--",
"app": "admin_audit",
"method": "",
"url": "--",
"scriptName": "occ",
"message": "App \"files_external\" enabled",
"userAgent": "--",
"version": "36.0.0.0",
"occ_command": ["occ", "app:enable"],
"data": {
"app": "admin_audit",
"operation": "apps.app.enabled",
"params": {
"app": "files_external"
}
}
}
Field reference
Empty values are written as two dashes: --. Fields marked as optional are left out when they do not apply.
reqIdRequest ID. All entries written during the same request share this value, also across the audit log and the regular Nextcloud log.
levelLog level. Always
1(INFO) for audited actions.timeDate and time of the entry. The format and time zone are set with
logdateformatandlogtimezoneinconfig/config.php. Defaults to ISO 8601 in UTC.remoteAddrIP address of the client. Empty for
occcommands and background jobs.userID of the user who performed the action, or
--when no user is logged in, for example forocccommands, background jobs and failed logins.userDisplayNameOptional. Display name of the acting user at the time the entry was written. Left out when
useris--.appAlways
admin_auditin the audit log.methodHTTP method, for example
GET,POSTorPROPFIND. Empty forocccommands.urlRequest path.
--forocccommands.scriptNamePHP script that handled the request, for example
/remote.phporocc.messageHuman readable description of the action. See Message and structured data.
userAgentUser agent of the client.
--forocccommands.versionNextcloud version at the time of the entry.
clientReqIdOptional. Value of the
X-Request-IdHTTP header sent by the client.occ_commandOptional. The
occcommand that was run, as an array of up to two arguments. Only present for actions performed on the command line.data.appAlways
admin_audit.data.operationOptional. Stable identifier of the action. See Operation identifiers.
data.paramsOptional. The parameters of the action as a JSON object, for example the affected user, group, file path or share ID. Left out when the action has no parameters or when the parameters are marked as sensitive.
Message and structured data
Every entry describes the action twice:
messageis an English sentence with the parameters inserted, meant to be read by people. Its wording can change between Nextcloud versions.data.operationanddata.paramsdescribe the same action in a machine readable form.
When you filter, count, or alert on audit entries, use data.operation and data.params instead of parsing
message.
The keys of data.params are the parameter names of the action, for example group, user, path or
id. The values are strings, numbers, booleans or null. Dates are written as strings in the format
YYYY-MM-DD HH:MM:SS.
Operation identifiers
data.operation identifies the type of action in the form <app>.<entity>.<action>, for example
files.file.deleted, sharing.share.created or auth.login.failed. The identifier does not change when the
wording of message changes, so it is safe to use it in filters, alert rules and retention policies.
Apps that write to the audit log can define their own identifiers in the same form. Entries written by apps that do
not provide an identifier have no data.operation field.
Log rotation
A background job checks the size of the audit log file every three hours. When the file is larger than
log_rotate_size (see Logging), it is renamed by appending .1
and a new file is started. An existing .1 file is overwritten, so only one rotated file is kept.
This background job only rotates the default audit.log and a file set with the legacy app setting. A file set
with logfile_audit is not rotated by Nextcloud. Use a tool such as logrotate for such files, and whenever you
need to keep audit entries for a defined period.
Known limitations
Coverage depends on the apps. Only actions that an app explicitly reports are recorded. Actions in apps that do not report to the audit log are not recorded at all.
No retention management. Nextcloud keeps at most one rotated file, and does not rotate a file set with
logfile_audit. Configurelogrotate, or forward the entries to a central log system, when you need to keep audit entries for a defined period.No viewer in the web interface. The audit log is only shown in Administration settings → Logging when it is written to the same file as the regular Nextcloud log.
No protection against tampering. The audit log is a plain file that the web server user can write to. To make sure entries cannot be changed after the fact, forward them to a separate system, for example with
log_type_auditset tosyslogand a remote syslog server.Display names can change.
userDisplayNameis the display name at the time of the entry. Useuserto correlate entries of the same account.Entries depend on the log level. If the system log level is above INFO and no
log.conditionis set for admin_audit, nothing is written. See Admin audit log configuration.