Skip to content

feat: add TRELLO_ALLOWED_WORKSPACES env var for workspace restriction - #61

Merged
delorenj merged 2 commits into
delorenj:mainfrom
nathanschram:feature/workspace-restriction
May 23, 2026
Merged

delorenj merged 2 commits into
delorenj:mainfrom
nathanschram:feature/workspace-restriction

Conversation

@nathanschram

Copy link
Copy Markdown

Summary

Add optional workspace access restriction via the TRELLO_ALLOWED_WORKSPACES environment variable. This allows administrators to limit which Trello workspaces can be accessed via MCP tools.

Use cases:

  • Security: Limiting AI agent access to only approved workspaces
  • Multi-tenant setups: Ensuring agents only access relevant workspaces
  • Testing: Isolating test environments from production data

Changes

  • Added allowedWorkspaceIds?: string[] to TrelloConfig interface
  • Added workspace filtering/validation methods to TrelloClient:
    • hasWorkspaceRestriction getter
    • isWorkspaceAllowed(workspaceId) method
    • validateWorkspaceAccess(workspaceId) private method
  • Modified these methods to enforce workspace restrictions:
    • listWorkspaces() - filters results to allowed workspaces only
    • listBoards() - filters boards by allowed workspaces
    • setActiveWorkspace() - validates workspace ID before setting
    • listBoardsInWorkspace() - validates workspace ID before fetching
    • createBoard() - validates target workspace before creating
  • Parse TRELLO_ALLOWED_WORKSPACES env var (comma-separated) in index.ts
  • Updated README with documentation

Configuration

# Only allow access to specific workspaces (comma-separated IDs)
TRELLO_ALLOWED_WORKSPACES=workspace-id-1,workspace-id-2

If not set or empty, all workspaces the token has access to will be available (backwards compatible).

Test plan

  • Build project with bun run build
  • Test with TRELLO_ALLOWED_WORKSPACES set to a single workspace ID
  • Verify list_workspaces only returns the allowed workspace
  • Verify set_active_workspace rejects non-allowed workspace IDs
  • Verify list_boards only shows boards from allowed workspaces
  • Test without TRELLO_ALLOWED_WORKSPACES to confirm backwards compatibility

🤖 Generated with Claude Code

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @nathanschram, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a crucial security and organizational feature by allowing administrators to define a whitelist of Trello workspaces accessible through the MCP tools. By introducing the TRELLO_ALLOWED_WORKSPACES environment variable, the system can now enforce strict access controls, ensuring that AI agents or other automated processes only interact with approved workspaces. This prevents accidental data exposure, facilitates multi-tenant environments, and provides better isolation for testing purposes, ultimately enhancing the robustness and security of Trello integrations.

Highlights

  • Workspace Access Restriction: Introduced a new optional environment variable, TRELLO_ALLOWED_WORKSPACES, to restrict Trello client operations to a predefined set of workspaces.
  • Configuration: The TRELLO_ALLOWED_WORKSPACES environment variable accepts a comma-separated list of Trello workspace IDs. If not set, all workspaces accessible by the token remain available.
  • Client Method Enforcement: Modified several TrelloClient methods (listWorkspaces, listBoards, setActiveWorkspace, listBoardsInWorkspace, createBoard) to filter results or validate access against the allowed workspaces list.
  • Documentation: Updated the README.md to include details on how to configure and use the new workspace access restriction feature, along with its benefits.
Changelog
  • README.md
    • Added TRELLO_ALLOWED_WORKSPACES to the environment variable configuration example.
    • Included a new section 'Workspace Access Restriction' detailing its purpose, use cases, and impact on various Trello client methods.
    • Provided an example configuration snippet for the new environment variable.
    • Clarified the default behavior when TRELLO_ALLOWED_WORKSPACES is not set.
  • src/index.ts
    • Added logic to read the TRELLO_ALLOWED_WORKSPACES environment variable.
    • Implemented parsing of the comma-separated string into an array of workspace IDs.
    • Passed the parsed allowedWorkspaceIds to the TrelloClient constructor.
  • src/trello-client.ts
    • Added a private allowedWorkspaceIds?: string[] property to store the allowed workspace IDs.
    • Initialized allowedWorkspaceIds in the constructor from the TrelloConfig.
    • Introduced a hasWorkspaceRestriction getter to quickly check if restrictions are active.
    • Created isWorkspaceAllowed(workspaceId: string) to verify if a given workspace ID is permitted.
    • Implemented private validateWorkspaceAccess(workspaceId: string) to throw an McpError for unauthorized access.
    • Modified setActiveWorkspace to include a call to validateWorkspaceAccess.
    • Updated listBoards to filter the returned boards, showing only those from allowed workspaces.
    • Adjusted listWorkspaces to filter the returned workspaces based on the allowed list.
    • Integrated validateWorkspaceAccess into listBoardsInWorkspace.
    • Enhanced createBoard to validate the target workspace using validateWorkspaceAccess before creation.
  • src/types.ts
    • Added allowedWorkspaceIds?: string[] to the TrelloConfig interface, along with a JSDoc comment explaining its purpose.
Activity
  • No human activity (comments, reviews, etc.) has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2b0683fac7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/trello-client.ts
Comment on lines +296 to +301
// Determine the target workspace
const targetWorkspace = params.idOrganization ?? this.activeConfig.workspaceId;

