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_id and 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 None for 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_* and get_* 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:

  1. Successful connection establishment and project ID extraction
  2. Ownership validation on instances, networks, and volumes
  3. 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() returns False for 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 resource project_id against the authenticated tenant for every operation.
  • Secure lookup abstraction: Helper functions find_resource_by_name_or_id() and get_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.py continuously 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →