HISTORY: історія входів, аудит алертів і команди, і одна помилкова тривога
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
95a19b074d
commit
64a55d1f7e
1 changed files with 60 additions and 0 deletions
60
HISTORY.md
60
HISTORY.md
|
|
@ -8056,3 +8056,63 @@ ROADMAP називав три причини, з яких ламається с
|
|||
пісочниці народжується чистою. І `журнал аудиту 0 → 0` — проба з
|
||||
правилом `min`, тобто нуль у ній нічого не доводить; чому після повної
|
||||
установки аудит порожній, варто подивитись окремо.
|
||||
|
||||
---
|
||||
|
||||
## 2026-08-29 — Хто заходив і хто що вимкнув
|
||||
|
||||
Дві сліпі зони, знайдені питанням «чому в пісочниці аудит порожній».
|
||||
Відповідь на саме питання виявилась нудною (установник робить лише те,
|
||||
що в переліку сліпих зон), а от дорога до неї — ні.
|
||||
|
||||
### Історія входів: 93 записи були в базі й ніде не показувались
|
||||
|
||||
`core.login_attempts` наповнювалась на кожній спробі входу від першого
|
||||
дня. Читалась рівно в одному місці — для стримування підбору. Ні
|
||||
ендпойнта, ні сторінки, ні згадки у вебі. Тобто на питання «хто заходив
|
||||
у мій моніторинг» продукт мав відповідь у базі й не мав способу її
|
||||
показати. Для B2B це перше, що питає служба безпеки клієнта.
|
||||
|
||||
**Головним була не верстка.** У таблиці немає `tenant_id` — саме тому ці
|
||||
події й не в аудиті (журнал вимагає кабінет, а на момент перевірки
|
||||
пароля кабінет ще невідомий). Показати «як є» означало б віддати одному
|
||||
кабінету спроби входу чужих людей. Прив'язка непряма: спроба →
|
||||
користувач → членство, трьома шляхами одночасно (`user_id`, `username`,
|
||||
`email`) в одному `JOIN LATERAL` з `tenant_id` усередині. Саме `JOIN`, а
|
||||
не `LEFT JOIN`: без збігу рядок ПРИБИРАЄТЬСЯ, а не лишається без імені.
|
||||
|
||||
На бойових даних це виявилось не теорією: у власника **немає пошти**,
|
||||
тож за `email` не прив'язується ЖОДНА з 94 спроб. Шлях через `username`
|
||||
дає 93. Тобто зіставлення «як усі роблять» показало б порожню сторінку —
|
||||
і виглядало б справним.
|
||||
|
||||
Невдала спроба з неіснуючим логіном не належить нікому. Обрано:
|
||||
**рядком не показувати, але порахувати** — «ще N спроб з M адрес не
|
||||
показані». Сигнал «логіни перебирають» лишається, чужа людина в чужий
|
||||
кабінет не потрапляє. Однозначно правильного варіанта тут немає, і в
|
||||
коді так і написано.
|
||||
|
||||
### Аудит: алерти й склад команди
|
||||
|
||||
За цілий день роботи (драбина, тригери, канал, правила відповідності,
|
||||
політика відкату) у журналі не з'явилось нічого. Тепер пишуться правила
|
||||
алертів, канали, драбини, правила відповідності, а також додавання
|
||||
людини в кабінет, зміна ролі, вилучення й скидання пароля.
|
||||
|
||||
Два рішення про зміст:
|
||||
|
||||
* **вимкнення видно з НАЗВИ дії** (`alr.rule.disable`), а не з різниці
|
||||
подробиць. Питання «хто вимкнув правило, за яким приходив алерт»
|
||||
має відповідатись переліком, а не порівнянням двох записів;
|
||||
* **`config` каналу не їде в запис ВЗАГАЛІ.** Там не лише токен бота: у
|
||||
webhook-каналі лежить адреса (доступ на запис у чужий чат) і заголовок
|
||||
`Authorization`. Замість вмісту — прапорець `secret_changed`.
|
||||
|
||||
Перевірено наживо: створення й видалення каналу лягли в журнал, токен у
|
||||
ньому не з'явився.
|
||||
|
||||
### Помилкова тривога, названа для чесності
|
||||
|
||||
Я вирішив, що сім подій у `core.event_outbox` «висять». Ні: усі сім
|
||||
позначені доставленими, а `pruneLoop` щогодини прибирає доставлені,
|
||||
старші за граничний вік. Найстаршій було 11 годин. Механізм справний.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue