Skip to content

UN-3318 [FIX] Stop noisy admin entries in resource sharing (auto-share + share dropdown)#2000

Merged
chandrasekharan-zipstack merged 4 commits into
mainfrom
fix/platform-key-admin-share
Jun 1, 2026
Merged

UN-3318 [FIX] Stop noisy admin entries in resource sharing (auto-share + share dropdown)#2000
chandrasekharan-zipstack merged 4 commits into
mainfrom
fix/platform-key-admin-share

Conversation

@chandrasekharan-zipstack

@chandrasekharan-zipstack chandrasekharan-zipstack commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

What

Two related cleanups so admin access stops adding noise to the sharing UI:

  1. Stop auto-sharing platform-key-created resources with the admin. Resources created via a platform API key are no longer auto-added to the key owner's shared_users list.
  2. Hide the current user and admins from the "Share Users" dropdown. You can't meaningfully share with yourself, and admins already have access to everything — so neither should appear as a share target.

Why

  • Org admins already see every resource via the for_user admin bypass (manager returns all org rows when is_user_organization_admin), so a shared_users entry for an admin grants no extra access — it only adds noise to the "Shared with" list and the share dropdown.
  • Offering admins as share targets is also misleading and would create stale grants that survive a later role demotion. Keeping admin access purely role-driven avoids that drift.
  • Sharing a resource with yourself is meaningless.

How

  • backend/backend/serializers.py: dropped the request.platform_api_key block in AuditSerializer.create.
  • backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py: dropped the is_service_account branch that added the key owner to a new tool's shared_users.
  • backend/tenant_account_v2/serializer.py: OrganizationMemberSerializer now returns an is_admin flag computed via is_admin_by_role, so the frontend doesn't hardcode role strings (works for OSS "admin" and Auth0 "unstract_admin"). View passes the existing auth_controller via serializer context.
  • frontend/.../SharePermission.jsx: dropdown candidate list excludes the current user (sessionDetails.userId) and admins (is_admin), in addition to the existing creator/selected exclusions.
  • Threaded is_admin through the share-user fetch sites (ListOfTools, Header, ToolSettings, useShareModal).

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. Admins retain full visibility/access to all org resources through the for_user admin bypass and the _is_organization_admin allow in object-level permission classes — independent of shared_users. Non-admins never saw platform-key-created resources before (creator is the service account). The dropdown change only removes options that were no-ops (self, admins); frontends that don't yet pass is_admin simply retain prior behavior (graceful degradation).

Database Migrations

  • None. Go-forward behavior only; existing rows are intentionally left untouched.

Env Config

  • None.

Notes on Testing

  • Create a resource (adapter / Prompt Studio project) via a platform API key, then open the share dialog as an admin → "Shared with" shows no auto-added admin. Verified live on a dev namespace: project created via platform key has shared_users: [].
  • Open the "Share Users" dropdown → the current user and admin members are not listed as options. Non-admin members still appear.
  • Confirm admins still see/manage all resources normally.

Related Issues or PRs

Notes

  • The cloud Lookups feature reuses this share widget via a plugin in unstract-cloud; a matching one-line is_admin mapping there is tracked as a separate cloud PR.

Checklist

I have read and understood the Contribution Guidelines.

…dmin

Resources created via a platform API key were auto-added to the key
owner's shared_users list. Since org admins already see every resource
via the for_user admin bypass, this entry granted no extra access and
just surfaced a lone admin in the "Shared with" list. Remove the
auto-add so shared_users reflects only explicit shares.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e979e84f-a3c8-4da6-b534-f8feae2b0534

📥 Commits

Reviewing files that changed from the base of the PR and between e2f206b and 20a67c0.

📒 Files selected for processing (1)
  • frontend/src/components/widgets/share-permission/SharePermission.jsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/widgets/share-permission/SharePermission.jsx

Summary by CodeRabbit

  • Bug Fixes

    • Removed automatic co-owner addition when service accounts or API keys create resources.
    • Admin users are now excluded from sharing recipient selection.
    • Current user is prevented from appearing in the share recipients list.
  • New Features

    • Organization members now display their admin status information.

Walkthrough

Removes two automatic co-owner additions (audit serializer and prompt-studio helper) and adds an is_admin field to organization member serialization; frontend sharing UI and hooks now propagate is_admin and filter recipients using session and admin/creator rules.

Changes

Automatic co-owner sharing removal

Layer / File(s) Summary
Serializer co-owner auto-add removal
backend/backend/serializers.py
AuditSerializer.create() now returns super().create(validated_data) directly and no longer mutates instance.shared_users to add API-key-created users.
Tool helper co-owner auto-add removal
backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py
Removed conditional that looked up a service-account PlatformApiKey and added its created_by user to a created CustomTool's shared_users prior to returning the tool.

Admin flag and sharing UI plumbing

