How to Test and Verify MCP Server Project Isolation Security
Run the bundled test_project_isolation.py script or programmatically invoke get_current_project_id(), validate_resource_ownership(), and find_resource_by_name_or_id() from src/mcp_openstack_ops/connection.py to confirm that OpenStack resources remain strictly scoped to the authenticated project.
The call518/mcp-openstack-ops repository implements a Multi-Cloud Platform (MCP) server that enforces strict project isolation for OpenStack resources. Verifying these security measures ensures that users cannot access or manipulate resources belonging to other projects, even when querying by resource name or ID.
Understanding the Three-Layer Isolation Architecture
The MCP server enforces project isolation through three coordinated mechanisms implemented in src/mcp_openstack_ops/connection.py:
- Current-project identification – The
get_current_project_id()function (lines 43-73) extracts the project ID from the authenticated token or falls back to a lookup viaOS_PROJECT_NAME. - Ownership validation – The
validate_resource_ownership()function (lines 78-128) checks that every returned resource'sproject_idmatches the current project or is recognized as a public system resource. - Secure lookup – The
find_resource_by_name_or_id()function (lines 132-176) first gathers all name matches, then discards any resources that do not belong to the current project before returning results.
These functions work collectively to prevent cross-project data leakage at the connection, validation, and query layers.
Running the Built-in Verification Test
The repository includes test_project_isolation.py, an end-to-end test script that exercises all isolation layers. The script performs four logical verification groups: connection and project-ID sanity, resource ownership validation, service-level filtering, and secure resource lookup.
Prepare your environment and execute the test:
# Configure your OpenStack credentials
cp .env.example .env
echo "OS_PROJECT_NAME=mytestproject" >> .env
# Run the verification suite
python test_project_isolation.py
A successful verification outputs:
✅ All security tests passed!
✅ Project 'mytestproject' isolation verified
✅ Cross-project access prevention confirmed
If any step reports a mismatch, the isolation mechanism is compromised and the script exits with a failure code.
Programmatic Verification Methods
You can programmatically test MCP server project isolation by importing the core utilities and exercising the security boundary directly.
Validating Current Project Identification
Verify that the connection correctly identifies the scoped project:
from mcp_openstack_ops.connection import get_openstack_connection, get_current_project_id
conn = get_openstack_connection()
project_id = get_current_project_id()
print(f"Current project ID: {project_id}")
assert project_id is not None, "Failed to extract project ID from token"
According to the source code in src/mcp_openstack_ops/connection.py, this function inspects the authentication token and validates against the OS_PROJECT_NAME environment variable to ensure the session operates under the expected project scope.
Checking Resource Ownership
Iterate through compute, network, and storage resources to confirm ownership validation:
from mcp_openstack_ops.connection import validate_resource_ownership
# Verify compute instances
for instance in conn.compute.servers():
is_owned = validate_resource_ownership(instance, "Instance")
assert is_owned, f"Instance {instance.id} failed ownership check"
# Verify networks
for network in conn.network.networks():
is_owned = validate_resource_ownership(network, "Network")
print(f"Network {network.name}: {'Owned' if is_owned else 'REJECTED'}")
The validate_resource_ownership() function compares each resource's project_id attribute against the current project ID, returning False for any resource outside the authorized scope.
Testing Secure Resource Lookup
Attempt to locate resources by common names (e.g., admin, public) that might exist across multiple projects:
from mcp_openstack_ops.connection import find_resource_by_name_or_id
# Attempt to find an instance named "admin" (likely exists in another project)
resource = find_resource_by_name_or_id(
conn.compute.servers(),
"admin",
"Instance"
)
if resource is None:
print("Secure lookup correctly prevented cross-project access")
else:
print(f"Security leak detected: Found instance {resource.id} in another project")
This test verifies that find_resource_by_name_or_id() filters results by project ownership after retrieval, ensuring that name collisions across projects do not result in unauthorized access.
Verifying Service-Level Scoping
High-level service helpers in the MCP server automatically enforce project isolation. Test these wrappers to ensure they return only project-scoped data:
from mcp_openstack_ops.services.compute import get_instance_details
from mcp_openstack_ops.services.network import get_network_details
from mcp_openstack_ops.services.storage import get_volume_list
# Each helper internally calls ownership validation
instances = get_instance_details(limit=5)
networks = get_network_details()
volumes = get_volume_list()
# Verify no foreign resources appear
for instance in instances['instances']:
assert instance['project_id'] == project_id, "Cross-project instance leak"
print(f"Verified isolation: {instances['count']} instances, {len(networks)} networks, {len(volumes)} volumes")
The service modules (src/mcp_openstack_ops/services/compute.py, network.py, and storage.py) utilize the core validation functions to ensure all returned collections are pre-filtered by project ID.
Summary
get_current_project_id()insrc/mcp_openstack_ops/connection.pyestablishes the security context by binding the session to a specific OpenStack project ID.validate_resource_ownership()acts as the gatekeeper, rejecting any resource where theproject_idattribute does not match the current session.find_resource_by_name_or_id()prevents name-squatting attacks by filtering lookup results post-query to exclude foreign project resources.test_project_isolation.pyprovides a comprehensive, automated verification suite that exercises all isolation layers against live OpenStack APIs.- Service helpers in
compute.py,network.py, andstorage.pyembed these checks automatically, ensuring project isolation is maintained across all MCP server operations.
Frequently Asked Questions
What happens if the MCP server fails project isolation validation?
If the test_project_isolation.py script detects a resource with a mismatched project_id, or if find_resource_by_name_or_id() returns a resource from another project, the test fails immediately with an assertion error. This indicates a security vulnerability where the server might expose resources across project boundaries, requiring immediate review of the validation logic in src/mcp_openstack_ops/connection.py.
Can I test project isolation without the bundled test script?
Yes. Import the core functions from mcp_openstack_ops.connection and manually verify isolation by attempting to access resources across project boundaries. Use validate_resource_ownership() on each returned object, or attempt to lookup commonly named resources in other projects using find_resource_by_name_or_id(). Any return of a foreign resource indicates a security failure.
How does the MCP server handle resources with the same name in different projects?
The find_resource_by_name_or_id() function retrieves all resources matching the provided name or ID, then iterates through the results to find the first entry where validate_resource_ownership() returns True. This ensures that even if multiple projects contain resources with identical names, the function returns only the resource belonging to the currently authenticated project, effectively preventing cross-project enumeration.
Where are the service-level isolation checks implemented?
The service wrappers in src/mcp_openstack_ops/services/compute.py, src/mcp_openstack_ops/services/network.py, and src/mcp_openstack_ops/services/storage.py implement project isolation by calling the core validation utilities. For example, get_instance_details() internally uses validate_resource_ownership() to filter the compute instances returned by the OpenStack API, ensuring the final payload contains only resources owned by the current project.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →