[GH-ISSUE #7301] Adding non-confirmed (Accepted) org member to a collection silently no-ops: PUT returns 200 OK but users_collections row is never written #30163

Open
opened 2026-06-17 09:55:16 -05:00 by GiteaMirror · 0 comments
Owner

Originally created by @martin-s-a on GitHub (Jun 4, 2026).
Original GitHub issue: https://github.com/dani-garcia/vaultwarden/issues/7301

Prerequisites

Vaultwarden Support String

Your environment (Generated via diagnostics page)

  • Vaultwarden version: v1.36.0
  • Web-vault version: v2026.4.1
  • OS/Arch: linux/x86_64
  • Running within a container: true (Base: Debian)
  • Database type: SQLite
  • Database version: 3.51.3
  • Uses config.json: false
  • Uses a reverse proxy: true
  • IP Header check: true (X-Real-IP)
  • Internet access: true
  • Internet access via a proxy: false
  • DNS Check: true
  • Browser/Server Time Check: true
  • Server/NTP Time Check: true
  • Domain Configuration Check: true
  • HTTPS Check: true
  • Websocket Check: true
  • HTTP Response Checks: false

Config & Details (Generated via diagnostics page)

Show Config & Details

Failed HTTP Checks:

API calls:
Header: 'x-frame-options' does not contain 'SAMEORIGIN'
Header: 'x-xss-protection' does not contain '0'
2FA Connector calls:
Header: 'x-xss-protection' does not contain '0'
Header: 'x-frame-options' is present while it should not

Config:

{
  "_duo_akey": null,
  "_enable_duo": true,
  "_enable_email_2fa": false,
  "_enable_smtp": true,
  "_enable_yubico": true,
  "_icon_service_csp": "",
  "_icon_service_url": "",
  "_ip_header_enabled": true,
  "_max_note_size": 10000,
  "_smtp_img_src": "***:",
  "admin_ratelimit_max_burst": 3,
  "admin_ratelimit_seconds": 300,
  "admin_session_lifetime": 20,
  "admin_token": "***",
  "allowed_connect_src": "",
  "allowed_iframe_ancestors": "",
  "attachments_folder": "data/attachments",
  "auth_request_purge_schedule": "30 * * * * *",
  "authenticator_disable_time_drift": false,
  "data_folder": "data",
  "database_conn_init": "",
  "database_idle_timeout": 600,
  "database_max_conns": 10,
  "database_min_conns": 2,
  "database_timeout": 30,
  "database_url": "***************",
  "db_connection_retries": 15,
  "disable_2fa_remember": false,
  "disable_admin_token": false,
  "disable_icon_download": false,
  "dns_prefer_ipv6": false,
  "domain": "*****://**********************",
  "domain_origin": "*****://**********************",
  "domain_path": "",
  "domain_set": true,
  "duo_context_purge_schedule": "30 * * * * *",
  "duo_host": null,
  "duo_ikey": null,
  "duo_skey": null,
  "duo_use_iframe": false,
  "email_2fa_auto_fallback": false,
  "email_2fa_enforce_on_verified_invite": false,
  "email_attempts_limit": 3,
  "email_change_allowed": true,
  "email_expiration_time": 600,
  "email_token_size": 6,
  "emergency_access_allowed": true,
  "emergency_notification_reminder_schedule": "0 3 * * * *",
  "emergency_request_timeout_schedule": "0 7 * * * *",
  "enable_db_wal": true,
  "enable_websocket": true,
  "enforce_single_org_with_reset_pw_policy": false,
  "event_cleanup_schedule": "0 10 0 * * *",
  "events_days_retain": null,
  "experimental_client_feature_flags": "",
  "extended_logging": true,
  "helo_name": null,
  "hibp_api_key": null,
  "http_request_block_non_global_ips": true,
  "http_request_block_regex": null,
  "icon_blacklist_non_global_ips": true,
  "icon_blacklist_regex": null,
  "icon_cache_folder": "data/icon_cache",
  "icon_cache_negttl": 259200,
  "icon_cache_ttl": 2592000,
  "icon_download_timeout": 10,
  "icon_redirect_code": 302,
  "icon_service": "internal",
  "incomplete_2fa_schedule": "30 * * * * *",
  "incomplete_2fa_time_limit": 3,
  "increase_note_size_limit": false,
  "invitation_expiration_hours": 120,
  "invitation_org_name": "Vaultwarden",
  "invitations_allowed": true,
  "ip_header": "X-Real-IP",
  "job_poll_interval_ms": 30000,
  "log_file": null,
  "log_level": "info",
  "log_timestamp_format": "%Y-%m-%d %H:%M:%S.%3f",
  "login_ratelimit_max_burst": 10,
  "login_ratelimit_seconds": 60,
  "org_attachment_limit": null,
  "org_creation_users": "",
  "org_events_enabled": false,
  "org_groups_enabled": false,
  "password_hints_allowed": true,
  "password_iterations": 600000,
  "purge_incomplete_sso_auth": "0 20 0 * * *",
  "push_enabled": false,
  "push_identity_uri": "https://identity.bitwarden.com",
  "push_installation_id": "***",
  "push_installation_key": "***",
  "push_relay_uri": "https://push.bitwarden.com",
  "reload_templates": false,
  "require_device_email": false,
  "rsa_key_filename": "data/rsa_key",
  "send_purge_schedule": "0 5 * * * *",
  "sendmail_command": null,
  "sends_allowed": true,
  "sends_folder": "data/sends",
  "show_password_hint": false,
  "signups_allowed": false,
  "signups_domains_whitelist": "",
  "signups_verify": false,
  "signups_verify_resend_limit": 6,
  "signups_verify_resend_time": 3600,
  "smtp_accept_invalid_certs": false,
  "smtp_accept_invalid_hostnames": false,
  "smtp_auth_mechanism": null,
  "smtp_debug": false,
  "smtp_embed_images": true,
  "smtp_explicit_tls": null,
  "smtp_from": "",
  "smtp_from_name": "***********",
  "smtp_host": null,
  "smtp_password": null,
  "smtp_port": 587,
  "smtp_security": "starttls",
  "smtp_ssl": null,
  "smtp_timeout": 15,
  "smtp_username": null,
  "sso_allow_unknown_email_verification": false,
  "sso_audience_trusted": null,
  "sso_auth_only_not_session": false,
  "sso_authority": "",
  "sso_authorize_extra_params": "",
  "sso_callback_path": "*****://***************************************************",
  "sso_client_cache_expiration": 0,
  "sso_client_id": "",
  "sso_client_secret": "***",
  "sso_debug_tokens": false,
  "sso_enabled": false,
  "sso_master_password_policy": null,
  "sso_only": false,
  "sso_pkce": true,
  "sso_scopes": "email profile",
  "sso_signups_match_email": true,
  "templates_folder": "data/templates",
  "tmp_folder": "data/tmp",
  "trash_auto_delete_days": null,
  "trash_purge_schedule": "0 5 0 * * *",
  "use_sendmail": false,
  "use_syslog": false,
  "user_attachment_limit": null,
  "user_send_limit": null,
  "web_vault_enabled": true,
  "web_vault_folder": "web-vault/",
  "yubico_client_id": null,
  "yubico_secret_key": null,
  "yubico_server": null
}

Vaultwarden Build Version

v1.36.0

Deployment method

Official Container Image

Custom deployment method

Compose stack behind Traefik, SQLite backend (./vw-data:/data), no custom build flags.

Reverse Proxy

Traefik v3.7.1

Host/Server Operating System

Linux

Operating System Version

Debian 12 (Bookworm)

Clients

Web Vault

Client Version

Web Vault 2026.4.1 (bundled with Vaultwarden v1.36.0)

Steps To Reproduce

  1. As Owner, invite a new user to the organization. The user accepts the invitation by clicking the email link, but the Owner has not yet confirmed them (membership status 1 = Accepted).
  2. As Owner, open an existing collection → Edit access
  3. Set permission to Manage collection and select the Accepted user from the "Select members" dropdown. The user appears in the list with the chosen permission alongside other Confirmed users.
  4. Click Save. The toast notification reports Collection <name> edited successfully.
  5. Close the dialog and re-open Edit access on the same collection.

Expected Result

Either:

  • The change persists and the Accepted user remains in the access list (and gains the assigned permission once they are Confirmed), or
  • The save call fails with an explicit error explaining that the target user must be Confirmed before they can be granted collection access.

In any case the UI feedback should match the actual server-side state.

Actual Result

  • The save call returns 200 OK and the success toast is shown.
  • On re-open of Edit access, the Accepted user is no longer present in the access list.
  • No record is ever written to the users_collections table for that user/collection pair.
  • There is no warning or error surfaced to the operator, who reasonably assumes the change was applied.

Direct inspection of the SQLite DB confirms: after the apparently-successful save the users_collections table contains zero rows for the target user, even though the membership row exists in users_organizations (with status = 1).

Logs

[INFO] PUT  /api/organizations/<org_id>/collections/<col_id>
[INFO] (put_organization_collection_update) PUT /api/organizations/<org_id>/collections/<col_id> => 200 OK
[INFO] GET  /api/organizations/<org_id>/collections/details
[INFO] (get_org_collections_details) GET /api/organizations/<org_id>/collections/details => 200 OK

(No WARN/ERROR entries are emitted on the save.)

Screenshots or Videos

No response

Additional Context

DB state right after the apparently-successful save (SQLite, schema of v1.36.0):

sqlite> SELECT u.email, uo.atype, uo.status
        FROM users_organizations uo JOIN users u ON u.uuid = uo.user_uuid;
owner@example.com    | 0 | 2   -- Owner, Confirmed
pending@example.com  | 0 | 1   -- target user, Accepted (not yet Confirmed)

sqlite> SELECT * FROM users_collections;
-- 0 rows

In all fields above, I have anonimized the data (emails, userames, etc) for privacy reasons.

Originally created by @martin-s-a on GitHub (Jun 4, 2026). Original GitHub issue: https://github.com/dani-garcia/vaultwarden/issues/7301 ### Prerequisites - [x] I have searched the existing **Closed _AND_ Open** [Issues](https://github.com/dani-garcia/vaultwarden/issues?q=is%3Aissue%20) **_AND_** [Discussions](https://github.com/dani-garcia/vaultwarden/discussions?discussions_q=) - [x] I have searched and read the [documentation](https://github.com/dani-garcia/vaultwarden/wiki/) ### Vaultwarden Support String ### Your environment (Generated via diagnostics page) * Vaultwarden version: v1.36.0 * Web-vault version: v2026.4.1 * OS/Arch: linux/x86_64 * Running within a container: true (Base: Debian) * Database type: SQLite * Database version: 3.51.3 * Uses config.json: false * Uses a reverse proxy: true * IP Header check: true (X-Real-IP) * Internet access: true * Internet access via a proxy: false * DNS Check: true * Browser/Server Time Check: true * Server/NTP Time Check: true * Domain Configuration Check: true * HTTPS Check: true * Websocket Check: true * HTTP Response Checks: false ### Config & Details (Generated via diagnostics page) <details><summary>Show Config & Details</summary> **Failed HTTP Checks:** ```yaml API calls: Header: 'x-frame-options' does not contain 'SAMEORIGIN' Header: 'x-xss-protection' does not contain '0' 2FA Connector calls: Header: 'x-xss-protection' does not contain '0' Header: 'x-frame-options' is present while it should not ``` **Config:** ```json { "_duo_akey": null, "_enable_duo": true, "_enable_email_2fa": false, "_enable_smtp": true, "_enable_yubico": true, "_icon_service_csp": "", "_icon_service_url": "", "_ip_header_enabled": true, "_max_note_size": 10000, "_smtp_img_src": "***:", "admin_ratelimit_max_burst": 3, "admin_ratelimit_seconds": 300, "admin_session_lifetime": 20, "admin_token": "***", "allowed_connect_src": "", "allowed_iframe_ancestors": "", "attachments_folder": "data/attachments", "auth_request_purge_schedule": "30 * * * * *", "authenticator_disable_time_drift": false, "data_folder": "data", "database_conn_init": "", "database_idle_timeout": 600, "database_max_conns": 10, "database_min_conns": 2, "database_timeout": 30, "database_url": "***************", "db_connection_retries": 15, "disable_2fa_remember": false, "disable_admin_token": false, "disable_icon_download": false, "dns_prefer_ipv6": false, "domain": "*****://**********************", "domain_origin": "*****://**********************", "domain_path": "", "domain_set": true, "duo_context_purge_schedule": "30 * * * * *", "duo_host": null, "duo_ikey": null, "duo_skey": null, "duo_use_iframe": false, "email_2fa_auto_fallback": false, "email_2fa_enforce_on_verified_invite": false, "email_attempts_limit": 3, "email_change_allowed": true, "email_expiration_time": 600, "email_token_size": 6, "emergency_access_allowed": true, "emergency_notification_reminder_schedule": "0 3 * * * *", "emergency_request_timeout_schedule": "0 7 * * * *", "enable_db_wal": true, "enable_websocket": true, "enforce_single_org_with_reset_pw_policy": false, "event_cleanup_schedule": "0 10 0 * * *", "events_days_retain": null, "experimental_client_feature_flags": "", "extended_logging": true, "helo_name": null, "hibp_api_key": null, "http_request_block_non_global_ips": true, "http_request_block_regex": null, "icon_blacklist_non_global_ips": true, "icon_blacklist_regex": null, "icon_cache_folder": "data/icon_cache", "icon_cache_negttl": 259200, "icon_cache_ttl": 2592000, "icon_download_timeout": 10, "icon_redirect_code": 302, "icon_service": "internal", "incomplete_2fa_schedule": "30 * * * * *", "incomplete_2fa_time_limit": 3, "increase_note_size_limit": false, "invitation_expiration_hours": 120, "invitation_org_name": "Vaultwarden", "invitations_allowed": true, "ip_header": "X-Real-IP", "job_poll_interval_ms": 30000, "log_file": null, "log_level": "info", "log_timestamp_format": "%Y-%m-%d %H:%M:%S.%3f", "login_ratelimit_max_burst": 10, "login_ratelimit_seconds": 60, "org_attachment_limit": null, "org_creation_users": "", "org_events_enabled": false, "org_groups_enabled": false, "password_hints_allowed": true, "password_iterations": 600000, "purge_incomplete_sso_auth": "0 20 0 * * *", "push_enabled": false, "push_identity_uri": "https://identity.bitwarden.com", "push_installation_id": "***", "push_installation_key": "***", "push_relay_uri": "https://push.bitwarden.com", "reload_templates": false, "require_device_email": false, "rsa_key_filename": "data/rsa_key", "send_purge_schedule": "0 5 * * * *", "sendmail_command": null, "sends_allowed": true, "sends_folder": "data/sends", "show_password_hint": false, "signups_allowed": false, "signups_domains_whitelist": "", "signups_verify": false, "signups_verify_resend_limit": 6, "signups_verify_resend_time": 3600, "smtp_accept_invalid_certs": false, "smtp_accept_invalid_hostnames": false, "smtp_auth_mechanism": null, "smtp_debug": false, "smtp_embed_images": true, "smtp_explicit_tls": null, "smtp_from": "", "smtp_from_name": "***********", "smtp_host": null, "smtp_password": null, "smtp_port": 587, "smtp_security": "starttls", "smtp_ssl": null, "smtp_timeout": 15, "smtp_username": null, "sso_allow_unknown_email_verification": false, "sso_audience_trusted": null, "sso_auth_only_not_session": false, "sso_authority": "", "sso_authorize_extra_params": "", "sso_callback_path": "*****://***************************************************", "sso_client_cache_expiration": 0, "sso_client_id": "", "sso_client_secret": "***", "sso_debug_tokens": false, "sso_enabled": false, "sso_master_password_policy": null, "sso_only": false, "sso_pkce": true, "sso_scopes": "email profile", "sso_signups_match_email": true, "templates_folder": "data/templates", "tmp_folder": "data/tmp", "trash_auto_delete_days": null, "trash_purge_schedule": "0 5 0 * * *", "use_sendmail": false, "use_syslog": false, "user_attachment_limit": null, "user_send_limit": null, "web_vault_enabled": true, "web_vault_folder": "web-vault/", "yubico_client_id": null, "yubico_secret_key": null, "yubico_server": null } ``` </details> ### Vaultwarden Build Version v1.36.0 ### Deployment method Official Container Image ### Custom deployment method Compose stack behind Traefik, SQLite backend (`./vw-data:/data`), no custom build flags. ### Reverse Proxy Traefik v3.7.1 ### Host/Server Operating System Linux ### Operating System Version Debian 12 (Bookworm) ### Clients Web Vault ### Client Version Web Vault 2026.4.1 (bundled with Vaultwarden v1.36.0) ### Steps To Reproduce 1. As Owner, invite a new user to the organization. The user accepts the invitation by clicking the email link, but the Owner has **not** yet confirmed them (membership status `1 = Accepted`). 2. As Owner, open an existing collection → **Edit access** 3. Set permission to **Manage collection** and select the Accepted user from the "Select members" dropdown. The user appears in the list with the chosen permission alongside other Confirmed users. 4. Click **Save**. The toast notification reports `Collection <name> edited` successfully. 5. Close the dialog and re-open **Edit access** on the same collection. ### Expected Result Either: - The change persists and the Accepted user remains in the access list (and gains the assigned permission once they are Confirmed), **or** - The save call fails with an explicit error explaining that the target user must be Confirmed before they can be granted collection access. In any case the UI feedback should match the actual server-side state. ### Actual Result - The save call returns `200 OK` and the success toast is shown. - On re-open of **Edit access**, the Accepted user is no longer present in the access list. - No record is ever written to the `users_collections` table for that user/collection pair. - There is no warning or error surfaced to the operator, who reasonably assumes the change was applied. Direct inspection of the SQLite DB confirms: after the apparently-successful save the `users_collections` table contains zero rows for the target user, even though the membership row exists in `users_organizations` (with `status = 1`). ### Logs ```text [INFO] PUT /api/organizations/<org_id>/collections/<col_id> [INFO] (put_organization_collection_update) PUT /api/organizations/<org_id>/collections/<col_id> => 200 OK [INFO] GET /api/organizations/<org_id>/collections/details [INFO] (get_org_collections_details) GET /api/organizations/<org_id>/collections/details => 200 OK (No WARN/ERROR entries are emitted on the save.) ``` ### Screenshots or Videos _No response_ ### Additional Context DB state right after the apparently-successful save (SQLite, schema of v1.36.0): ``` sqlite> SELECT u.email, uo.atype, uo.status FROM users_organizations uo JOIN users u ON u.uuid = uo.user_uuid; owner@example.com | 0 | 2 -- Owner, Confirmed pending@example.com | 0 | 1 -- target user, Accepted (not yet Confirmed) sqlite> SELECT * FROM users_collections; -- 0 rows ``` In all fields above, I have anonimized the data (emails, userames, etc) for privacy reasons.
GiteaMirror added the bug label 2026-06-17 09:55:16 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/vaultwarden#30163