Layer / File(s) Summary
Organization member is_admin field & context wiring
backend/tenant_account_v2/serializer.py, backend/tenant_account_v2/users_view.py
OrganizationMemberSerializer adds is_admin = SerializerMethodField() with get_is_admin using an auth_controller from serializer context (or a new AuthenticationController), and the view now passes auth_controller into the serializer context.
Frontend: include is_admin in user lists
frontend/src/components/custom-tools/header/Header.jsx, frontend/src/components/custom-tools/list-of-tools/ListOfTools.jsx, frontend/src/components/tool-settings/tool-settings/ToolSettings.jsx, frontend/src/hooks/useShareModal.js
Mappings that build userList/allUserList now include is_admin from API responses across header, list, tool settings, and the useShareModal hook.
Frontend: share-permission filtering and session awareness
frontend/src/components/widgets/share-permission/SharePermission.jsx
Adds useSessionStore usage and rewrites recipient filtering to exclude already-selected users, admins, the current user, and the creator (unless org sharing is allowed); sets shareWithEveryone from adapter data and filters admin entries out of the displayed "Shared with" list.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main changes: stopping auto-sharing with admins and removing them from the share dropdown, which are the core objectives of this PR.
Description check ✅ Passed The description comprehensively covers all required sections: What, Why, How, impact analysis, testing notes, related issues, and the contribution guidelines checklist. All critical information is present and well-explained.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/platform-key-admin-share

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chandrasekharan-zipstack chandrasekharan-zipstack marked this pull request as ready for review June 1, 2026 07:14
@greptile-apps

greptile-apps Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR removes two admin auto-share side-effects (from AuditSerializer.create and PromptStudioHelper) and adds an is_admin flag to the org-member API so the frontend can hide admins and the current user from the "Share Users" dropdown and "Shared with" display.

  • Backend cleanup: Drops the platform_api_key auto-share block in AuditSerializer and the is_service_account key-owner share in PromptStudioHelper; no data migration — go-forward only, with existing legacy rows suppressed in the UI.
  • Backend serializer: OrganizationMemberSerializer gains an is_admin SerializerMethodField delegating to auth_controller.is_admin_by_role, threaded via context from the view; a safe fallback instantiates AuthenticationController() when context is absent.
  • Frontend: is_admin is propagated through all three user-list response shapes in useShareModal, Header, ListOfTools, and ToolSettings, then used in SharePermission to filter both the dropdown candidates and the rendered "Shared with" list.

Confidence Score: 5/5

Safe to merge — changes are additive UI cleanups with no schema alterations and no impact on access-control logic.

The backend deletions remove dead-end auto-share side-effects without touching any permission enforcement path; admins retain full access through the existing role-based bypass. The new is_admin field is computed by the same is_admin_by_role helper already in use across the codebase. Frontend filtering is purely cosmetic — it cannot be used to grant or deny access — so any edge case in the filter (e.g., session not yet loaded when the component first renders) degrades gracefully to prior behavior.

No files require special attention.

Important Files Changed

Filename Overview
backend/tenant_account_v2/serializer.py Added is_admin SerializerMethodField to OrganizationMemberSerializer; defers role check to auth_controller with a safe fallback, consistent with existing usage patterns in the codebase.
frontend/src/components/widgets/share-permission/SharePermission.jsx Refactored user filtering to exclude current user and admins from dropdown and display; introduces sharedUsersToDisplay to hide legacy admin shared_users rows without touching DB data.
backend/backend/serializers.py Removed the platform-key auto-share block from AuditSerializer.create — straightforward deletion with no side effects.
backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py Removed the service-account key-owner auto-share block when creating a Prompt Studio tool — clean deletion.
frontend/src/hooks/useShareModal.js Threads is_admin through all three user-list response shapes; clean, consistent mapping.

Sequence Diagram

sequenceDiagram
    participant FE as Frontend
    participant View as OrganizationUserViewSet
    participant Ser as OrganizationMemberSerializer
    participant AC as AuthenticationController

    FE->>View: GET /get_organization_members
    View->>AC: get_organization_members_by_org_id()
    AC-->>View: members[]
    View->>Ser: "serialize(members, context={auth_controller})"
    loop per member
        Ser->>AC: is_admin_by_role(member.role)
        AC-->>Ser: bool
    end
    Ser-->>View: "[{id, email, role, is_admin}]"
    View-->>FE: "{members: [...]}"

    Note over FE: useShareModal maps is_admin through
    FE->>FE: "SharePermission filters dropdown (exclude is_admin=true, exclude self)"
    FE->>FE: "sharedUsersToDisplay filters list (exclude is_admin=true legacy rows)"
Loading

Reviews (3): Last reviewed commit: "Merge branch 'main' into fix/platform-ke..." | Re-trigger Greptile

Comment thread backend/backend/serializers.py
The "Share Users" dropdown listed every org member, including the
viewer themselves and admins. Sharing with yourself is meaningless, and
admins already have access to every resource via the for_user admin
bypass, so offering them as share targets is misleading (and would
create stale grants that survive a later role demotion).

- OrganizationMemberSerializer now returns an `is_admin` flag computed
  via is_admin_by_role, so the frontend doesn't hardcode role strings
  (works for OSS "admin" and Auth0 "unstract_admin").
