Skip to content

feat(auth)!: replace id whitelist with unlisted session admission - #222

Merged
BegoniaHe merged 5 commits into
masterfrom
feat/unlisted-session-admission
Sep 17, 2026
Merged

BegoniaHe merged 5 commits into
masterfrom
feat/unlisted-session-admission

Conversation

@BegoniaHe

Copy link
Copy Markdown
Member

Summary

Replace ID-whitelist admission with admission.unlisted_sessions plus canonical session overlays after WakingCheck. Empty or disabled lists become allow; a non-empty enabled list becomes deny plus listed session overlays. Unique-session /llm disable now writes the group session key so every member is gated.

Related issue

Fixes #215
Related: #212

Behavior

  • Fresh profiles get admission.unlisted_sessions=allow. There is no id_whitelist, enable_id_white_list, id_whitelist_log, or wl_ignore_admin_*.
  • Config load migrates those old fields. Empty or disabled lists become allow. A non-empty enabled list becomes deny and records canonical session keys; startup then writes session_enabled=true overlays unless that field is already a bool.
  • Bare whitelist IDs expand to session:{platform_id}:group:{id} for each configured platform. Unique-session UMO list entries are not rewritten to group IDs.
  • AdmissionCheckStage sits after WakingCheckStage and reads overlays on the canonical session key, not unique-session UMO. WebChat, OneBot notice/request, and provider.manage on the instance skip unlisted-session deny.
  • IM /llm disable and /llm enable store llm_enabled on session:{platform}:group|private:{id}. should_process_llm_request reads that same key. Old unique-session UMO llm_enabled=false rows are not dual-read.
  • Dashboard writes that include the removed whitelist fields fail with the existing removed-field error. Custom-rule rows stay UMO-keyed until [feat] expose sender overlays in custom rules and Dashboard #217.

Non-goals

