Skip to content

Add tenant isolation for Crew storage (Redis, Manager, Handlers)#549

Merged
phenobarbital merged 11 commits intoui-implementationfrom
codex/add-tenant-attribute-to-crew
Feb 4, 2026
Merged

Add tenant isolation for Crew storage (Redis, Manager, Handlers)#549
phenobarbital merged 11 commits intoui-implementationfrom
codex/add-tenant-attribute-to-crew

Conversation

@phenobarbital
Copy link
Owner

Motivation

  • Support multi-tenant segmentation for AgentCrew so crews can be isolated, listed, filtered and persisted per-tenant.
  • Preserve backward compatibility for existing global crews while introducing an explicit tenant attribute and tenant-aware storage.

Description

  • Add tenant: str = "global" to CrewDefinition so every crew carries a tenant scope. (parrot/handlers/crew/models.py)
  • Make Redis persistence tenant-aware by namespacing keys as crew:{tenant}:{name} and crew:{tenant}:id:{crew_id}, tracking tenants in crew:tenants, and keeping legacy global fallbacks for old keys. (parrot/handlers/crew/redis_persistence.py)
  • Expose new tenant-aware operations in the persistence layer: load_crew(name, tenant), load_crew_by_id(crew_id, tenant), delete_crew(name, tenant), list_crews(tenant), list_all_crews(), get_all_crews(tenant), crew_exists(name, tenant), and metadata methods that include tenant. (parrot/handlers/crew/redis_persistence.py)
  • Thread tenant through the CRUD and execution endpoints so API calls can pass or query tenant and responses include tenant. (parrot/handlers/crew/handler.py, parrot/handlers/crew/execution_handler.py)
  • Update BotManager in-memory cache to use tenant-prefixed cache keys, and make manager operations (add_crew, get_crew, list_crews, remove_crew, update_crew, load_crews, sync_crews) tenant-aware. (parrot/manager/manager.py)
  • Ensure running jobs persist tenant in job metadata so execution context can be restored or referenced. (parrot/handlers/crew/execution_handler.py)

Testing

  • No automated tests were run as part of this change; unit/integration tests were not executed.
  • The changes preserve legacy behavior for global crews via fallback keys in Redis and should be covered by adding tenant-focused unit/integration tests in follow-ups.

Codex Task

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request introduces tenant isolation for AgentCrew storage across Redis, BotManager, and HTTP handlers. The changes enable multi-tenant segmentation while preserving backward compatibility with existing global crews through legacy key fallbacks.

Changes:

  • Added tenant field to CrewDefinition with default value "global" for backward compatibility
  • Implemented tenant-aware Redis key namespacing (crew:{tenant}:{name}) with legacy fallback support for existing keys
  • Extended BotManager cache to use tenant-prefixed keys and made all crew operations tenant-aware
  • Updated CRUD and execution endpoints to accept and propagate tenant parameters through the request/response cycle

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 20 comments.

Show a summary per file
File Description
parrot/handlers/crew/models.py Adds tenant field to CrewDefinition with "global" default
parrot/handlers/crew/redis_persistence.py Implements tenant-aware key namespacing, legacy fallbacks, and multi-tenant listing operations
parrot/manager/manager.py Updates in-memory cache to use tenant-prefixed keys and makes all crew operations tenant-aware
parrot/handlers/crew/handler.py Threads tenant parameter through GET, PUT, DELETE endpoints and includes in responses
parrot/handlers/crew/execution_handler.py Extracts tenant from execution requests and persists in job metadata

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

qs = self.get_arguments(self.request)
crew_id = match_params.get('id') or qs.get('crew_id')
crew_name = qs.get('name')
tenant = qs.get('tenant') or "global"
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The tenant parameter defaults to "global" when not provided, which mirrors the same issue in the GET handler. In a multi-tenant system, silently defaulting to "global" could lead to accidental deletion of global tenant crews when the client intended to delete from a specific tenant but forgot the parameter. Consider making tenant a required parameter or at least validating/logging when the default is used.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

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

@copilot open a new pull request to apply changes based on this feedback

qs = self.get_arguments(self.request)
crew_id = match_params.get('id') or qs.get('crew_id')
crew_name = qs.get('name')
tenant = qs.get('tenant') or "global"
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

Similar to the GET handler, the tenant parameter from the query string is not validated or sanitized. This creates a security risk where malicious tenant values could be used to construct invalid Redis keys or potentially access data from other tenants if the key construction is vulnerable to injection. Implement tenant validation to ensure only safe, expected tenant identifiers are accepted.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Copilot AI commented Feb 4, 2026

@phenobarbital I've opened a new pull request, #552, to work on those changes. Once the pull request is ready, I'll request review from you.

phenobarbital and others added 2 commits February 4, 2026 16:29
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Feb 4, 2026

@phenobarbital I've opened a new pull request, #553, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Contributor

Copilot AI commented Feb 4, 2026

@phenobarbital I've opened a new pull request, #554, to work on those changes. Once the pull request is ready, I'll request review from you.

phenobarbital and others added 6 commits February 4, 2026 16:30
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…-one

[WIP] Address feedback on tenant isolation for Crew storage implementation
[WIP] WIP Address feedback on tenant isolation for Crew storage
[WIP] WIP Address feedback on tenant isolation for Crew storage implementation
@phenobarbital phenobarbital merged commit 0cc4416 into ui-implementation Feb 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants