UN-3584 [FEAT] Restrict LLM adapter creation to org admins (controlled mode)#2132
UN-3584 [FEAT] Restrict LLM adapter creation to org admins (controlled mode)#2132Deepak-Kesavan wants to merge 4 commits into
Conversation
…d mode) Add a per-org 'restrict_llm_adapter_creation' setting (default off). When an org admin enables it, only organization admins may create LLM adapters: non-admin create requests are rejected with 403 and a contact-admin message. Other adapter types and the default-off behavior are unchanged. - account_v2: new BooleanField on Organization + migration - tenant_account_v2: admin-only GET/PATCH organization/settings endpoint - adapter_processor_v2: enforce the gate in AdapterInstanceViewSet.create - frontend: admin-only toggle in Platform Settings
…in OSS) Org admin roles / user management don't exist in OSS, so the controlled-mode toggle must not render there. Probe for an enterprise-only plugin (absent in OSS) and show the toggle only on enterprise/cloud builds, mirroring the plugin-gating idiom in SideNavBar. Backend is already OSS-safe: the flag defaults off and the create gate never fires.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Summary by CodeRabbit
WalkthroughAdds an organization restriction flag for LLM adapter creation, exposes admin read/write access for it, enforces it during adapter creation, and adds an enterprise admin toggle in platform settings. ChangesLLM Adapter Creation Restriction
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…audit, extract gate - Bypass the LLM-creation gate for service accounts (platform API-key sessions), consistent with how the rest of the permission layer treats them (Greptile P1). - Set Organization.modified_by on the settings PATCH so the audit field isn't left stale (Greptile P2). - Extract the controlled-mode check into _enforce_llm_creation_restriction to bring AdapterInstanceViewSet.create back under the cognitive-complexity limit (SonarQube).
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/adapter_processor_v2/views.py`:
- Around line 189-193: The adapter creation flow in
AdapterInstanceSerializer/AdapterInstanceView should not trust the payload’s
organization field. Update the save path in the view so the organization used
for creation is always the request-scoped organization from
UserContext.get_organization() (or otherwise force it server-side), and ensure
any serializer fields for organization cannot override it. Keep the existing
restrict_llm_adapter_creation/admin check tied to the same organization that
will actually be assigned.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 61151cf5-6d80-4831-999e-99a2b6e73456
📒 Files selected for processing (2)
backend/adapter_processor_v2/views.pybackend/tenant_account_v2/views.py
🚧 Files skipped from review as they are similar to previous changes (1)
- backend/tenant_account_v2/views.py
…rg override) AdapterInstanceSerializer exposes organization via fields=__all__, and DefaultOrganizationMixin.save only fills it when None — so a payload-supplied organization would persist. Pass organization=UserContext.get_organization() to serializer.save() so the row is bound to the same request-scoped org the controlled-mode check evaluates, closing a per-org restriction bypass (CodeRabbit security finding).
Frontend Lint Report (Biome)✅ All checks passed! No linting or formatting issues found. |
|
Unstract test resultsPer-group results
Critical paths
|



What
Add a per-organization "controlled mode" setting that restricts creation of LLM adapters (connections) to organization admins.
Why
UN-3584 (RLDatix on-prem onboarding blocker). Non-admin users must not be able to create unrestricted LLM connections, and this must be enforced in the product/API rather than by convention. Built as a general, opt-in product capability (any org can enable it), not a customer-specific hack.
How
account_v2— newOrganization.restrict_llm_adapter_creationBooleanField(defaultFalse) + migration0006_organization_restrict_llm_adapter_creation.tenant_account_v2— new admin-onlyGET/PATCHorganization/settingsendpoint (reusesIsOrganizationAdmin) to read/toggle the flag.adapter_processor_v2— gate inAdapterInstanceViewSet.create: when the org flag is on andadapter_type == LLM, non-admins are rejected with403 PermissionDenied("contact your organization admin"). Admins bypass; other adapter types and editing existing adapters are unaffected (the gate is oncreateonly).frontend— admin-only toggle in Platform Settings, enterprise-gated (probes for an enterprise-only plugin) so it never renders in OSS, where org-admin / user-management doesn't exist.Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)
No.
Database Migrations
Yes —
backend/account_v2/migrations/0006_organization_restrict_llm_adapter_creation.pyaddsBooleanField(default=False). No data migration.Env Config
None.
Relevant Docs
None.
Related Issues or PRs
Dependencies Versions
None.
Notes on Testing
Deployed to a dev namespace (image
snapshot.74) and verified live:GET /organization/settingsreturns 200 on load;PATCHpersists the flag (200, value echoed); migration applied.PermissionDenied(no traceback / unhandled error).Out of scope (per ticket clarification): Bedrock inference-profile enforcement (the
model_id/ "Application Inference Profile ARN" field already exists in the Bedrock adapter) and an approved-model allowlist.Screenshots
Platform Settings → "LLM Adapter Creation" toggle (admin-only, enterprise build); verified on dev.
Checklist
I have read and understood the Contribution Guidelines.