mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-09 18:32:52 +00:00
docs: v1 docs refresh (batch 8) (#1797)
* docs(rbac): refresh Users panel screenshots to current build Recapture users-list, add-user-form, role-selector, and delete-confirm against the live app so they reflect the current Community RBAC parity UI. Update alt text to match. * docs(sso): refresh SSO settings screenshots and document last-provider lockout guard Screenshots were captured against a stale build; refresh with current UI. Also documents the guard that blocks disabling or removing the last enabled SSO provider while SSO-only mode is active, and corrects the Recovery settings path (Operations, not System). * docs(sso): refresh SSO quickstart screenshots to current build Screenshots were captured against a stale build; recapture the provider overview and the LDAP test-connection failure state against current UI. Page text already matched the implementation, so no content changes. * docs(alerts): refresh Alerts and Notifications for current RBAC and retention behavior Verified every claim against current backend/frontend code and the live app. Corrected two factual errors: stack alert rule add/delete visibility now follows the stack:edit permission (roles renamed since the last refresh, not an admin-only gate), and the notification_history cap is a 500-row per-stack / 1000-row per-node-unattached pair enforced on the monitor's 30-second cleanup pass, not a flat 100-row per-node cap evicted on insert. Added the stack_taken_down category (also part of the built-in bell quieting rule, previously undocumented) and the seven history-only categories that are filterable but never dispatched externally. Noted the two vulnerability-scan retention controls now sharing the Data Retention page, with a cross-link to their own doc. Recaptured all eight screenshots against the production node. * docs(fleet-sync): remove stale Admiral gate claim, refresh replica screenshots Fleet Sync's replication, anchor, and demote mechanics have been free on Community since the paid gates were dropped from sync-status and reset-anchor; the Prerequisites table still claimed the control instance needed Admiral. Also documents the one-click "Reset anchor on peer" recovery banner on Settings -> Nodes, verified live against a real control/replica pair, and replaces all four screenshots with current captures.
This commit is contained in:
@@ -53,7 +53,7 @@ Sencho sends the alert title, body, severity, and either tags or destination URL
|
||||
|
||||
### Test sends and delivery semantics
|
||||
|
||||
The **Test** button on each tab dispatches the literal message `🔌 Test Notification from Sencho!` at level `info` through the same path a real alert would take, including the node's delivery-retries setting. Test sends require the admin role; the server returns 403 if an operator or viewer submits one.
|
||||
The **Test** button on each tab dispatches the literal message `🔌 Test Notification from Sencho!` at level `info` through the same path a real alert would take, including the node's delivery-retries setting. Test sends require the admin role; the server returns 403 for any non-admin user.
|
||||
|
||||
Each delivery attempt is an HTTP POST with a 10-second `AbortSignal.timeout`. By default (`Delivery retries` = 0) Sencho makes one attempt. You can allow up to three extra in-process attempts with a fixed one-second delay between them. Retries apply only to classified transient failures (for example HTTP 5xx or network timeouts). Client errors such as HTTP 4xx and Apprise HTTP 204 are not retried. There is no durable retry queue: if the process exits mid-dispatch, remaining attempts are not persisted. Delivery is at-least-once under ambiguous timeouts or connection resets, so a receiver that accepted a request whose response was lost can receive a duplicate. If every attempt fails, the alert remains in the bell with `dispatch_error` set.
|
||||
|
||||
@@ -75,7 +75,7 @@ A route with all five matchers left unconstrained (`Node` = any, and empty Stack
|
||||
|
||||
### Creating a routing rule
|
||||
|
||||
Open **Settings · Notifications · Notification Routing** and click **+ Add Route**.
|
||||
Open **Settings · Notifications · Routing** and click **+ Add route**.
|
||||
|
||||
| Field | Purpose |
|
||||
|-------|---------|
|
||||
@@ -132,9 +132,11 @@ Rules you create on the control instance replicate to remote nodes so alerts emi
|
||||
|
||||
From the bell, admins can open a row menu and choose **Mute this category**, **Mute notifications like this**, or **Mute this stack** to create a quick rule with default **Both** targeting and no weekly window. The same presets are available from stack menus (sidebar, stack header, activity tab), fleet node cards, and label groups.
|
||||
|
||||
The masthead carries `SCOPE` (`global`), `RULES` (total), and `ACTIVE` (count).
|
||||
|
||||
### Built-in bell quieting (not a mute rule)
|
||||
|
||||
Sencho also hides one class of notification from the popover without a user rule: rows where the category is one of `deploy_success`, `stack_started`, `stack_stopped`, `stack_restarted`, or `image_update_applied`, and the row carries an `actor_username` other than `system`. These are confirmations of an action you just clicked. The rows are still persisted and still dispatched externally; only the bell render hides them. Use mute rules when you need configurable, operator-controlled muting.
|
||||
Sencho also hides one class of notification from the popover without a user rule: `info`-level rows where the category is one of `deploy_success`, `stack_started`, `stack_stopped`, `stack_restarted`, `stack_taken_down`, or `image_update_applied`, and the row carries an `actor_username` other than `system`. These are confirmations of an action you just clicked. The rows are still persisted and still dispatched externally; only the bell render hides them. Use mute rules when you need configurable, user-controlled muting.
|
||||
|
||||
## Notification categories
|
||||
|
||||
@@ -147,6 +149,7 @@ Every alert Sencho dispatches carries a category that you can filter on in the b
|
||||
| `stack_started` | Stack started | Stack started via the dashboard or API |
|
||||
| `stack_stopped` | Stack stopped | Stack stopped via the dashboard or API |
|
||||
| `stack_restarted` | Stack restarted | Stack restarted via the dashboard or API |
|
||||
| `stack_taken_down` | Stack taken down | Stack taken down via the dashboard or API |
|
||||
| `image_update_available` | Update available | Image-update poll found a newer digest |
|
||||
| `node_update_available` | Node update | Sencho self-update available for this node |
|
||||
| `image_update_applied` | Update applied | Manual or scheduled auto-update applied new images |
|
||||
@@ -161,6 +164,8 @@ Every alert Sencho dispatches carries a category that you can filter on in the b
|
||||
|
||||
The four `blueprint_*` categories are accepted by routing rules but render as raw category strings in the bell because the frontend label map omits them.
|
||||
|
||||
Seven further categories are written to notification history and the stack activity timeline, and can be targeted by a mute rule, but are never dispatched to external channels or accepted by a routing rule: `drift_detected` (Drift detected), `drift_resolved` (Drift resolved), `update_started` (Update started), `health_gate_passed` (Health gate passed), `health_gate_failed` (Health gate failed), `rollback_generation_released` (Rollback protection released), and `network_auto_created` (renders as a raw category string, same reason as the blueprint categories above).
|
||||
|
||||
## Stack alert rules
|
||||
|
||||
Each stack carries its own set of threshold rules that fire when a metric stays above (or below) a value for a configurable window. A rule can target **All services** in the stack or one Compose service. Metrics are evaluated per running container (not as a stack aggregate): each container has its own duration timer, and cooldown is tracked per Compose service so replicas of the same service share one silence window while different services can alert independently.
|
||||
@@ -211,7 +216,7 @@ The **NOTIFICATION CHANNELS** banner above the rules list reflects what dispatch
|
||||
- **Active** is a green banner reading `Notifications active via Discord, Slack, …` with the configured channels listed.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/alerts-notifications/alert-panel-remote-banner.png" alt="The Stack › SAELIX-DB › MONITOR sheet on a remote node, with the blue 'Remote node: node-a' banner explaining that rules are stored and evaluated on the remote, plus a follow-up amber line noting that no notification channels are configured on that remote." />
|
||||
<img src="/images/alerts-notifications/alert-panel-remote-banner.png" alt="The Stack › nakama › MONITOR sheet on a remote node, with the blue 'Remote node: Pitt-Moba' banner explaining that rules are stored and evaluated on the remote, plus a follow-up amber line noting that no notification channels are configured on that remote." />
|
||||
</Frame>
|
||||
|
||||
### Example: alert on high CPU
|
||||
@@ -228,7 +233,7 @@ To page when CPU on a stack stays above 80% for at least five minutes, with no m
|
||||
|
||||
### Permissions and validation
|
||||
|
||||
Operators and viewers see existing rules read-only; only admins see the add and delete affordances. Submitting an empty threshold surfaces `Please enter a threshold.` Successful saves toast `Alert rule added.` and `Alert rule deleted.` A failed POST surfaces `Network error. Could not reach the node.`
|
||||
Stack alert rules are gated by the `stack:edit` permission on the target stack, not a fixed admin check. A user sees the **Add new rule** form and the delete action on each row only if their role (or a scoped grant) carries `stack:edit` for that stack; a user with only `stack:read` sees existing rules read-only. Built-in roles: `admin` and `node-admin` have `stack:edit` on every stack; `deployer`, `viewer`, and `auditor` do not, so they see a read-only list. Submitting an empty threshold surfaces `Please enter a threshold.` Successful saves toast `Alert rule added.` and `Alert rule deleted.` A failed POST surfaces `Network error. Could not reach the node.`
|
||||
|
||||
The delete confirmation dialog reads `Delete Alert Rule` / `This will permanently remove this alert rule. Notifications for this condition will no longer be sent.` with a destructive **Delete** button.
|
||||
|
||||
@@ -237,7 +242,7 @@ The delete confirmation dialog reads `Delete Alert Rule` / `This will permanentl
|
||||
The bell icon at the top of the shell is the live feed of every alert across the fleet. A pulsing red dot surfaces unread items.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/alerts-notifications/notification-popover.png" alt="The notification bell open, with a 'Notifications' italic title, '9 UNREAD' uppercase mono caption, an All / Unread / Alerts segmented control, the filter-toggle, mark-all-read, and clear-all icon actions, a 'TODAY' day-band header, and a stack of severity-tinted rows describing Sencho version updates and a recent stack stop, each with a node-name pill, a relative timestamp, and a per-row dismiss target." />
|
||||
<img src="/images/alerts-notifications/notification-popover.png" alt="The notification bell open, with a 'Notifications' italic title, '1 UNREAD' uppercase mono caption, an All / Unread / Alerts segmented control, the filter-toggle, mark-all-read, and clear-all icon actions, a 'TODAY' day-band header, and a warning-tinted row reporting a CPU threshold breach on the plex stack with a relative timestamp and a per-row dismiss target." />
|
||||
</Frame>
|
||||
|
||||
### Anatomy
|
||||
@@ -286,11 +291,11 @@ The popover renders three different empty states:
|
||||
|
||||
### What you won't see in the bell
|
||||
|
||||
Sencho deliberately suppresses one class of notification from the popover: rows where the category is one of `deploy_success`, `stack_started`, `stack_stopped`, `stack_restarted`, or `image_update_applied`, AND the row carries an `actor_username` other than `system`. These are confirmations of an action you just clicked, surfaced as a toast at the moment of the action; replaying them in the bell would be noise. The rows are still persisted to `notification_history` and still dispatched to global channels and matching routes; only the bell render hides them.
|
||||
Sencho deliberately suppresses one class of notification from the popover: `info`-level rows where the category is one of `deploy_success`, `stack_started`, `stack_stopped`, `stack_restarted`, `stack_taken_down`, or `image_update_applied`, AND the row carries an `actor_username` other than `system`. These are confirmations of an action you just clicked, surfaced as a toast at the moment of the action; replaying them in the bell would be noise. The rows are still persisted to `notification_history` and still dispatched to global channels and matching routes; only the bell render hides them.
|
||||
|
||||
### Limits
|
||||
|
||||
The popover holds the latest 50 rows per node per fetch. The backend caps `notification_history` at 100 rows per node, regardless of the user-tunable retention setting; the cap evicts the oldest rows on every insert. There is no `Load more` affordance; older rows roll off the cap.
|
||||
The popover holds the latest 50 rows per node per fetch. There is no `Load more` affordance; older rows roll off the caps described in [Retention and limits](#retention-and-limits) below.
|
||||
|
||||
## Cross-node delivery
|
||||
|
||||
@@ -397,10 +402,10 @@ Fleet Sync requires Admiral on the control instance.
|
||||
|
||||
## Retention and limits
|
||||
|
||||
Three retention controls live under **Settings · Operations · Data Retention**.
|
||||
**Settings · Operations · Data Retention** hosts the notification and audit retention windows alongside two vulnerability-scan retention controls (**Scan history per digest** and **Remove scans for deleted images and stacks**); those two are covered in [Vulnerability scanning](/features/vulnerability-scanning), not here.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/alerts-notifications/developer-retention.png" alt="Settings · Operations · Data Retention card showing three rows: Container metrics with a 24 HRS field, Notification log with a 30 DAYS field, and Audit log (Admiral) with a 90 DAYS field, plus a SAVE SETTINGS button." />
|
||||
<img src="/images/alerts-notifications/developer-retention.png" alt="Settings · Operations · Data Retention card showing Container metrics with a 24 HRS field, Notification log with a 30 DAYS field, Scan history per digest with a 50 SCANS field, a Remove scans for deleted images and stacks toggle in the ON state, and Audit log with a 90 DAYS field, plus a SAVE SETTINGS button." />
|
||||
</Frame>
|
||||
|
||||
| Control | Range | Default | What it prunes |
|
||||
@@ -409,7 +414,7 @@ Three retention controls live under **Settings · Operations · Data Retention**
|
||||
| **Notification log** | 1 to 365 days | 30 days | The bell's `notification_history` table |
|
||||
| **Audit log** *(Admiral)* | 1 to 365 days | 90 days | Audit trail entries |
|
||||
|
||||
A hard 100-row per-node cap inside `notification_history` always applies on top of the user-tunable retention; new inserts evict the oldest rows beyond 100 even if your retention window is longer.
|
||||
Beyond the time-based window above, `notification_history` also carries two hard row caps that a cleanup pass enforces on every monitor tick: up to 500 rows per (node, stack) pair, and up to 1,000 rows per node for stack-less system events (host thresholds, fleet-sync warnings, scheduled-task results). A chatty stack cannot evict a quieter stack's history because each stack has its own 500-row quota. These caps apply on top of your retention window, whichever prunes first.
|
||||
|
||||
A separate rate limit applies to crash and health alerts only: 20 emits per fixed 60-second window per node (not a rolling window). When the cap is hit, individual overflow alerts are not written to history or the bell; at the end of the window Sencho emits a single `warning`/`monitor_alert` roll-up that names crash-only, health-only, or mixed suppression.
|
||||
|
||||
@@ -465,7 +470,7 @@ Switching the active node tears down per-stack rule editors and reloads channel
|
||||
Sencho rate-limits crash and health dispatches together to 20 emits per fixed 60-second window per node, then emits a single `warning`/`monitor_alert` roll-up such as `N additional container crash alerts were rate-limited in the last minute.`, a health-only variant, or a mixed `(X crash, Y health)` summary once the window closes. Rate-limited overflow individuals are not written to `notification_history` and do not appear in the bell; only the roll-up is persisted for that overflow. Separately, health flaps on the same container are deduped for 60 minutes after a persisted unhealthy alert, even if Docker recovered and failed again inside that window.
|
||||
</Accordion>
|
||||
<Accordion title="My deploy success doesn't appear in the bell, only as a toast">
|
||||
Sencho deliberately hides rows whose category is one of `deploy_success`, `stack_started`, `stack_stopped`, `stack_restarted`, or `image_update_applied` AND whose `actor_username` is set to a real user. The reasoning: those are confirmations of the action you just clicked and are already shown as a toast. The rows are still persisted to `notification_history` and still dispatched to global channels and matching routes; only the bell render hides them.
|
||||
Sencho deliberately hides `info`-level rows whose category is one of `deploy_success`, `stack_started`, `stack_stopped`, `stack_restarted`, `stack_taken_down`, or `image_update_applied` AND whose `actor_username` is set to a real user. The reasoning: those are confirmations of the action you just clicked and are already shown as a toast. The rows are still persisted to `notification_history` and still dispatched to global channels and matching routes; only the bell render hides them.
|
||||
</Accordion>
|
||||
<Accordion title="A routing rule is set up but the global channel still fires">
|
||||
Routing matchers AND together: every non-empty matcher must match the alert. A rule with **Stacks** set to `prod-api` will not match a `monitor_alert` for a different stack, and a rule with a populated **Stacks** matcher will not match host-level alerts (which carry no stack target). Stack patterns may use `*` as a wildcard (for example `prod-*`). When zero rules match, Sencho falls back to global channels. To intercept everything, leave Node as any and leave Stacks, Labels, Categories, and Severity empty. Also confirm the rule's **Enabled** pill is `ON`.
|
||||
|
||||
@@ -37,7 +37,7 @@ The transition from control to replica happens automatically the first time a re
|
||||
The read-only banner above only appears when you sign in **directly** to the replica's own URL. Scan policies, CVE suppressions, and misconfig acknowledgements are fetched with a `localOnly` request, so they are not proxied through the Distributed API the way most other per-node pages are. If you instead browse a remote node's **Security** page from the control by switching nodes in the top-left node switcher, the Policies and Suppressions tabs show a different message and no replicated data at all:
|
||||
|
||||
<Frame>
|
||||
<img src="/images/fleet-sync/fleet-sync-proxy-notice.png" alt="The Security page Policies tab on the control, with the node switcher set to a remote named Opsix. A callout reads 'Managed on the local instance: Scan policies are managed on the local Sencho instance. Switch to the local node to manage them,' with no policy list below it." />
|
||||
<img src="/images/fleet-sync/fleet-sync-proxy-notice.png" alt="The Security page Policies tab on the control, with the node switcher set to a remote. A callout reads 'Managed on the local instance: Scan policies are managed on the local Sencho instance. Switch to the local node to manage them,' with no policy list below it." />
|
||||
</Frame>
|
||||
|
||||
To see a replica's mirrored rules, sign in to that instance's own URL instead of viewing it through the control's node switcher. This is different from most other Security page tabs (Images, Secrets, Scanner setup) and most other Sencho pages generally, which do proxy through the node switcher; scan policies, CVE suppressions, and misconfig acknowledgements are the exception.
|
||||
@@ -47,7 +47,7 @@ To see a replica's mirrored rules, sign in to that instance's own URL instead of
|
||||
The three replicated resources share one wire protocol, one retry queue, and one anchor. Each push carries the full current state of one resource (not a delta); the receiver replaces every `replicated_from_control = 1` row in a single transaction. On the replica, each mirrored row carries a **replicated** tag so you can tell it apart from a local one at a glance:
|
||||
|
||||
<Frame>
|
||||
<img src="/images/fleet-sync/fleet-sync-suppressions-replica.png" alt="The Security page Suppressions tab on a replica. Two CVE suppressions for github.com/docker/docker are listed, each tagged 'Accepted risk' and 'replicated,' with no Add suppression or Export VEX buttons visible. A Misconfig acknowledgements section below is empty." />
|
||||
<img src="/images/fleet-sync/fleet-sync-suppressions-replica.png" alt="The Security page Suppressions tab on a replica. A CVE suppression is listed, tagged 'Accepted risk' and 'replicated,' with no Add suppression or Export VEX buttons visible. A Misconfig acknowledgements section below is empty." />
|
||||
</Frame>
|
||||
|
||||
What does *not* replicate:
|
||||
@@ -81,7 +81,9 @@ A replica binds to the first non-empty fingerprint it sees. After that:
|
||||
- A push carrying a different non-empty fingerprint is rejected with `HTTP 409` and the body code `CONTROL_IDENTITY_MISMATCH`. This prevents an operator from accidentally pointing a second control at an existing replica and overwriting its mirrored state.
|
||||
- A push with no fingerprint at all is accepted (this is the legacy code path; the receiver treats absence as "unknown control" and applies the rows without binding).
|
||||
|
||||
When you need to re-bind a replica to a different control (for example, the original control was rebuilt and now carries a fresh install ID), an admin on the replica calls the re-anchor endpoint with an explicit override flag:
|
||||
When you need to re-bind a replica to a different control (for example, the original control was rebuilt and now carries a fresh install ID), the control itself surfaces the mismatch: **Settings → Nodes** shows a banner on the affected node reading "Node is anchored to another central," with a **Reset anchor on peer** button. An admin clicks it and the control proxies the reset to the peer over its existing bearer token, no direct access to the replica required.
|
||||
|
||||
If you need to script it or the node is not reachable from the control's own Settings → Nodes list, call the endpoint directly on the replica with an admin JWT and an explicit override flag:
|
||||
|
||||
```bash
|
||||
curl -X POST https://<replica-url>/api/fleet/role/reanchor \
|
||||
@@ -90,7 +92,7 @@ curl -X POST https://<replica-url>/api/fleet/role/reanchor \
|
||||
-d '{"override": true}'
|
||||
```
|
||||
|
||||
Re-anchor clears the cached fingerprint, clears the per-resource watermarks, and drops every replicated row inside one transaction. The replica stays a replica (it remains a passive receiver) and the next push from any control becomes the new anchor.
|
||||
Either path clears the cached fingerprint, clears the per-resource watermarks, and drops every replicated row inside one transaction. The replica stays a replica (it remains a passive receiver) and the next push from any control becomes the new anchor.
|
||||
|
||||
## Push ordering and retry
|
||||
|
||||
@@ -127,9 +129,10 @@ Demote requires `{"confirm": true}` in the request body to prevent a misclick fr
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Fleet Sync works on every tier: authoring scan policies, CVE suppressions, and misconfig acknowledgements, and the replication, anchor, and demote mechanics that ship them to remotes, all run on Community. Replicas accept pushes regardless of their own tier.
|
||||
|
||||
| Requirement | Why it matters |
|
||||
|---|---|
|
||||
| **A Sencho Admiral plan on the control instance** | Authoring scan policies, CVE suppressions, and misconfig acknowledgements works on every tier. Fleet Sync (cross-node replication and anchor controls) requires Admiral on the control instance. Replicas accept pushes regardless of their own tier. |
|
||||
| **Admin user role on the control** | Authoring the rules that replicate, and operating the re-anchor and demote endpoints on a replica, are all admin-only actions. Operator and viewer roles can read rules but cannot create or remove them. |
|
||||
| **Proxy-mode remotes with `api_url` and `api_token` configured in Settings → Nodes** | Fleet Sync pushes over HTTPS to each remote's Sencho API using its long-lived bearer token. Remotes without an `api_url` or `api_token`, or remotes that connect over the pilot tunnel, are skipped. |
|
||||
| **Network reachability from the control to each remote** | Pushes are HTTP requests originating on the control. A remote that is firewalled off, behind NAT without a forwarded port, or otherwise unreachable will queue retries until it returns. |
|
||||
@@ -155,7 +158,7 @@ Fleet Sync v1 ships the three replicated resources and the control mechanics des
|
||||
This usually means the remote has not yet received its first push (it is still a fresh control from its own perspective). Any write on the control triggers a fresh push, or you can add the remote again in **Settings → Nodes** to trigger the add-node backfill. Once the first push lands, the remote flips to replica and shows the "Managed by control node" callout above the policy list.
|
||||
</Accordion>
|
||||
<Accordion title="A push returns 409 CONTROL_IDENTITY_MISMATCH">
|
||||
The replica is already anchored to a different control's fingerprint. Either point your browser at the original control and continue authoring there, or sign in as admin on the replica and call the re-anchor endpoint with `{"override": true}` to clear the anchor. The next push from any control then becomes the new anchor.
|
||||
The replica is already anchored to a different control's fingerprint. **Settings → Nodes** on the control shows a banner on the affected node with a **Reset anchor on peer** button; click it to clear the anchor without leaving the control. Alternatively, point your browser at the original control and continue authoring there, or sign in as admin on the replica and call the re-anchor endpoint with `{"override": true}` directly. The next push from any control then becomes the new anchor.
|
||||
</Accordion>
|
||||
<Accordion title="A push returns 409 STALE_SYNC_PUSH">
|
||||
A newer push for the same resource has already landed on this replica, so the older retry is silently dropped. No action needed; the next write on the control will produce a fresher timestamp and succeed.
|
||||
|
||||
@@ -62,7 +62,7 @@ Both plans use the same five built-in roles and the same additive stack and node
|
||||
The Users panel lives at **Settings · Users**, under the **Access** group of the settings sidebar. It is visible only to users with the Admin role, and is hidden when a remote node is the active selection.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/rbac/users-list.png" alt="Settings Users panel showing the Access sidebar selection, a SCOPE global chip, an OPERATORS 2 counter, an Add user button, and a four-column table (Username, Role, Created, Actions) with two rows: admin marked (you) with a disabled trash icon and viewer with active edit and trash icons." />
|
||||
<img src="/images/rbac/users-list.png" alt="Settings Users panel showing the Access sidebar selection, a SCOPE global chip, an OPERATORS 3 counter, an Add user button, and a four-column table (Username, Role, Created, Actions) with three rows: an Admin row marked (you) with a disabled trash icon, a second Admin row, and a Viewer row, both with active edit and trash icons." />
|
||||
</Frame>
|
||||
|
||||
The table shows one row per user with their **Username**, **Role** badge, account **Created** date, and per-row action icons. The signed-in admin's row carries a small `(you)` marker after the username and the delete icon is disabled, so you cannot lock yourself out by deleting your own account.
|
||||
@@ -157,7 +157,7 @@ If you need to track repeated lockouts, the audit log records each failed login
|
||||
Click the trash icon on a user row. A confirmation modal with the kicker `USERS · DELETE · IRREVERSIBLE` opens.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/rbac/delete-confirm.png" alt="Delete confirmation modal with the kicker USERS DELETE IRREVERSIBLE, the title Delete user viewer in italic display type, the body Removes the user immediately. They lose access right away., and Cancel and Delete buttons on the lower right." />
|
||||
<img src="/images/rbac/delete-confirm.png" alt="Delete confirmation modal with the kicker USERS DELETE IRREVERSIBLE, the bold title Delete user site-viewer, the body Removes the user immediately. They lose access right away., and Cancel and Delete buttons on the lower right." />
|
||||
</Frame>
|
||||
|
||||
The body reads:
|
||||
|
||||
+12
-2
@@ -87,6 +87,12 @@ At the top of the page, **Authentication mode** chooses how interactive login wo
|
||||
|
||||
SSO only cannot be enabled until at least one provider is enabled, a connection test succeeds, and the signed-in administrator authenticated through SSO with the Admin role. Confirm the outage-risk warning before saving. Existing sessions stay valid until they expire or are revoked.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/sso/sso-settings-sso-only-confirm.png" alt="SSO-only confirmation panel showing the outage-risk warning, the list of providers that remain available, the emergency recovery command, and the confirmation checkbox required before saving" />
|
||||
</Frame>
|
||||
|
||||
Once SSO only is active, you cannot disable or remove the last enabled provider from the Settings UI; doing so would lock out every SSO user with no way to sign in. Switch back to **Local and SSO** first, or use the emergency recovery CLI below, before disabling or removing that provider.
|
||||
|
||||
If the identity provider is unavailable after SSO only is enabled, restore local password login from the host:
|
||||
|
||||
```bash
|
||||
@@ -94,7 +100,7 @@ docker compose exec sencho node dist/cli/enableLocalLogin.js
|
||||
docker compose restart sencho
|
||||
```
|
||||
|
||||
Restart is required so the running process reloads the setting. The same command is listed under **Settings → System → Recovery**.
|
||||
Restart is required so the running process reloads the setting. The same command is listed under **Settings → Operations → Recovery**.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/sso/sso-settings.png" alt="SSO settings panel listing the five identity providers as collapsible cards with enable / disable toggles" />
|
||||
@@ -318,7 +324,7 @@ If not set, Sencho auto-detects the URL from the request's `Host` header and pro
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Users land with the wrong username or no email">
|
||||
Enable **Developer Mode** (Settings → Operations → Developer Diagnostics) to log the raw claims Sencho receives from the provider in the server logs. Check your provider's documentation for which claims it includes in the ID token and `userinfo` response, and verify that the configured **Scopes** include everything your provider needs to emit `email` and group claims. For Custom OIDC, override **User ID Claim**, **Username Claim**, or **Email Claim** to match the names your provider actually emits.
|
||||
Enable **Developer mode** (Settings → Operations → Developer Diagnostics) to log the raw claims Sencho receives from the provider in the server logs. Check your provider's documentation for which claims it includes in the ID token and `userinfo` response, and verify that the configured **Scopes** include everything your provider needs to emit `email` and group claims. For Custom OIDC, override **User ID Claim**, **Username Claim**, or **Email Claim** to match the names your provider actually emits.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="The provider returns 'invalid redirect URI' during sign-in">
|
||||
@@ -338,6 +344,10 @@ If not set, Sencho auto-detects the URL from the request's `Host` header and pro
|
||||
|
||||
Then sign in with a local administrator account and repair the identity provider configuration before enabling SSO only again.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="'Cannot disable/delete the last SSO provider while SSO-only mode is active'">
|
||||
Sencho blocks this to prevent a lockout: with SSO only active and no local password fallback, disabling or removing the one remaining enabled provider would leave nobody able to sign in. Switch **Authentication mode** back to **Local and SSO** first, then disable or remove the provider, or re-enable it under a different configuration if you are migrating identity providers.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
The [operations troubleshooting page](/operations/troubleshooting#ldap-connection-refused) covers a few more cases that come up during initial setup, including LDAP connection refused, TLS certificate errors, and OAuth callback URL mismatches.
|
||||
|
||||
Reference in New Issue
Block a user