How MCP-OpenStack-Ops Ensures Project Isolation and Tenant Security at the Operational Level
MCP-OpenStack-Ops enforces strict project isolation by embedding security checks directly into the OpenStack SDK connection layer, ensuring every resource operation validates ownership against the authenticated tenant ID before execution.
The call518/mcp-openstack-ops repository implements a defense-in-depth security model that prevents cross-tenant resource leakage across compute, network, storage, and identity services. By centralizing project scoping logic in the connection layer, the framework guarantees that no operation can unintentionally access resources belonging to another tenant, even if underlying SDK configurations vary.
Core Security Architecture in the Connection Layer
All tenant security guarantees originate in src/mcp_openstack_ops/connection.py, which exposes three critical mechanisms used uniformly across every service module.
Current Project Identification
The get_current_project_id() function extracts the authenticated project ID from the OpenStack token or performs a fallback name-lookup, making the tenant context globally available to all subsequent operations.
- Source location:
connection.py#L43-L71 - Return value: The active project ID string used for all ownership comparisons
- Usage pattern: Stored in
conn.current_project_idand referenced by identity and network services
Resource Ownership Validation
The validate_resource_ownership(resource, resource_type) function compares the project_id or tenant_id of any OpenStack resource against the current project ID. Public resources (flavors, public images) bypass validation via an is_public flag, while any project mismatch triggers a warning and returns false.
- Source location:
connection.py#L78-L106 - Security behavior: Returns boolean ownership status; logs warnings on cross-tenant access attempts
- Public resource handling: Automatically allows shared resources like flavors and public images
Secure Lookup Helpers
The find_resource_by_name_or_id() and get_project_scoped_resources() functions combine resource discovery with immediate ownership validation. These helpers first locate resources by name or ID, then invoke validate_resource_ownership() to ensure only tenant-owned resources are returned to service modules.
- Source location:
connection.py#L124-L165 - Validation chain: Every lookup automatically filters cross-tenant resources before they reach business logic
- Error handling: Returns
Nonefor inaccessible resources, preventing accidental operations
Service-Level Isolation Enforcement
All service implementations import these connection-layer helpers and apply them before any Create, Read, Update, or Delete (CRUD) operation.
Compute Service Isolation
In src/mcp_openstack_ops/services/compute.py, the get_instance_details() function retrieves servers using conn.compute.servers(details=True, all_projects=False), then explicitly validates each instance:
- Validation call:
validate_resource_ownership(server, "Instance")for every server object - Source location:
compute.py#L48-L61 - Filtering logic: Only instances passing the ownership test are included in the final result set
Identity and Network Security
The identity service functions (get_user_list(), get_role_assignments(), set_project()) rely on conn.current_project_id to filter role assignments and project-specific actions. Similarly, network, storage, image, monitoring, and load-balancer services use get_current_project_id() or get_project_scoped_resources() to scope all listings and modifications to the active tenant.
- Identity enforcement:
identity.py#L133-L197 - Cross-service consistency: Every
set_*andget_*function exposes a tenant-aware interface without requiring manual filter parameters
Automated Security Verification
The project isolation mechanisms are continuously validated by test_project_isolation.py, which confirms:
- Successful connection establishment and project ID extraction
- Ownership validation on instances, networks, and volumes
- Secure lookup behavior proving cross-tenant resources remain invisible
- Test coverage:
test_project_isolation.py#L42-L63 - Verification method: Automated assertions that
validate_resource_ownership()returnsFalsefor non-owned resources
Practical Implementation Examples
The following patterns demonstrate how MCP-OpenStack-Ops maintains tenant security in production code:
from mcp_openstack_ops.connection import (
get_current_project_id,
validate_resource_ownership,
find_resource_by_name_or_id,
)
# Retrieve the authenticated project ID used for all ownership checks
project_id = get_current_project_id()
print(f"Current project ID: {project_id}")
# Validate instance ownership before processing
from mcp_openstack_ops.services.compute import get_instance_details
instances = get_instance_details(limit=5)["instances"]
for inst in instances:
is_owned = validate_resource_ownership(inst, "Instance")
print(f"Instance {inst['name']} owned by tenant: {is_owned}")
# Securely lookup network by name with automatic tenant validation
from mcp_openstack_ops.services.network import get_network_details
network = find_resource_by_name_or_id(
conn.network.networks(),
"private-net",
"Network",
)
if network:
print(f"Network {network.name} accessible in current tenant")
else:
print("Network not found or belongs to different project")
Summary
- Centralized validation: All tenant security logic resides in
src/mcp_openstack_ops/connection.py, preventing code duplication and inconsistent enforcement. - Explicit ownership checks: The
validate_resource_ownership()function compares resourceproject_idagainst the authenticated tenant for every operation. - Secure lookup abstraction: Helper functions
find_resource_by_name_or_id()andget_project_scoped_resources()combine discovery with validation, ensuring only owned resources are returned. - Public resource bypass: Shared resources like flavors and public images are automatically allowed while tenant-specific data remains protected.
- Automated testing:
test_project_isolation.pycontinuously verifies that cross-tenant access is impossible across compute, network, and storage services.
Frequently Asked Questions
How does MCP-OpenStack-Ops prevent accidental access to other tenants' resources?
MCP-OpenStack-Ops implements explicit resource ownership validation in validate_resource_ownership(), which compares the project_id of every OpenStack resource against the authenticated tenant ID extracted by get_current_project_id(). This check runs automatically through secure lookup helpers before any resource is returned to service logic, ensuring cross-tenant resources are filtered out regardless of SDK configuration.
What happens when the system encounters a public resource like a shared flavor or image?
Public resources are automatically allowed through the ownership validation layer. The validate_resource_ownership() function detects the is_public flag on resources like flavors and public images, bypassing the project ID comparison while still protecting tenant-specific data. This preserves standard OpenStack behavior for shared infrastructure components.
Can service developers accidentally bypass the project isolation mechanisms?
No. All high-level service functions (compute, network, storage, identity) import and use the secure lookup helpers (find_resource_by_name_or_id, get_project_scoped_resources) from connection.py. These helpers enforce validation automatically, so developers cannot return unvalidated resources without explicitly circumventing the entire service architecture.
How is the project isolation security model tested and verified?
The repository includes test_project_isolation.py, which automates verification that only resources matching the authenticated project ID are accessible. The test suite exercises get_current_project_id(), validate_resource_ownership(), and the secure lookup helpers across instances, networks, and volumes to confirm that cross-tenant resources remain invisible and inaccessible.
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 →