Журнал аудита¶
Чтение журнала аудита админки: записи о действиях, выполненных через API, с указанием кто, когда, с какого IP и над чем их совершил. Поскольку Admin Next делает всё через API, журнал охватывает весь Admin Next плюс любые клиенты с ключами API. Действия, выполненные в классической админке в обход API, не записываются.
По умолчанию журнал выключен. Включите его через plugins.api.audit.enabled; для этого нужно расширение PHP pdo_sqlite. plugins.api.audit.coverage задаёт уровень детализации (standard или detailed, чтобы также сохранять значения полей до и после для правок страниц), retention_days и retention_max_rows ограничивают объём хранения, а anonymize_ip маскирует последнюю часть сохранённых IP.
Разрешения: каждый маршрут требует суперадминистратора с api.super. Учётная запись, имеющая только admin.super, получает отказ, а ключу API с ограниченной областью действия нужна область admin.super — так же, как для любого другого эндпоинта только для суперадминистратора. Демо-учётные записи получают 403 с сообщением «The audit trail is hidden in demo mode.», так как на публичном демо журнал содержит IP и user agent других посетителей.
За исключением Состояния аудита, маршруты возвращают 404, пока журнал выключен, и 503, когда отсутствует SQLite.
Фильтры¶
Список событий аудита и Экспорт журнала аудита принимают одинаковые фильтры, все необязательные и объединяемые через И:
| Параметр | Совпадение |
|---|---|
event |
Точный код события, например page.update |
actor |
Точный id или имя субъекта действия |
target_type |
Точный тип цели, например page, media, user, group, config, package |
severity |
Точная важность: записанные события используют info, notice или warning |
from |
Самая ранняя метка времени включительно, в миллисекундах эпохи Unix |
to |
Самая поздняя метка времени включительно, в миллисекундах эпохи Unix |
q |
Подстрока без учёта регистра в имени субъекта действия, id цели, коде события или IP |
Поля события¶
Каждое событие содержит id, ts в миллисекундах эпохи Unix, код event (namespace.action), severity, субъект действия (actor_id, actor_name, actor_roles), auth_method (apikey, jwt или session), ip и user_agent клиента, target_type и target_id, зарезервированный status, который сейчас всегда равен null, и объект context, специфичный для события, либо null, когда у события нет дополнительных подробностей.
Состояние аудита¶
GET /audit/status
Доступен ли журнал аудита и включён ли он, с его уровнем детализации и настройками хранения. Admin Next использует его, чтобы решить, показывать ли вкладку аудита. В отличие от остальных маршрутов аудита, он работает и при выключенном журнале. Требуется суперадминистратор с api.super (ключу API с ограниченной областью действия нужна область admin.super); демо-учётные записи получают 403.
Ответ
{"data": {"enabled": true, "available": true, "coverage": "standard", "retention": {"days": 90, "max_rows": 100000}, "total": 1284}}
Коды ответов
| Код | Описание |
|---|---|
200 |
Состояние возвращено. |
401 |
Не авторизован. |
403 |
Не суперадминистратор с api.super, ключ с ограниченной областью действия без admin.super или демо-учётная запись. |
available сообщает, загружено ли расширение pdo_sqlite, а enabled равно true, только когда включён plugins.api.audit.enabled и доступен SQLite. coverage — standard или detailed. В retention поле days удаляет старые записи, а max_rows ограничивает их число; 0 отключает соответствующее ограничение. total — число сохранённых событий или null, когда журнал выключен либо подсчёт не удался.
Список событий аудита¶
GET /audit/events
События аудита с постраничной разбивкой, сначала новые, суженные необязательными фильтрами. Ссылки links для постраничной разбивки сохраняют активные фильтры, поэтому переход по next в отфильтрованном представлении остаётся отфильтрованным. Требуется суперадминистратор с api.super (ключу API с ограниченной областью действия нужна область admin.super); демо-учётные записи получают 403.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
page |
integer | Нет | Номер страницы (по умолчанию 1). |
per_page |
integer | Нет | Событий на странице. По умолчанию 50, максимум plugins.api.pagination.max_per_page (по умолчанию 1000). |
event |
string | Нет | Точный код события, например page.update. |
actor |
string | Нет | Точный id или имя субъекта действия. |
target_type |
string | Нет | Точный тип цели, например page, user или config. |
severity |
string | Нет | Точная важность (info, notice или warning). |
from |
integer | Нет | Самая ранняя метка времени включительно, в миллисекундах эпохи Unix. |
to |
integer | Нет | Самая поздняя метка времени включительно, в миллисекундах эпохи Unix. |
q |
string | Нет | Подстрока без учёта регистра в имени субъекта действия, id цели, коде события или IP. |
Ответ
{"data": [{"id": 42, "ts": 1758441600000, "event": "page.update", "severity": "info", "actor_id": "admin", "actor_name": "Admin User", "actor_roles": ["admin"], "auth_method": "jwt", "ip": "127.0.0.1", "user_agent": "Mozilla/5.0", "target_type": "page", "target_id": "/blog/my-first-post", "status": null, "context": {"changes": {"title": {"old": "Hello", "new": "My First Post"}}}}], "meta": {"pagination": {"page": 1, "per_page": 50, "total": 1, "total_pages": 1}}, "links": {"self": "/api/v1/audit/events?page=1&per_page=50&event=page.update"}}
Коды ответов
| Код | Описание |
|---|---|
200 |
События возвращены. |
401 |
Не авторизован. |
403 |
Не суперадминистратор с api.super, ключ с ограниченной областью действия без admin.super или демо-учётная запись. |
404 |
Журнал аудита не включён. |
503 |
Расширение PHP SQLite не установлено. |
Описание полей события см. во введении к разделу Журнал аудита. context несёт несколько скалярных подсказок из события, когда они есть (method, reason, old_route, new_route, lang, version, bytes), а при coverage: detailed обновление страницы также несёт changes — значение каждого изменённого поля до и после, как в примере.
Фасеты аудита¶
GET /audit/facets
Уникальные коды событий и субъекты действия, найденные в журнале, отсортированные, для выпадающих списков фильтров. Требуется суперадминистратор с api.super (ключу API с ограниченной областью действия нужна область admin.super); демо-учётные записи получают 403.
Ответ
{"data": {"events": ["config.update", "page.update", "user.login", "user.login.failed"], "actors": [{"id": "admin", "name": "Admin User"}]}}
Коды ответов
| Код | Описание |
|---|---|
200 |
Фасеты возвращены. |
401 |
Не авторизован. |
403 |
Не суперадминистратор с api.super, ключ с ограниченной областью действия без admin.super или демо-учётная запись. |
404 |
Журнал аудита не включён. |
503 |
Расширение PHP SQLite не установлено. |
id и name субъекта действия равны null для событий, записанных без известной учётной записи. При неудачном входе оба содержат имя пользователя, которое пытались использовать.
Экспорт журнала аудита¶
GET /audit/export
Скачивает все события, подходящие под фильтры, сначала новые и не более 100 000 строк, как вложение (audit-log.csv или audit-log.json), отправляемое с Cache-Control: no-store. Файл не оборачивается в JSON-обёртку. Требуется суперадминистратор с api.super (ключу API с ограниченной областью действия нужна область admin.super); демо-учётные записи получают 403.
Параметры
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
format |
string | Нет | csv (по умолчанию) или json. Любое другое значение приводит к CSV. |
event |
string | Нет | Точный код события, например page.update. |
actor |
string | Нет | Точный id или имя субъекта действия. |
target_type |
string | Нет | Точный тип цели, например page, user или config. |
severity |
string | Нет | Точная важность (info, notice или warning). |
from |
integer | Нет | Самая ранняя метка времени включительно, в миллисекундах эпохи Unix. |
to |
integer | Нет | Самая поздняя метка времени включительно, в миллисекундах эпохи Unix. |
q |
string | Нет | Подстрока без учёта регистра в имени субъекта действия, id цели, коде события или IP. |
Ответ
id,ts,event,severity,actor_id,actor_name,actor_roles,auth_method,ip,user_agent,target_type,target_id,status,context
42,1758441600000,page.update,info,admin,"Admin User","[""admin""]",jwt,127.0.0.1,Mozilla/5.0,page,/blog/my-first-post,,
Коды ответов
| Код | Описание |
|---|---|
200 |
Файл журнала, как text/csv или application/json. |
401 |
Не авторизован. |
403 |
Не суперадминистратор с api.super, ключ с ограниченной областью действия без admin.super или демо-учётная запись. |
404 |
Журнал аудита не включён. |
503 |
Расширение PHP SQLite не установлено. |
Столбцы CSV: id, ts, event, severity, actor_id, actor_name, actor_roles, auth_method, ip, user_agent, target_type, target_id, status, context. Значения-массивы, такие как actor_roles и context, кодируются как JSON, а ячейка, начинающаяся с =, +, -, @, табуляции или возврата каретки, получает префикс ', чтобы табличные приложения не выполнили её как формулу.
При format=json файл — это чистый JSON-массив событий с теми же полями, что в Списке событий аудита.