Skip to content

Feat/admin audit server apps - #65542

Open
GhassenKefi wants to merge 20 commits into
masterfrom
feat/admin-audit-server-apps
Open

GhassenKefi wants to merge 20 commits into
masterfrom
feat/admin-audit-server-apps

Conversation

@GhassenKefi

@GhassenKefi GhassenKefi commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor
  • Resolves: #

Summary

Add audit log entries for actions in The following apps, either by sending CriticalActionPerformedEvent from the app or by having admin_audit listen to existing events.

App Lists :

  • files
  • files_sharing (restore, link changes, remote shares)
  • federatedfilesharing (existing entries updated, plus revoke)
  • cloud_federation_api
  • files_external
  • encryption
  • federation (trusted server added, shared secret exchanged)
  • dav (calendar export, federated calendars, direct links, birthday calendars)
  • settings
  • provisioning_api
  • oauth2
  • twofactor_backupcodes
  • user_ldap
  • workflowengine
  • webhook_listeners
  • theming
  • updatenotification
  • appstore
  • systemtags (in core SystemTagManager: who may assign a tag)

TODO

  • ...

Checklist

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

admin_audit now listens to core events that were dispatched but not
audited:

- SubAdminAddedEvent / SubAdminRemovedEvent (groups.subadmin.*)
- GroupChangedEvent for display name changes
- TwoFactorProviderForUserRegistered / Unregistered
  (auth.twofactor_provider.*)
- UserChangedEvent for display name, quota and managers

Display name values are not logged, only the fact that they changed.

Password changes are now logged for every user backend, not only the
database backend, so LDAP password renewals and admin resets of LDAP
passwords are audited too. The backend is added as a parameter.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
…nments

Updating and deleting system tags is now audited through the existing
TagUpdatedEvent and TagDeletedEvent. Changing the groups that may
assign a restricted tag dispatches no event, so SystemTagManager
dispatches a CriticalActionPerformedEvent there.

Assigning and unassigning is only logged for restricted and invisible
tags, as those are the ones access control and retention rules rely
on. Ordinary user tags are not logged. Each entry carries the number
of objects and at most ten object IDs, so bulk assignments stay a
single short entry.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Requesting, accepting and rejecting an ownership transfer, and the
transfer itself, are now written to the audit log. The transfer entry
is dispatched by OwnershipTransferService, so it covers the background
job and occ files:transfer-ownership. Rejecting by dismissing the
notification is logged as well.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
- Accepting a share and leaving it are logged through the existing
  ShareAcceptedEvent and ShareDeletedFromSelfEvent.
- Restoring a deleted share is logged by DeletedShareAPIController.
- Share20\Manager::updateShare logs changes to the download restriction
  and share attributes, and a changed link token. The token itself is
  never logged.
- Accepting, declining and removing an incoming federated share is
  logged by the external share manager.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
…dit entries

The existing audit entries of the legacy OCS endpoints now carry an
operation (federatedfilesharing.share.*) and named parameters, with the
messages unchanged. Revoking a reshare is logged as well.

Shares and notifications arriving through the generic OCM endpoints
are logged by cloud_federation_api, so nothing is logged twice.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
…ations

Shares and notifications received on the OCM endpoints are now audited
for every resource type (files, calendars, Talk, ...), after the
provider has accepted them. The shared secret of a notification is not
logged.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Creating, updating and deleting external storages is now audited in
StoragesService, so admin and personal storages are covered for the web
UI and occ. Saving global or per-user credentials is logged by the
controllers. Backend options and credentials are never logged.

The existing Storage*Event classes are not public API and turn a mount
point change into a delete and a create, so they are not used for this.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Enabling and disabling the recovery key, changing its password,
changing a user's recovery setting, recovering a user's files,
regenerating a user's keys after an admin password reset, changing the
private key password and toggling home storage encryption are now
audited. Passwords and keys are never logged.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Adding a trusted server and exchanging a shared secret with it are now
audited. Removing a trusted server is logged through the existing
TrustedServerRemovedEvent. The shared secret is never logged.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
admin_audit now listens to the dav calendar and address book events:
creation, trashing, deletion, restore, publishing and share changes.
The public link of a published calendar is not logged.

Calendar export, accepting and declining federated calendars, creating
direct download links and enabling or disabling birthday calendars are
logged by dav itself. Direct link tokens are never logged.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Audit entries are added for app password creation, deletion and scope
changes, remote wipe requests, WebAuthn devices, two-factor
enforcement, mail server settings and credentials, admin delegation,
presets, declarative settings and log file downloads.

The existing AI settings entry keeps its message and now carries an
operation (settings.ai.updated) and named parameters.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
…ounts

Setting and deleting app config values through the API is now audited,
with the app and key only, since app config can hold secrets. Remote
wipe of a user's devices, resending the welcome email and edits of
another user's account are logged too. For account edits only the
field name is logged, and fields already audited by core are skipped.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
ClientService now audits adding and removing OAuth2 clients, which
covers the admin settings and occ. The client secret is never logged.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Generating backup codes, which replaces any previous codes, is now
audited. The codes are never logged.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Creating, updating, copying and deleting LDAP configurations through
the API, revealing the bind password and clearing user or group
mappings are now audited. For updates only the names of the changed
keys are logged, never their values.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Creating, updating and deleting flow rules is now audited in the
manager, for both admin and user scope. Check values are not logged.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Creating, updating and deleting webhooks is now audited. Only the
origin of the target URI is logged, since webhook URIs often contain
secrets in their path or query. Headers and auth data are never logged.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Changing, resetting and uploading theming settings and images through
the web UI is now audited. Only the setting name is logged.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Changing the update channel and creating a web updater token are now
audited. The token is never logged.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
Removing an app from the app store is now audited, next to the
existing enable, disable and update entries.

Refs nextcloud-gmbh/governance#221

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ghassen kefi <ghassen.kefi.dev@gmail.com>
@GhassenKefi
GhassenKefi force-pushed the feat/admin-audit-server-apps branch from f685ce8 to aee3d38 Compare October 16, 2026 11:28
@SebastianKrupinski

Copy link
Copy Markdown
Contributor

Question...

What happens when one of these apps is disabled? files_external or files_sharing for instance...

Since the classes are unavailable when the app is disabled does this not crash the system?

@susnux

susnux commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Since the classes are unavailable when the app is disabled does this not crash the system?

Listeners are registered by class string so its not a problem if the class does not exist, as the listener will just never be called

@SebastianKrupinski

Copy link
Copy Markdown
Contributor

Listeners are registered by class string so its not a problem if the class does not exist, as the listener will just never be called

That works then

On a side note I think this approache is unsatainable... I think each app/module should implement its own auditing... like the NC logger... (full transparancy this might already exist I just haven't looked in to it)

@susnux

susnux commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

On a side note I think this approache is unsatainable... I think each app/module should implement its own auditing... like the NC logger... (full transparancy this might already exist I just haven't looked in to it)

Yes I agree! @GhassenKefi apps should, as discussed, use the CriticalActionPerformedEvent.
The listeners in admin_audit app are only for actions that are not bound to an app like file system events or activity.
Basically everything that is done in OCP / OC / the lib (and maybe core) is fine as a listener in admin_audit.

All other app related logging should be done with CriticalActionPerformedEvent directly by that app.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants