.skills/discourse-acl-authoring/SKILL.md
Use this skill before adding or reviewing ACL-backed resource permissions in Discourse core or plugins.
view, edit, and manage, but confirm the target's domain semantics.AccessControlList, AclTarget, Acl::Target, Acl::User, Guardian, User#permission_acl, or target visibility queries.DAccessControl..skills/discourse-service-authoring for Service::Base changes, .skills/discourse-writing-rspec-tests for RSpec, and .skills/discourse-writing-js-tests for QUnit.AccessControlListManager.call; the manager is a destructive replacement service and currently assumes the caller already authorized the actor.AccessControlListManager for writes, including empty submitted ACL arrays, so mandatory ACLs are injected and old rows are replaced intentionally.AccessControlList.flattened_list as the API shape for UI/client payloads and AccessControlList.expand_list_for_bulk_insert as the DB insert shape.AclTarget visibility scopes for checks and target scopes instead of hand-querying ACL tables in controllers.DiscoursePluginRegistry.register_acl_target_class so Site#access_control exposes mandatory and banned ACL metadata to the frontend.banned_acl as a server-enforced restriction. DAccessControl hides banned permission choices for UX, but AccessControlListManager must still reject submitted banned entries.allowed_user_ids and user entries exist in lower layers but are not fully wired by expand_list, preload_allowed, cleanup jobs, or DAccessControl.app/models/access_control_list.rbapp/models/concerns/acl_target.rblib/acl/target.rb, lib/acl/user.rblib/guardian.rbapp/models/user.rbapp/services/access_control_list_manager.rbapp/jobs/regular/cleanup_acls_for_deleted.rb, app/models/group.rbapp/models/site.rb, app/serializers/site_serializer.rbfrontend/discourse/app/ui-kit/d-access-control.gjsspec/models/access_control_list_spec.rb, spec/models/concerns/acl_target_spec.rb, spec/lib/acl/target_spec.rb, spec/jobs/regular/cleanup_acls_for_deleted_spec.rb, spec/services/access_control_list_manager_spec.rb, spec/serializers/site_serializer_spec.rb, frontend/discourse/tests/integration/components/d-access-control-test.gjsplugins/discourse-kanban or the external discourse-kanban checkout when present.