[GH-ISSUE #20701] Issue: Group Sharing Permissions Bug and OAuth Group Duplication #34796

Closed
opened 2026-04-25 08:58:25 -05:00 by GiteaMirror · 12 comments
Owner

Originally created by @antpar-rf on GitHub (Jan 15, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/20701

Check Existing Issues

  • I have searched for any existing and/or related issues.
  • I have searched for any existing and/or related discussions.
  • I have also searched in the CLOSED issues AND CLOSED discussions and found no related items (your issue might already be addressed on the development branch!).
  • I am using the latest version of Open WebUI.

Installation Method

Git Clone

Open WebUI Version

0.7.2

Ollama Version (if applicable)

No response

Operating System

Ubuntu

Browser (if applicable)

No response

Confirmation

  • I have read and followed all instructions in README.md.
  • I am using the latest version of both Open WebUI and Ollama.
  • I have included the browser console logs.
  • I have included the Docker container logs.
  • I have provided every relevant configuration, setting, and environment variable used in my setup.
  • I have clearly listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc).
  • I have documented step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation. My steps:
  • Start with the initial platform/version/OS and dependencies used,
  • Specify exact install/launch/configure commands,
  • List URLs visited, user input (incl. example values/emails/passwords if needed),
  • Describe all options and toggles enabled or changed,
  • Include any files or environmental changes,
  • Identify the expected and actual result at each stage,
  • Ensure any reasonably skilled user can follow and hit the same issue.

Expected Behavior

Commit ca514cd3 introduced critical bugs in group sharing permissions that cause:

  1. Groups with {"config": {"share": "members"}} to be invisible to their own members
  2. All groups becoming visible in sharing dropdowns regardless of membership
  3. Duplicate group creation during Okta SSO login on upgrade from 0.6.4 to 0.7.2

Affected Versions

  • Introduced in: v0.7.0
  • Present in: v0.7.2
  • Upgrade path affected: v0.6.4 → v0.7.2

When new groups are created they are defaulted presently to enable sharing for "Anyone" which could be a security issue

Proposal for new feature:

Add environment variable configuration:

# In config.py
DEFAULT_GROUP_SHARE_PERMISSION = os.getenv(
    "DEFAULT_GROUP_SHARE_PERMISSION", "members"
)  # Options: "none", "members", "anyone"

# Then use it in insert_new_group:
group_data["data"]["config"]["share"] = DEFAULT_GROUP_SHARE_PERMISSION

for when new groups are created through SSO or SCIM rather than defaulting to an access of "Anyone"

Actual Behavior

Bug #1: Groups with share: "members" Invisible to Members

Location: backend/open_webui/models/groups.py - GroupTable.get_groups() method

The Problem:

In the after code (commit ca514cd3), the filtering logic was changed from:

# BEFORE (working)
if share_value:
    query = query.filter(
        or_(
            Group.data.is_(None),
            json_share.is_(None),
            json_share == True,
        )
    )

To:

# AFTER (broken)
if share_value:
    anyone_can_share = or_(
        Group.data.is_(None),
        json_share_bool.is_(None),
        json_share_bool == True,
    )
    
    if member_id:  # ⚠️ ONLY checks member groups if member_id is provided!
        member_groups_subq = (
            db.query(GroupMember.group_id)
            .filter(GroupMember.user_id == member_id)
            .subquery()
        )
        members_only_and_is_member = and_(
            json_share_str == "members",
            Group.id.in_(member_groups_subq),
        )
        query = query.filter(
            or_(anyone_can_share, members_only_and_is_member)
        )
    else:
        query = query.filter(anyone_can_share)  # ⚠️ Excludes "members" groups!

Bug #2: OAuth/Okta Group Duplication

Location: OAuth group synchronization code path (likely in backend/open_webui/routers/auths.py or group creation logic)

The Problem:

When upgrading from 0.6.4 to 0.7.2, the modified get_groups() filtering logic affects how OAuth/Okta group synchronization finds existing groups. If the group lookup query is filtered with share=True but doesn't pass member_id, groups with {"config": {"share": "members"}} won't be found, causing the system to treat them as non-existent and create duplicates.

Steps to Reproduce

Bug #1: Groups with share: "members" Invisible to Members

  1. Missing member_id in filter dict: If the calling code doesn't pass filter.get("member_id"), groups with {"config": {"share": "members"}} are excluded entirely - even for actual members!

  2. Type confusion: The code uses both json_share_bool == True and json_share_str == "members", but the new string value "members" isn't handled in the anyone_can_share condition. When interpreted as a boolean, the string "members" won't equal True.

  3. Legacy data handling: Existing groups with:

    • data = null → Works (matches Group.data.is_(None))
    • data = {}Broken (doesn't match any condition)
    • data = {"config": {"share": false}} → Works (matches json_share_bool == False in the else branch)
    • data = {"config": {"share": "members"}}Broken (requires member_id in filter)

Bug #2: OAuth/Okta Group Duplication

Sequence of events:

  1. User logs in via Okta
  2. OAuth handler retrieves group claims from Okta
  3. System attempts to find existing groups by name using get_groups() with a filter
  4. Due to the filtering bug, existing groups aren't returned
  5. System creates duplicate groups with the same name
  6. User ends up with duplicate group memberships

Logs & Screenshots

🧪 Testing Plan

Test Case 1: Member-Only Group Visibility

  1. Create a group with {"config": {"share": "members"}}
  2. Add user A as a member
  3. User A should see the group in sharing dropdowns
  4. User B (non-member) should NOT see the group

Test Case 2: Legacy Group Migration

  1. Create groups with legacy configs:
    • data = null
    • data = {}
    • data = {"config": {"share": false}}
    • data = {"config": {"share": true}}
  2. Run migration
  3. Verify all converted to string format
  4. Verify visibility works correctly

Test Case 3: OAuth Group No Duplication

  1. Create groups via Okta SSO
  2. Log out and log back in
  3. Verify no duplicate groups created
  4. Verify group memberships maintained

Additional Information

🔧 Proposed Fixes

Fix #1: Correct the Share Filtering Logic

File: backend/open_webui/models/groups.py

Changes needed in get_groups() method:

if "share" in filter:
    share_value = filter["share"]
    member_id = filter.get("member_id")
    
    json_share = Group.data["config"]["share"]
    json_share_bool = json_share.as_boolean()
    json_share_str = json_share.as_string()

    if share_value:
        # Groups where data is null or share config is missing (legacy open groups)
        legacy_open_groups = or_(
            Group.data.is_(None),
            json_share_bool.is_(None),
        )
        
        # Groups explicitly set to anyone can share (boolean true or string "anyone")
        anyone_can_share = or_(
            json_share_bool == True,
            json_share_str == "anyone",  # Support explicit "anyone" string
        )
        
        # Combine legacy and explicit open groups
        open_groups = or_(legacy_open_groups, anyone_can_share)
        
        if member_id:
            # Member-only groups where user is actually a member
            member_groups_subq = (
                db.query(GroupMember.group_id)
                .filter(GroupMember.user_id == member_id)
                .subquery()
            )
            members_only_and_is_member = and_(
                json_share_str == "members",
                Group.id.in_(member_groups_subq),
            )
            
            # Return: open groups OR (member-only groups where user is a member)
            query = query.filter(
                or_(open_groups, members_only_and_is_member)
            )
        else:
            # If no member_id provided, only return open groups
            query = query.filter(open_groups)
    else:
        # Filter for groups where sharing is explicitly disabled
        query = query.filter(
            and_(
                Group.data.isnot(None), 
                or_(
                    json_share_bool == False,
                    json_share_str == "none",  # Support explicit "none" string
                )
            )
        )

Fix #2: Ensure member_id is Always Passed When Needed

Files to check and update:

  • Any API endpoint that calls Groups.get_groups() for user-specific contexts
  • Workspace UI components fetching groups for sharing
  • Check: backend/open_webui/routers/groups.py, UI components in src/

Example fix (in relevant API endpoints):

@router.get("/groups")
def get_groups_endpoint(user=Depends(get_verified_user)):
    filter_dict = {
        "share": True,
        "member_id": user.id  # ⚠️ MUST include user.id for member groups!
    }
    groups = Groups.get_groups(filter=filter_dict)
    return groups

Fix #3: OAuth Group Lookup Should Not Use Share Filtering

File: backend/open_webui/routers/auths.py (or wherever OAuth group sync happens)

Problem: When looking up existing groups during OAuth sync, the query should NOT apply share permission filters.

Fix:

# BEFORE (if using filtered lookup)
existing_groups = Groups.get_groups(filter={"share": True})

# AFTER
existing_groups = Groups.get_all_groups()  # Use unfiltered query
# OR
existing_groups_by_name = {g.name: g for g in Groups.get_all_groups()}
for okta_group_name in okta_group_claims:
    if okta_group_name not in existing_groups_by_name:
        # Create new group
        ...

Fix #4: Example of Database Migration for Legacy Groups / Normalize sharing options

New migration file: backend/open_webui/migrations/versions/XXXX_normalize_group_share_config.py

"""Normalize group share configuration

Revision ID: XXXX
Revises: [previous_revision]
Create Date: 2026-01-XX

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.orm import Session
import json

def upgrade():
    bind = op.get_bind()
    session = Session(bind=bind)
    
    # Get all groups
    result = session.execute(sa.text("SELECT id, data FROM 'group'"))
    
    for row in result:
        group_id, data = row
        
        # Parse existing data
        if data is None:
            # null -> {"config": {"share": "anyone"}}
            new_data = {"config": {"share": "anyone"}}
        else:
            data_dict = json.loads(data) if isinstance(data, str) else data
            
            if data_dict == {} or "config" not in data_dict:
                # {} -> {"config": {"share": "anyone"}}
                new_data = {"config": {"share": "anyone"}}
            elif "share" not in data_dict.get("config", {}):
                # {"config": {}} -> {"config": {"share": "anyone"}}
                data_dict.setdefault("config", {})["share"] = "anyone"
                new_data = data_dict
            elif data_dict["config"]["share"] is True:
                # {"config": {"share": true}} -> {"config": {"share": "anyone"}}
                data_dict["config"]["share"] = "anyone"
                new_data = data_dict
            elif data_dict["config"]["share"] is False:
                # {"config": {"share": false}} -> {"config": {"share": "none"}}
                data_dict["config"]["share"] = "none"
                new_data = data_dict
            else:
                # Already has string value ("members", "anyone", "none") - keep as is
                continue
        
        # Update the group
        session.execute(
            sa.text("UPDATE 'group' SET data = :data WHERE id = :id"),
            {"data": json.dumps(new_data), "id": group_id}
        )
    
    session.commit()


def downgrade():
    # Reverting would convert back to boolean, but this is destructive
    # Better to keep the string format
    pass

Fix #5: Default Share Config for New Groups

File: backend/open_webui/models/groups.py - insert_new_group() method

Current:

def insert_new_group(
    self, user_id: str, form_data: GroupForm, db: Optional[Session] = None
) -> Optional[GroupModel]:
    with get_db_context(db) as db:
        group = GroupModel(
            **{
                **form_data.model_dump(exclude_none=True),
                "id": str(uuid.uuid4()),
                "user_id": user_id,
                "created_at": int(time.time()),
                "updated_at": int(time.time()),
            }
        )

Proposed Fix (add default share config):

def insert_new_group(
    self, user_id: str, form_data: GroupForm, db: Optional[Session] = None
) -> Optional[GroupModel]:
    with get_db_context(db) as db:
        # Set default share config if not provided
        group_data = form_data.model_dump(exclude_none=True)
        if "data" not in group_data or group_data["data"] is None:
            group_data["data"] = {}
        if "config" not in group_data["data"]:
            group_data["data"]["config"] = {}
        if "share" not in group_data["data"]["config"]:
            # Default to "members" for new groups
            group_data["data"]["config"]["share"] = "members"
        
        group = GroupModel(
            **{
                **group_data,
                "id": str(uuid.uuid4()),
                "user_id": user_id,
                "created_at": int(time.time()),
                "updated_at": int(time.time()),
            }
        )
        # ... rest of the method

Alternative: Add environment variable configuration:

# In config.py
DEFAULT_GROUP_SHARE_PERMISSION = os.getenv(
    "DEFAULT_GROUP_SHARE_PERMISSION", "members"
)  # Options: "none", "members", "anyone"

# Then use it in insert_new_group:
group_data["data"]["config"]["share"] = DEFAULT_GROUP_SHARE_PERMISSION

Fix #6: OAuth Group Creation Default Config

File: Wherever OAuth groups are created (likely create_groups_by_group_names() in groups.py)

Current (from source):

def create_groups_by_group_names(
    self, user_id: str, group_names: list[str], db: Optional[Session] = None
) -> list[GroupModel]:
    existing_groups = self.get_all_groups(db=db)
    existing_group_names = {group.name for group in existing_groups}
    new_groups = []

    with get_db_context(db) as db:
        for group_name in group_names:
            if group_name not in existing_group_names:
                new_group = GroupModel(
                    id=str(uuid.uuid4()),
                    user_id=user_id,
                    name=group_name,
                    description="",
                    created_at=int(time.time()),
                    updated_at=int(time.time()),
                )

Fix:

def create_groups_by_group_names(
    self, user_id: str, group_names: list[str], db: Optional[Session] = None
) -> list[GroupModel]:
    existing_groups = self.get_all_groups(db=db)
    existing_group_names = {group.name for group in existing_groups}
    new_groups = []

    with get_db_context(db) as db:
        for group_name in group_names:
            if group_name not in existing_group_names:
                new_group = GroupModel(
                    id=str(uuid.uuid4()),
                    user_id=user_id,
                    name=group_name,
                    description="",
                    data={
                        "config": {
                            "share": os.getenv("OAUTH_DEFAULT_GROUP_SHARE_PERMISSION", "members")
                        }
                    },  # ⚠️ Add default share config!
                    created_at=int(time.time()),
                    updated_at=int(time.time()),
                )
Originally created by @antpar-rf on GitHub (Jan 15, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/20701 ### Check Existing Issues - [x] I have searched for any existing and/or related issues. - [x] I have searched for any existing and/or related discussions. - [x] I have also searched in the CLOSED issues AND CLOSED discussions and found no related items (your issue might already be addressed on the development branch!). - [x] I am using the latest version of Open WebUI. ### Installation Method Git Clone ### Open WebUI Version 0.7.2 ### Ollama Version (if applicable) _No response_ ### Operating System Ubuntu ### Browser (if applicable) _No response_ ### Confirmation - [x] I have read and followed all instructions in `README.md`. - [x] I am using the latest version of **both** Open WebUI and Ollama. - [x] I have included the browser console logs. - [x] I have included the Docker container logs. - [x] I have **provided every relevant configuration, setting, and environment variable used in my setup.** - [x] I have clearly **listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup** (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc). - [x] I have documented **step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation**. My steps: - Start with the initial platform/version/OS and dependencies used, - Specify exact install/launch/configure commands, - List URLs visited, user input (incl. example values/emails/passwords if needed), - Describe all options and toggles enabled or changed, - Include any files or environmental changes, - Identify the expected and actual result at each stage, - Ensure any reasonably skilled user can follow and hit the same issue. ### Expected Behavior Commit [ca514cd3](https://github.com/open-webui/open-webui/commit/ca514cd3eda2524b8da472ef17c0ccb216bac2e8) introduced critical bugs in group sharing permissions that cause: 1. Groups with `{"config": {"share": "members"}}` to be invisible to their own members 2. All groups becoming visible in sharing dropdowns regardless of membership 3. Duplicate group creation during Okta SSO login on upgrade from 0.6.4 to 0.7.2 ### Affected Versions - **Introduced in**: v0.7.0 - **Present in**: v0.7.2 - **Upgrade path affected**: v0.6.4 → v0.7.2 When new groups are created they are defaulted presently to enable sharing for "Anyone" which could be a security issue Proposal for new feature: Add environment variable configuration: ```python # In config.py DEFAULT_GROUP_SHARE_PERMISSION = os.getenv( "DEFAULT_GROUP_SHARE_PERMISSION", "members" ) # Options: "none", "members", "anyone" # Then use it in insert_new_group: group_data["data"]["config"]["share"] = DEFAULT_GROUP_SHARE_PERMISSION ``` for when new groups are created through SSO or SCIM rather than defaulting to an access of "Anyone" ### Actual Behavior ### Bug #1: Groups with `share: "members"` Invisible to Members **Location**: `backend/open_webui/models/groups.py` - `GroupTable.get_groups()` method **The Problem**: In the `after` code (commit ca514cd3), the filtering logic was changed from: ```python # BEFORE (working) if share_value: query = query.filter( or_( Group.data.is_(None), json_share.is_(None), json_share == True, ) ) ``` To: ```python # AFTER (broken) if share_value: anyone_can_share = or_( Group.data.is_(None), json_share_bool.is_(None), json_share_bool == True, ) if member_id: # ⚠️ ONLY checks member groups if member_id is provided! member_groups_subq = ( db.query(GroupMember.group_id) .filter(GroupMember.user_id == member_id) .subquery() ) members_only_and_is_member = and_( json_share_str == "members", Group.id.in_(member_groups_subq), ) query = query.filter( or_(anyone_can_share, members_only_and_is_member) ) else: query = query.filter(anyone_can_share) # ⚠️ Excludes "members" groups! ``` ### Bug #2: OAuth/Okta Group Duplication **Location**: OAuth group synchronization code path (likely in `backend/open_webui/routers/auths.py` or group creation logic) **The Problem**: When upgrading from 0.6.4 to 0.7.2, the modified `get_groups()` filtering logic affects how OAuth/Okta group synchronization finds existing groups. If the group lookup query is filtered with `share=True` but doesn't pass `member_id`, groups with `{"config": {"share": "members"}}` won't be found, causing the system to treat them as non-existent and create duplicates. ### Steps to Reproduce ### Bug #1: Groups with `share: "members"` Invisible to Members 1. **Missing `member_id` in filter dict**: If the calling code doesn't pass `filter.get("member_id")`, groups with `{"config": {"share": "members"}}` are excluded entirely - even for actual members! 2. **Type confusion**: The code uses both `json_share_bool == True` and `json_share_str == "members"`, but the new string value `"members"` isn't handled in the `anyone_can_share` condition. When interpreted as a boolean, the string `"members"` won't equal `True`. 3. **Legacy data handling**: Existing groups with: - `data = null` → Works (matches `Group.data.is_(None)`) - `data = {}` → **Broken** (doesn't match any condition) - `data = {"config": {"share": false}}` → Works (matches `json_share_bool == False` in the else branch) - `data = {"config": {"share": "members"}}` → **Broken** (requires `member_id` in filter) ### Bug #2: OAuth/Okta Group Duplication **Sequence of events**: 1. User logs in via Okta 2. OAuth handler retrieves group claims from Okta 3. System attempts to find existing groups by name using `get_groups()` with a filter 4. Due to the filtering bug, existing groups aren't returned 5. System creates duplicate groups with the same name 6. User ends up with duplicate group memberships ### Logs & Screenshots ## 🧪 Testing Plan ### Test Case 1: Member-Only Group Visibility 1. Create a group with `{"config": {"share": "members"}}` 2. Add user A as a member 3. User A should see the group in sharing dropdowns 4. User B (non-member) should NOT see the group ### Test Case 2: Legacy Group Migration 1. Create groups with legacy configs: - `data = null` - `data = {}` - `data = {"config": {"share": false}}` - `data = {"config": {"share": true}}` 2. Run migration 3. Verify all converted to string format 4. Verify visibility works correctly ### Test Case 3: OAuth Group No Duplication 1. Create groups via Okta SSO 2. Log out and log back in 3. Verify no duplicate groups created 4. Verify group memberships maintained ### Additional Information ## 🔧 Proposed Fixes ### Fix #1: Correct the Share Filtering Logic **File**: `backend/open_webui/models/groups.py` **Changes needed in `get_groups()` method**: ```python if "share" in filter: share_value = filter["share"] member_id = filter.get("member_id") json_share = Group.data["config"]["share"] json_share_bool = json_share.as_boolean() json_share_str = json_share.as_string() if share_value: # Groups where data is null or share config is missing (legacy open groups) legacy_open_groups = or_( Group.data.is_(None), json_share_bool.is_(None), ) # Groups explicitly set to anyone can share (boolean true or string "anyone") anyone_can_share = or_( json_share_bool == True, json_share_str == "anyone", # Support explicit "anyone" string ) # Combine legacy and explicit open groups open_groups = or_(legacy_open_groups, anyone_can_share) if member_id: # Member-only groups where user is actually a member member_groups_subq = ( db.query(GroupMember.group_id) .filter(GroupMember.user_id == member_id) .subquery() ) members_only_and_is_member = and_( json_share_str == "members", Group.id.in_(member_groups_subq), ) # Return: open groups OR (member-only groups where user is a member) query = query.filter( or_(open_groups, members_only_and_is_member) ) else: # If no member_id provided, only return open groups query = query.filter(open_groups) else: # Filter for groups where sharing is explicitly disabled query = query.filter( and_( Group.data.isnot(None), or_( json_share_bool == False, json_share_str == "none", # Support explicit "none" string ) ) ) ``` ### Fix #2: Ensure `member_id` is Always Passed When Needed **Files to check and update**: - Any API endpoint that calls `Groups.get_groups()` for user-specific contexts - Workspace UI components fetching groups for sharing - Check: `backend/open_webui/routers/groups.py`, UI components in `src/` **Example fix** (in relevant API endpoints): ```python @router.get("/groups") def get_groups_endpoint(user=Depends(get_verified_user)): filter_dict = { "share": True, "member_id": user.id # ⚠️ MUST include user.id for member groups! } groups = Groups.get_groups(filter=filter_dict) return groups ``` ### Fix #3: OAuth Group Lookup Should Not Use Share Filtering **File**: `backend/open_webui/routers/auths.py` (or wherever OAuth group sync happens) **Problem**: When looking up existing groups during OAuth sync, the query should **NOT** apply share permission filters. **Fix**: ```python # BEFORE (if using filtered lookup) existing_groups = Groups.get_groups(filter={"share": True}) # AFTER existing_groups = Groups.get_all_groups() # Use unfiltered query # OR existing_groups_by_name = {g.name: g for g in Groups.get_all_groups()} for okta_group_name in okta_group_claims: if okta_group_name not in existing_groups_by_name: # Create new group ... ``` ### Fix #4: Example of Database Migration for Legacy Groups / Normalize sharing options **New migration file**: `backend/open_webui/migrations/versions/XXXX_normalize_group_share_config.py` ```python """Normalize group share configuration Revision ID: XXXX Revises: [previous_revision] Create Date: 2026-01-XX """ from alembic import op import sqlalchemy as sa from sqlalchemy.orm import Session import json def upgrade(): bind = op.get_bind() session = Session(bind=bind) # Get all groups result = session.execute(sa.text("SELECT id, data FROM 'group'")) for row in result: group_id, data = row # Parse existing data if data is None: # null -> {"config": {"share": "anyone"}} new_data = {"config": {"share": "anyone"}} else: data_dict = json.loads(data) if isinstance(data, str) else data if data_dict == {} or "config" not in data_dict: # {} -> {"config": {"share": "anyone"}} new_data = {"config": {"share": "anyone"}} elif "share" not in data_dict.get("config", {}): # {"config": {}} -> {"config": {"share": "anyone"}} data_dict.setdefault("config", {})["share"] = "anyone" new_data = data_dict elif data_dict["config"]["share"] is True: # {"config": {"share": true}} -> {"config": {"share": "anyone"}} data_dict["config"]["share"] = "anyone" new_data = data_dict elif data_dict["config"]["share"] is False: # {"config": {"share": false}} -> {"config": {"share": "none"}} data_dict["config"]["share"] = "none" new_data = data_dict else: # Already has string value ("members", "anyone", "none") - keep as is continue # Update the group session.execute( sa.text("UPDATE 'group' SET data = :data WHERE id = :id"), {"data": json.dumps(new_data), "id": group_id} ) session.commit() def downgrade(): # Reverting would convert back to boolean, but this is destructive # Better to keep the string format pass ``` ### Fix #5: Default Share Config for New Groups **File**: `backend/open_webui/models/groups.py` - `insert_new_group()` method **Current**: ```python def insert_new_group( self, user_id: str, form_data: GroupForm, db: Optional[Session] = None ) -> Optional[GroupModel]: with get_db_context(db) as db: group = GroupModel( **{ **form_data.model_dump(exclude_none=True), "id": str(uuid.uuid4()), "user_id": user_id, "created_at": int(time.time()), "updated_at": int(time.time()), } ) ``` **Proposed Fix** (add default share config): ```python def insert_new_group( self, user_id: str, form_data: GroupForm, db: Optional[Session] = None ) -> Optional[GroupModel]: with get_db_context(db) as db: # Set default share config if not provided group_data = form_data.model_dump(exclude_none=True) if "data" not in group_data or group_data["data"] is None: group_data["data"] = {} if "config" not in group_data["data"]: group_data["data"]["config"] = {} if "share" not in group_data["data"]["config"]: # Default to "members" for new groups group_data["data"]["config"]["share"] = "members" group = GroupModel( **{ **group_data, "id": str(uuid.uuid4()), "user_id": user_id, "created_at": int(time.time()), "updated_at": int(time.time()), } ) # ... rest of the method ``` **Alternative**: Add environment variable configuration: ```python # In config.py DEFAULT_GROUP_SHARE_PERMISSION = os.getenv( "DEFAULT_GROUP_SHARE_PERMISSION", "members" ) # Options: "none", "members", "anyone" # Then use it in insert_new_group: group_data["data"]["config"]["share"] = DEFAULT_GROUP_SHARE_PERMISSION ``` ### Fix #6: OAuth Group Creation Default Config **File**: Wherever OAuth groups are created (likely `create_groups_by_group_names()` in `groups.py`) **Current** (from source): ```python def create_groups_by_group_names( self, user_id: str, group_names: list[str], db: Optional[Session] = None ) -> list[GroupModel]: existing_groups = self.get_all_groups(db=db) existing_group_names = {group.name for group in existing_groups} new_groups = [] with get_db_context(db) as db: for group_name in group_names: if group_name not in existing_group_names: new_group = GroupModel( id=str(uuid.uuid4()), user_id=user_id, name=group_name, description="", created_at=int(time.time()), updated_at=int(time.time()), ) ``` **Fix**: ```python def create_groups_by_group_names( self, user_id: str, group_names: list[str], db: Optional[Session] = None ) -> list[GroupModel]: existing_groups = self.get_all_groups(db=db) existing_group_names = {group.name for group in existing_groups} new_groups = [] with get_db_context(db) as db: for group_name in group_names: if group_name not in existing_group_names: new_group = GroupModel( id=str(uuid.uuid4()), user_id=user_id, name=group_name, description="", data={ "config": { "share": os.getenv("OAUTH_DEFAULT_GROUP_SHARE_PERMISSION", "members") } }, # ⚠️ Add default share config! created_at=int(time.time()), updated_at=int(time.time()), ) ```
GiteaMirror added the bug label 2026-04-25 08:58:25 -05:00
Author
Owner

@owui-terminator[bot] commented on GitHub (Jan 15, 2026):

🔍 Similar Issues Found

I found some existing issues that might be related to this one. Please check if any of these are duplicates or contain helpful solutions:

  1. #20666 issue: knowledge sharing in groups member broken
    by janl772 • Jan 14, 2026 • bug

  2. #19588 issue: Model group permissions
    by apunkt • Nov 29, 2025 • bug

  3. #19426 issue: Strange Behavior With Groups
    by matthew-kusz • Nov 24, 2025 • bug

  4. #19475 issue: A users groups aren't always updated on OAuh login
    by tobiasge • Nov 25, 2025 • bug


💡 Tips:

  • If this is a duplicate, please consider closing this issue and adding any additional details to the existing one
  • If you found a solution in any of these issues, please share it here to help others

This comment was generated automatically by a bot. Please react with a 👍 if this comment was helpful, or a 👎 if it was not.

<!-- gh-comment-id:3756408660 --> @owui-terminator[bot] commented on GitHub (Jan 15, 2026): 🔍 **Similar Issues Found** I found some existing issues that might be related to this one. Please check if any of these are duplicates or contain helpful solutions: 1. [#20666](https://github.com/open-webui/open-webui/issues/20666) **issue: knowledge sharing in groups member broken** *by janl772 • Jan 14, 2026 • `bug`* 2. [#19588](https://github.com/open-webui/open-webui/issues/19588) **issue: Model group permissions** *by apunkt • Nov 29, 2025 • `bug`* 3. [#19426](https://github.com/open-webui/open-webui/issues/19426) **issue: Strange Behavior With Groups** *by matthew-kusz • Nov 24, 2025 • `bug`* 4. [#19475](https://github.com/open-webui/open-webui/issues/19475) **issue: A users groups aren't always updated on OAuh login** *by tobiasge • Nov 25, 2025 • `bug`* --- 💡 **Tips:** - If this is a duplicate, please consider closing this issue and adding any additional details to the existing one - If you found a solution in any of these issues, please share it here to help others *This comment was generated automatically by a bot.* Please react with a 👍 if this comment was helpful, or a 👎 if it was not.
Author
Owner

@michal-zima-cnb commented on GitHub (Jan 21, 2026):

It looks that Bug #1: Groups with share: "members" Invisible to Members within this issue is similar to #19468 , which has been fixed in v 0.6.41, but it is appearing again in current release v 0.7.2

<!-- gh-comment-id:3777554947 --> @michal-zima-cnb commented on GitHub (Jan 21, 2026): It looks that Bug #1: Groups with share: "members" Invisible to Members within this issue is similar to #19468 , which has been fixed in v 0.6.41, but it is appearing again in current release v 0.7.2
Author
Owner

@michal-zima-cnb commented on GitHub (Feb 16, 2026):

Is there any update/work in progress for issue Bug #1: Groups with share: "members" Invisible to Members ? I have not seen any update for releases higher than 0.7.2. Thanks for response

<!-- gh-comment-id:3908137693 --> @michal-zima-cnb commented on GitHub (Feb 16, 2026): Is there any update/work in progress for issue Bug #1: Groups with share: "members" Invisible to Members ? I have not seen any update for releases higher than 0.7.2. Thanks for response
Author
Owner

@Classic298 commented on GitHub (Feb 16, 2026):

How can i reproduce this? If I have a group set to "members", it ... just works.
All members can see the group and share to it too.

<!-- gh-comment-id:3908202724 --> @Classic298 commented on GitHub (Feb 16, 2026): How can i reproduce this? If I have a group set to "members", it ... just works. All members can see the group and share to it too.
Author
Owner

@michal-zima-cnb commented on GitHub (Feb 16, 2026):

How can i reproduce this? If I have a group set to "members", it ... just works. All members can see the group and share to it too.

I just downloaded and tested image with latest release (v 0.8.2) and it seems, that issue has been fixed here - group sharing (write access) for models works fine. But release detail ( does not mention it.

<!-- gh-comment-id:3908648191 --> @michal-zima-cnb commented on GitHub (Feb 16, 2026): > How can i reproduce this? If I have a group set to "members", it ... just works. All members can see the group and share to it too. I just downloaded and tested image with latest release (v 0.8.2) and it seems, that issue has been fixed here - group sharing (write access) for models works fine. But release detail [(](https://github.com/open-webui/open-webui/releases) does not mention it.
Author
Owner

@Classic298 commented on GitHub (Feb 16, 2026):

I have never seen this issue to begin with, but alright - thanks for confirming it is fixed!

<!-- gh-comment-id:3908659180 --> @Classic298 commented on GitHub (Feb 16, 2026): I have never seen this issue to begin with, but alright - thanks for confirming it is fixed!
Author
Owner

@michal-zima-cnb commented on GitHub (Feb 16, 2026):

I have never seen this issue to begin with, but alright - thanks for confirming it is fixed!

This issue has been present in 0.7.2 - definitely....

<!-- gh-comment-id:3908693461 --> @michal-zima-cnb commented on GitHub (Feb 16, 2026): > I have never seen this issue to begin with, but alright - thanks for confirming it is fixed! This issue has been present in 0.7.2 - definitely....
Author
Owner

@antpar-rf commented on GitHub (Feb 19, 2026):

@Classic298 @michal-zima-cnb - when a migration occurs to 0.6.x -> 0.8.3 it still changes group permissions from what use to be "members only" to anyone can access said group, which is an issue; someone has to manually update all the records in the database -- which we did.

Additionally -- there is no environmental variable that enables new groups via oauth to persist as members only which was the behavior back in 0.6 when new groups are created via oAuth, for example as the logic listed above was different in the original Issue created.

The other bugs look to be resolved.

<!-- gh-comment-id:3930370693 --> @antpar-rf commented on GitHub (Feb 19, 2026): @Classic298 @michal-zima-cnb - when a migration occurs to 0.6.x -> 0.8.3 it still changes group permissions from what use to be "members only" to anyone can access said group, which is an issue; someone has to manually update all the records in the database -- which we did. Additionally -- there is no environmental variable that enables new groups via oauth to persist as members only which was the behavior back in 0.6 when new groups are created via oAuth, for example as the logic listed above was different in the original Issue created. The other bugs look to be resolved.
Author
Owner

@antpar-rf commented on GitHub (Feb 19, 2026):

b8112d72b9/backend/open_webui/utils/oauth.py (L36) adding a new environment variable like ENABLE_OAUTH_GROUP_DEFAULT_SHARING would be helpful to setting defaults of oauth group sharing permissions

If case 'members' ENABLE_OAUTH_GROUP_DEFAULT_SHARING=members

b8112d72b9/backend/open_webui/utils/oauth.py (L1245)

                    new_group_form = GroupForm(
                        name=group_name,
                        description=f"Group '{group_name}' created automatically via OAuth.",
                        permissions=default_permissions,  # Use default permissions from function args
                        data={"config": {"share": "members"}}, Different if cases here for ENABLE_OAUTH_GROUP_DEFAULT_GROUP_SHARING
                        user_ids=[],  # Start with no users, user will be added later by subsequent logic
                    )

would solve the permissions issues with new groups being created by oAuth being defaulted to anyone in regards to group sharing. Ideally the default behavior should be No One if not set.

@tjbck

A migration script logic should exist mentioned above for the group data permissions payload in groups being changed, but in our case we manually changed them all to solve the issue.

<!-- gh-comment-id:3930535303 --> @antpar-rf commented on GitHub (Feb 19, 2026): https://github.com/open-webui/open-webui/blob/b8112d72b95e480f946f0688bed29321b61e65af/backend/open_webui/utils/oauth.py#L36 adding a new environment variable like ENABLE_OAUTH_GROUP_DEFAULT_SHARING would be helpful to setting defaults of oauth group sharing permissions If case 'members' ENABLE_OAUTH_GROUP_DEFAULT_SHARING=members https://github.com/open-webui/open-webui/blob/b8112d72b95e480f946f0688bed29321b61e65af/backend/open_webui/utils/oauth.py#L1245 new_group_form = GroupForm( name=group_name, description=f"Group '{group_name}' created automatically via OAuth.", permissions=default_permissions, # Use default permissions from function args data={"config": {"share": "members"}}, Different if cases here for ENABLE_OAUTH_GROUP_DEFAULT_GROUP_SHARING user_ids=[], # Start with no users, user will be added later by subsequent logic ) would solve the permissions issues with new groups being created by oAuth being defaulted to anyone in regards to group sharing. Ideally the default behavior should be No One if not set. @tjbck A migration script logic should exist mentioned above for the group data permissions payload in groups being changed, but in our case we manually changed them all to solve the issue.
Author
Owner

@Classic298 commented on GitHub (Feb 19, 2026):

@antpar-rf this behaviour was documented in the changelog

<!-- gh-comment-id:3930644450 --> @Classic298 commented on GitHub (Feb 19, 2026): @antpar-rf this behaviour was documented in the changelog
Author
Owner

@antpar-rf commented on GitHub (Feb 19, 2026):

I could create a PR for said change for Group Sharing default behavior when created via Oauth as a feature; otherwise, anyway we could have that added as an environment variable to differentiate no one, members or anyone. @Classic298

<!-- gh-comment-id:3930653116 --> @antpar-rf commented on GitHub (Feb 19, 2026): I could create a PR for said change for Group Sharing default behavior when created via Oauth as a feature; otherwise, anyway we could have that added as an environment variable to differentiate no one, members or anyone. @Classic298
Author
Owner

@antpar-rf commented on GitHub (Feb 21, 2026):

PR Created related to issue: https://github.com/open-webui/open-webui/pull/21679 @Classic298 @tjbck

<!-- gh-comment-id:3937756951 --> @antpar-rf commented on GitHub (Feb 21, 2026): PR Created related to issue: https://github.com/open-webui/open-webui/pull/21679 @Classic298 @tjbck
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#34796