feat(BA-6860): RBAC-gate app_config fragment writes at the processors#12759
Draft
jopemachine wants to merge 3 commits into
Draft
feat(BA-6860): RBAC-gate app_config fragment writes at the processors#12759jopemachine wants to merge 3 commits into
jopemachine wants to merge 3 commits into
Conversation
This was referenced Jul 10, 2026
e2546af to
62c763d
Compare
1ac7aa8 to
b65cd3a
Compare
62c763d to
0ffd004
Compare
b65cd3a to
6f1d562
Compare
0ffd004 to
4232da6
Compare
6f1d562 to
eff9831
Compare
4232da6 to
166ad7c
Compare
2c9e320 to
b8eafd8
Compare
b528b62 to
0c1ba3e
Compare
b8eafd8 to
a7944ba
Compare
Attach the RBAC validators to the app_config_fragment write processors (create -> scope, update/purge -> single-entity, bulk_* -> bulk) and pass validators through the factory. Reads (get/admin_search/scoped_search) carry no validator — they stay gated by the allow list and scope visibility. The fragment write routes move from superadmin_required to auth_required and the handler/adapter methods drop their admin_ prefix; RBAC resolves who may write (a user their own user-scope fragment via their system role and the fragment's scope association from BA-6859, a domain admin their domain's, a superadmin any scope — public stays superadmin-only, having no RBAC scope). Replaces the interim fixed-scope _may_write service check entirely. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
0c1ba3e to
c0b6154
Compare
Co-authored-by: octodog <[email protected]>
a402f67 to
78caa30
Compare
…osure The processor-level RBAC validator wiring is consolidated into #12801 (BA-6859), which now owns the fragment write-authorization path end to end. Revert this PR's processors.py / factory.py validator wiring to base so it no longer duplicates #12801, leaving only the API-route change: fragment POST/PATCH/DELETE move from superadmin-only to authenticated (RBAC gates the write at #12801). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This was referenced Jul 14, 2026
Draft
jopemachine
added a commit
that referenced
this pull request
Jul 15, 2026
`app_config` became an RBAC resource type when an `app_configs` table still existed. 84d5c6daf8cc (BA-5822, #11265) dropped that table along with the model and the service, but left the entity type in `_resource_types()` and in the role fixture, so the grants outlived the entity they guarded. Nothing resolves them: no table, no model, no service, and no action declares `EntityType.APP_CONFIG`. The BEP-1052 replacement does not revive it either — the new AppConfig service owns no tables and is not an RBAC target, it merges the allow-list entries visible to a user/domain with no RBAC validation. #12359, #12377 and #12759 contain no reference to it outside the legacy backfill. Stop granting it at role creation, stop seeding it, and delete the 47 rows per database that a5e87ed3b6d4 backfilled. Dropping a type from RESOURCE_ENTITY_TYPES does not remove its rows — they fall through to base_permissions and are preserved as unmanaged. RETIRED_ENTITY_TYPES keeps them stripped without re-emitting, so the retirement is reproducible by re-running the generator rather than a one-off hand edit. The enum member itself stays: it is exposed through the GraphQL RBAC types and the v2 DTO, and existing rows must stay readable until the migration has run. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
jopemachine
added a commit
that referenced
this pull request
Jul 15, 2026
`app_config` became an RBAC resource type when an `app_configs` table still existed. 84d5c6daf8cc (BA-5822, #11265) dropped that table along with the model and the service, but left the entity type in `_resource_types()` and in the role fixture, so the grants outlived the entity they guarded. Nothing resolves them: no table, no model, no service, and no action declares `EntityType.APP_CONFIG`. The BEP-1052 replacement does not revive it either — the new AppConfig service owns no tables and is not an RBAC target, it merges the allow-list entries visible to a user/domain with no RBAC validation. #12359, #12377 and #12759 contain no reference to it outside the legacy backfill. Stop granting it at role creation, stop seeding it, and delete the 47 rows per database that a5e87ed3b6d4 backfilled. Dropping a type from RESOURCE_ENTITY_TYPES does not remove its rows — they fall through to base_permissions and are preserved as unmanaged. RETIRED_ENTITY_TYPES keeps them stripped without re-emitting, so the retirement is reproducible by re-running the generator rather than a one-off hand edit. The enum member itself stays: it is exposed through the GraphQL RBAC types and the v2 DTO, and existing rows must stay readable until the migration has run. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Gates AppConfig fragment writes with RBAC (BA-6860, BEP-1052 / epic BA-5781), completing the write-authorization path whose data layer landed in #12801 (BA-6859). The interim fixed-scope
_may_writeservice check is gone — authorization now runs on the standard RBAC validators at the processor layer.How
create→ scope validator,update/purge→ single-entity validator,bulk_*→ bulk validator;validatorsis passed through the factory. Read processors (get/admin_search/scoped_search) carry no validator.APP_CONFIG_FRAGMENTin the fragment's scope — a user in their ownuserscope (system role, auto-provisioned at user creation; the fragment→scope association from feat(BA-6859): bind app_config fragments to their RBAC scope on write (repository layer) #12801 resolves update/purge targets), a domain admin in their domain, a superadmin anywhere.publicfragments are global-scoped (no RBAC scope) → superadmin-only.POST /,PATCH /{id},DELETE /{id}move fromsuperadmin_requiredtoauth_required; handler/adapter methods drop theadmin_prefix. Read routes unchanged.Notes
bulk_*service paths are validator-gated but not yet API-exposed.📚 Stacked PRs
Part of the AppConfigFragment / AppConfig stack under BEP-1052 (epic BA-5781). Merge in order:
feat(BA-6552): app_config_fragments DB model and Alembic migrationfeat(BA-6553): repository layerrefactor(BA-6619): consolidate AppConfigScopeType into common.datarefactor(BA-6620): ExistsQuerier + AppConfigAllowList.existsfeat(BA-6554): AppConfigFragment service layerfeat(BA-6702): move fragment rank to the allow list with scope defaultsfeat(BA-6701): expose allow-list rank on the v2 API surfacefeat(BA-6704): cascade app config subtree deletion from the definitionfeat(BA-6626): app_config_fragment bulk repository layerfeat(BA-6618): app_config_fragment bulk CRUD service layerfeat(BA-6810): AppConfigFragment visible-fragments query (repository layer)feat(BA-6886): registerAPP_CONFIG_FRAGMENTas an RBAC resource type + permission backfillfeat(BA-6859): bind fragments to their RBAC scope on write (repository layer)fix(BA-6872): seedAPP_CONFIG_FRAGMENTpermissions into the RBAC role fixturechore(BA-6873): drop the dead APP_CONFIG RBAC entity typefeat(BA-6555): AppConfig merge engine + resolve service (service layer)feat(BA-6556): AppConfig REST v2 APIfeat(BA-6860): fragment write API routes + bulk write authz ← you are hereAccess model: fragment
create/update/purgeare gated by RBAC (a user writes their ownuser-scope fragment, a domain admin their domain's, a superadmin any —publicis superadmin-only); reads are gated by the allow list (existence = readable layer,rank= merge order) plus scope visibility, with no RBAC on the read path;app_config_definitions/app_config_allow_listthemselves are superadmin-only (REST + GQL). Closed / superseded: #12794 · #12756 · #12764.📚 Documentation preview 📚: https://sorna--12759.org.readthedocs.build/en/12759/
📚 Documentation preview 📚: https://sorna-ko--12759.org.readthedocs.build/ko/12759/