- SharePermission dropdown excludes the current user and admins on top
  of the existing creator/selected-user exclusions.
- Thread `is_admin` through the share-user fetch sites.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@chandrasekharan-zipstack chandrasekharan-zipstack changed the title UN-3318 [FIX] Stop auto-sharing platform-key-created resources with admin UN-3318 [FIX] Stop noisy admin entries in resource sharing (auto-share + share dropdown) Jun 1, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@frontend/src/components/widgets/share-permission/SharePermission.jsx`:
- Around line 32-33: sessionDetails.userId is incorrect: the session store
exposes sessionDetails.id, so update the SharePermission.jsx usage to derive
currentUserId from sessionDetails?.id?.toString() (replace
sessionDetails?.userId?.toString()); search for other occurrences of
sessionDetails?.userId in this component and related components and change them
to sessionDetails?.id to keep behavior consistent with GetSessionData.js
(useSessionStore and currentUserId are the identifiers to update).
🪄 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: c21d673b-6bca-4b98-b342-c7804f7b5c64

📥 Commits

Reviewing files that changed from the base of the PR and between 8f2e5c6 and e2f206b.

📒 Files selected for processing (7)
  • backend/tenant_account_v2/serializer.py
  • backend/tenant_account_v2/users_view.py
  • frontend/src/components/custom-tools/header/Header.jsx
  • frontend/src/components/custom-tools/list-of-tools/ListOfTools.jsx
  • frontend/src/components/tool-settings/tool-settings/ToolSettings.jsx
  • frontend/src/components/widgets/share-permission/SharePermission.jsx
  • frontend/src/hooks/useShareModal.js

Comment thread frontend/src/components/widgets/share-permission/SharePermission.jsx Outdated
Comment thread backend/backend/serializers.py
@Deepak-Kesavan Deepak-Kesavan self-requested a review June 1, 2026 09:26
chandrasekharan-zipstack and others added 2 commits June 1, 2026 15:04
- Use sessionDetails.id (not .userId, which the session store doesn't
  expose) so the "can't share with yourself" filter actually fires.
- Hide admins from the "Shared with" list too, so legacy admin rows
  from before the auto-share removal no longer appear — closing the
  noise gap without a data migration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Frontend Lint Report (Biome)

All checks passed! No linting or formatting issues found.

@sonarqubecloud

sonarqubecloud Bot commented Jun 1, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Unstract test results

Per-group results

Status Group Tier Passed Failed Errors Skipped Duration (s)
unit-connectors unit 64 12 0 3 17.2
unit-core unit 0 0 2 0 1.2
unit-platform-service unit 9 0 1 0 1.4
unit-prompt-service unit 15 0 0 0 19.4
unit-rig unit 53 0 0 0 3.4
unit-runner unit 11 0 0 0 3.5
unit-sdk1 unit 354 0 0 0 20.6
unit-tool-registry unit 0 0 1 0 1.4
unit-workers unit 0 0 0 0 18.0
TOTAL 506 12 4 3 86.1

Critical paths

⚠️ Critical paths not yet covered

  • auth-login — User can log in and obtain a session cookie. (entry: POST /api/v1/auth/login; declared coverage: no groups declared)
  • adapter-register-llm — Register and validate an LLM adapter. (entry: POST /api/v1/adapter/; declared coverage: no groups declared)
  • workflow-create-execute — Create a workflow, configure source+destination, execute, poll, fetch result. (entry: POST /api/v1/workflow/{id}/execute/; declared coverage: e2e-workflow)
  • api-deployment-run — Deploy a workflow as an API, POST a document, receive structured JSON. (entry: POST /deployment/api/{org}/{name}/; declared coverage: e2e-api-deployment)
  • prompt-studio-fetch-response — Prompt Studio: create project, add prompt, run single-pass, get response. (entry: POST /api/v1/prompt-studio/prompt-studio-tool/{id}/fetch_response/; declared coverage: e2e-prompt-studio)
  • pipeline-etl-execute — Run an ETL pipeline from source connector to destination. (entry: POST /api/v1/pipeline/{id}/execute/; declared coverage: no groups declared)
  • usage-token-tracking — Per-execution token usage is recorded and retrievable. (entry: GET /api/v1/usage/get_token_usage/; declared coverage: no groups declared)
  • workflow-execution-fan-out — Multi-file workflow execution fans out to file-processing workers and rejoins. (entry: internal: backend → rabbitmq → workers/file_processing; declared coverage: no groups declared)
  • callback-result-delivery — Async results are posted back via the callback worker. (entry: internal: workers/callback → backend /internal endpoints; declared coverage: no groups declared)
✅ Covered critical paths
  • tool-sandbox-exec — covered by unit-runner

@chandrasekharan-zipstack chandrasekharan-zipstack merged commit c633db8 into main Jun 1, 2026
10 checks passed
@chandrasekharan-zipstack chandrasekharan-zipstack deleted the fix/platform-key-admin-share branch June 1, 2026 09:43
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.

3 participants