Skip to content

fix: add pipeline override hook and guard singleton user reuse for multi-tenant#655

Merged
njbrake merged 1 commit intomainfrom
fix/multi-tenant-pipeline-and-user-isolation
Mar 17, 2026
Merged

fix: add pipeline override hook and guard singleton user reuse for multi-tenant#655
njbrake merged 1 commit intomainfrom
fix/multi-tenant-pipeline-and-user-isolation

Conversation

@njbrake
Copy link
Collaborator

@njbrake njbrake commented Mar 17, 2026

Description

Two fixes to support multi-tenant (premium) mode correctly:

  1. Pipeline override hook: Adds set_pipeline_override() and get_active_pipeline() to router.py so the premium plugin can inject quota-check and usage-tracking steps into the agent pipeline. Previously, handle_inbound_message() always used DEFAULT_PIPELINE, which meant all premium quota enforcement was bypassed for every inbound message (Telegram and web chat).

  2. Singleton user reuse guard: In _get_or_create_user(), skips the "reuse sole existing user" path when settings.premium_plugin is set. Without this guard, in multi-tenant mode, the first new Telegram sender would have their messages linked to an existing user's account -- a data leak where User B's messages appear in User A's session.

Type

  • Feature
  • Bug fix
  • Refactor
  • Test
  • CI/CD
  • Documentation

Checklist

  • Tests pass (uv run pytest -v)
  • Lint passes (ruff check backend/ && ruff format --check backend/)
  • New tests added for new functionality
  • Bug fixes include regression tests

AI Usage

  • AI-assisted (describe how)
  • No AI used

Architecture review and fix implementation by Claude Opus 4.6. Identified the two critical multi-tenant gaps by cross-referencing clawbolt OSS/premium with the porchsongs reference implementation.

…lti-tenant

Two fixes to support multi-tenant (premium) mode:

1. Pipeline override: add set_pipeline_override() and get_active_pipeline()
   to router.py so the premium plugin can inject quota-check and
   usage-tracking steps into the agent pipeline. Previously,
   handle_inbound_message() always used DEFAULT_PIPELINE, bypassing
   all premium quota enforcement.

2. Singleton user reuse guard: in _get_or_create_user(), skip the
   "reuse sole existing user" path when settings.premium_plugin is set.
   Without this guard, the first new Telegram sender in a multi-tenant
   deployment would have their messages linked to an existing user's
   account (data leak).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@njbrake njbrake merged commit ad08f73 into main Mar 17, 2026
9 checks passed
@njbrake njbrake deleted the fix/multi-tenant-pipeline-and-user-isolation branch March 17, 2026 21:25
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.

1 participant