// Validate workspace access if a workspace is specified and restrictions are enabled
if (targetWorkspace && this.hasWorkspaceRestriction) {
this.validateWorkspaceAccess(targetWorkspace);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Block create_board when no workspace is set

When TRELLO_ALLOWED_WORKSPACES is configured, createBoard only validates if targetWorkspace is truthy, so a caller who omits idOrganization (and has no active workspace set) skips the restriction entirely. In that scenario, Trello will create a personal board (no organization), which violates the “only allowed workspaces” guarantee described in the README. Consider rejecting creation when restrictions are enabled and no workspace is specified/active, or forcing an allowed workspace ID.

Useful? React with 👍 / 👎.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a valuable feature for restricting access to specific Trello workspaces via an environment variable. The implementation is well-structured, with robust parsing of the configuration and clear validation logic integrated into the TrelloClient. My review includes a few suggestions: one to fix a potential runtime error when filtering boards not associated with a workspace, another to correct a misleading example in the documentation, and a minor refactoring to improve code maintainability by removing a redundant property. Overall, this is a solid contribution that enhances the security and configurability of the tool.

Comment thread src/trello-client.ts Outdated

// Filter by allowed workspaces if restriction is enabled
if (this.hasWorkspaceRestriction) {
return boards.filter(board => this.isWorkspaceAllowed(board.idOrganization));

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.

high

The board.idOrganization property can be null for personal boards that don't belong to any workspace, but isWorkspaceAllowed expects a string. Passing null could lead to unexpected behavior or runtime errors. You should handle the null case to ensure personal boards are correctly filtered out when workspace restrictions are active.

It would also be beneficial to update the TrelloBoard type definition in src/types.ts to idOrganization: string | null; to reflect the Trello API response accurately, though that file is not part of this PR's changes.

Suggested change
return boards.filter(board => this.isWorkspaceAllowed(board.idOrganization));
return boards.filter(board => board.idOrganization && this.isWorkspaceAllowed(board.idOrganization));

Comment thread README.md Outdated
Example configuration:
```bash
# Only allow access to two specific workspaces
TRELLO_ALLOWED_WORKSPACES=697c549ce04dc460af133a75,5f8a3b2c1d4e5f6g7h8i9j0k

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.

medium

The example workspace ID 5f8a3b2c1d4e5f6g7h8i9j0k appears to be invalid. Trello IDs are typically 24-character hexadecimal strings, but this example is 23 characters long and contains non-hexadecimal characters (g, h, i, j, k). Using a realistic example will prevent confusion for users configuring this feature.

Suggested change
TRELLO_ALLOWED_WORKSPACES=697c549ce04dc460af133a75,5f8a3b2c1d4e5f6g7h8i9j0k
TRELLO_ALLOWED_WORKSPACES=697c549ce04dc460af133a75,5f8a3b2c1d4e5f6a7b8c9d0e

Comment thread src/trello-client.ts Outdated
private rateLimiter;
private defaultBoardId?: string;
private activeConfig: TrelloConfig;
private allowedWorkspaceIds?: string[];

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.

medium

The allowedWorkspaceIds property is redundant. The constructor already takes private config: TrelloConfig, which makes this.config available throughout the class. You can directly use this.config.allowedWorkspaceIds instead of storing this value in a separate property. This will make the code cleaner and avoid data duplication.

To apply this change:

  1. Remove this property (allowedWorkspaceIds).
  2. Remove its assignment in the constructor (line 55).
  3. Update hasWorkspaceRestriction, isWorkspaceAllowed, and validateWorkspaceAccess to use this.config.allowedWorkspaceIds.

@delorenj

Copy link
Copy Markdown
Owner

Solid feature — workspace allowlisting is a real security knob for multi-tenant agent setups. Asking for:

  1. Rebase against latest main (merges to src/index.ts / src/trello-client.ts / src/types.ts).
  2. One test. The repo now uses vitest (bun run test:unit); a small unit test asserting hasWorkspaceRestriction returns false when the env var is empty/unset, and that assertWorkspaceAllowed throws when given a non-allowed id, would lock the behavior in.
  3. Tool-description hint. When the restriction is active and the agent calls list_workspaces, the response should ideally still surface that filtering is happening (otherwise an LLM can't explain to its user why a workspace it knows about isn't visible). A one-line note in the tool's description covering this would be nice.

Once rebased + a test, happy to merge. Thanks.

Nathan Schram and others added 2 commits May 22, 2026 23:13
Add optional workspace access restriction to limit which Trello workspaces
can be accessed via MCP tools. This is useful for:
- Security: Limiting AI agent access to only approved workspaces
- Multi-tenant setups: Ensuring agents only access relevant workspaces
- Testing: Isolating test environments from production data

When TRELLO_ALLOWED_WORKSPACES is set (comma-separated IDs):
- list_workspaces only returns workspaces in the allowed list
- list_boards only returns boards from allowed workspaces
- set_active_workspace rejects workspaces not in the allowed list
- list_boards_in_workspace rejects non-allowed workspace IDs
- create_board rejects creation in non-allowed workspaces

If not set or empty, all workspaces remain accessible (default behaviour).

Co-Authored-By: Claude <noreply@anthropic.com>
- Block createBoard when restrictions enabled but no workspace set
  (prevents bypassing restriction by creating personal boards)
- Handle null idOrganization in listBoards filter
  (personal boards without a workspace could cause runtime errors)
- Fix invalid example workspace ID in README
  (use valid 24-char hex string instead of non-hex characters)
- Remove redundant allowedWorkspaceIds property
  (use this.config.allowedWorkspaceIds directly)

Co-Authored-By: Claude <noreply@anthropic.com>
@delorenj
delorenj force-pushed the feature/workspace-restriction branch from a9a22bc to b27626a Compare May 23, 2026 03:13
@delorenj
delorenj merged commit aa9558b into delorenj:main May 23, 2026
1 check passed
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.

2 participants