Sender overlays and /user (#216). Custom-rule sender targets, OpenAPI session APIs, and Dashboard sender pickers (#217). Absorbing SessionStatusCheckStage. Moving persona, TTS, or session_enabled off UMO. Command allow/deny lists, LLM block tools, and restoring admins_id. Adding admission.unlisted_senders as a config knob.

Implementation notes

Surgical replacement of WhitelistCheckStage; composition stays in compose_admission. unlisted_senders is hard-coded allow until A3. Pending overlay keys are persisted in a data-root sidecar before config integrity strips unknown whitelist fields, then applied and deleted. Builtin commands cannot import astrbot.core, so session_admission_key_from_event is exported from astrbot.api. OpenAPI generation is not required: no route or schema contract change. Dashboard custom-rule LLM toggles still save against UMO.

Validation

uv run pytest tests/unit/test_admission_check_stage.py tests/unit/test_admission_migration.py tests/unit/test_config.py tests/unit/test_config_metadata_i18n.py tests/unit/test_dashboard_util.py tests/unit/test_runtime_catalogs.py tests/unit/test_smoke.py tests/unit/test_builtin_command_extensions.py tests/unit/test_session_llm_manager.py
cd dashboard && pnpm i18n:check
cd docs && pnpm run docs:build
make check-md

Focused pytest passed (207 tests). Dashboard pnpm i18n:check, docs pnpm run docs:build, and make check-md passed. make check and the full blocking pytest suite were not run.

Compatibility and risk

Breaking config and pipeline change. Operators with a non-empty enabled whitelist get unlisted_sessions=deny plus listed overlays; operators who relied on empty/disabled lists keep the default allow. Unique-session group /llm disable now applies to the whole group. Existing unique-session UMO llm_enabled=false rows stop taking effect. apply_pending_session_allows does not overwrite an existing bool session_enabled (including false). session_blocked overlays still pass this stage; SessionStatusCheckStage remains the command-passthrough owner.

Checklist

  • A Feature request Issue exists for large work, or this is a small, obvious addition.
  • The change is focused and does not include unrelated refactoring.
  • I added or updated tests, or explained why tests are not practical.
  • User-visible behavior updates both docs/zh/ and docs/en/.
  • OpenAPI, generated client, docs/public/openapi.json, and tests change together when routes or schemas change.
  • No secrets committed. Runtime Python deps update pyproject.toml, requirements.txt, and uv.lock together.
  • I did not restore legacy shims, Python <3.14 fallbacks, or upstream publish/docs URLs as fork artifacts.
  • Breaking API or behavior changes use ! and a BREAKING CHANGE: footer.
  • I will not merge this PR myself. Merge needs a human maintainer review plus a separate AI-assisted review (AI_POLICY.md).
  • AI use follows AI_POLICY.md. Keep exactly one author note below. Do not fabricate the other.

Agent note

Goal: land A2 of #212 / #215 — delete ID-whitelist admission, migrate to admission.unlisted_sessions plus canonical session overlays, and point group /llm disable at the canonical session key. Three commits on feat/unlisted-session-admission: feat(auth)! (config, migration sidecar, AdmissionCheckStage), feat(commands) (/llm + astrbot.api export), docs. Checks actually run are listed above; full make check / blocking pytest were not. Residual risk: no dual-read of old unique-session UMO LLM rows; Dashboard custom-rule LLM toggles remain UMO-keyed until #217; unlisted_senders stays hard-coded allow until #216. Tools: OpenCode. This write-up is not the required separate AI-assisted review.

Add admission.unlisted_sessions and migrate old whitelist fields into
canonical session overlays. Replace WhitelistCheckStage with
AdmissionCheckStage after WakingCheck.

BREAKING CHANGE: id_whitelist, enable_id_white_list, id_whitelist_log,
and wl_ignore_admin_* are removed. Empty or disabled lists become
allow. A non-empty enabled list becomes deny plus listed session
overlays. Dashboard writes of the old fields fail. WebChat, OneBot
notice/request, and provider.manage skip unlisted-session deny.

Related: #215
AI-Generated: true
Generated-At: 2026-09-17T18:27:57Z
Store and read llm_enabled on session:{platform}:group|private:{id}
instead of unique-session UMO so a group disable applies to every
member. Export session_admission_key_from_event from astrbot.api
because builtin commands cannot import astrbot.core.

Related: #215
AI-Generated: true
Generated-At: 2026-09-17T18:28:10Z
Replace remaining whitelist wording with admission.unlisted_sessions
and the AdmissionCheck pipeline stage. Update command help so /session
info no longer tells operators to whitelist a group ID.

Related: #215
AI-Generated: true
Generated-At: 2026-09-17T18:28:16Z
Comment thread astrbot/core/config/admission_migration.py Fixed
Keep migrated allowlists per config profile instead of a global
session_enabled overlay. Dashboard service rules dual-write admission
fields onto the canonical session key, unique-session UMOs unwrap to
the group id, and LLM status reads that same key.

Related: #215
AI-Generated: true
Generated-At: 2026-09-17T20:09:12Z
Narrow session_service_config writes so quality pyright accepts the
canonical dual-write helper. Log tempfile cleanup failures instead of
an empty except.

Related: #215
AI-Generated: true
Generated-At: 2026-09-17T20:19:47Z
@BegoniaHe

Copy link
Copy Markdown
Member Author

Pushed 185fcedc0 to address the remaining Quality Gates / CodeQL findings on this branch:

  • pyright: update_session_rule now writes session_service_config through a dict[str, Any] helper return, so _put_session_service_config type-checks.
  • CodeQL py/empty-except: tempfile cleanup on sidecar replace failure now logs the OSError instead of pass.

Local checks: make quality-pyright (0 errors; pre-existing STAGES_ORDER __all__ warning only) and focused pytest for admission/session management (92 passed).

@BegoniaHe
BegoniaHe merged commit 1aa9569 into master Sep 17, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] replace id_whitelist with unlisted session admission

2 participants