A production-grade, policy-as-code middleware for FastMCP servers that uses macaroons for fine-grained, dynamic, and capability-based authorization.
Project description
MCP Macaroon Middleware
A production-grade, policy-as-code middleware for FastMCP servers that uses macaroons for fine-grained, dynamic, and capability-based authorization.
Table of Contents
Overview
mcp_macaroon_middleware is a robust and flexible policy-as-code middleware designed to secure FastMCP (Microservices Communication Protocol) servers using the power of macaroons. It provides fine-grained, dynamic, and capability-based authorization, allowing developers to define complex access control policies directly in code. This ensures that your microservices can enforce sophisticated security rules with minimal overhead, leveraging the decentralized and delegated authorization benefits of macaroons.
This middleware is ideal for applications requiring:
- Decentralized Authorization: Delegate authorization decisions without centralizing state.
- Fine-Grained Access Control: Specify precise permissions for specific actions and resources.
- Context-Aware Policies: Implement policies that adapt based on request context, macaroon caveats, and external data.
- Reduced Trust: Minimize the need for services to trust each other implicitly, as macaroons carry their own authorization logic.
Features
- Macaroon-Based Authorization: Leverages
pymacaroonsfor secure token handling. - Policy-as-Code: Define authorization policies using Python, offering flexibility and version control.
- FastMCP Integration: Seamlessly integrates with
fastmcpservers for request interception. - Dynamic Policy Enforcement: Policies can be updated and enforced without service restarts (depending on configuration).
- Redis Caching: Supports Redis for efficient caching of policy decisions and macaroon validation, improving performance.
- Extensible Policy Engine: Easily extendable to support custom caveat evaluators and enforcement logic.
- Detailed Error Handling: Provides clear exceptions for authorization failures, aiding in debugging and user feedback.
Installation
To install mcp_macaroon_middleware, use pip:
pip install mcp_macaroon_middleware
For development, you can install the development dependencies:
pip install "mcp_macaroon_middleware[dev]"
Usage
Integrating the middleware into your FastMCP server involves a few steps:
-
Define your Policies: Create Python modules that define your authorization policies. These policies will specify how macaroons are validated and what permissions they grant.
Example (
policies/my_service_policy.py):# policies/my_service_policy.py from mcp_macaroon_middleware.core.policy_engine import PolicyEngine from mcp_macaroon_middleware.models.caveat import Caveat from mcp_macaroon_middleware.policies.decorators import enforce @enforce("my_service:read_data") async def can_read_data(caveats: list[Caveat], context: dict) -> bool: """ Policy to check if the macaroon allows reading data. This is a simplified example; real policies would inspect caveats more deeply. """ for caveat in caveats: if "has_permission = read" == caveat.payload: return True return False @enforce("my_service:write_data") async def can_write_data(caveats: list[Caveat], context: dict) -> bool: """ Policy to check if the macaroon allows writing data. """ for caveat in caveats: if "has_permission = write" == caveat.payload: return True return False
-
Configure and Apply Middleware: Instantiate the
MacaroonMiddlewareand apply it to your FastMCP server.Example (
server.py):import asyncio from fastmcp.server import FastMCPServer from fastmcp.route import route from mcp_macaroon_middleware.core.middleware import MacaroonMiddleware from mcp_macaroon_middleware.config.loader import ConfigLoader from mcp_macaroon_middleware.policies.default_enforcers import METADATA_ENFORCER # Assuming you have a config.yaml or similar for policy paths and Redis # Example config: # --- # policy_directories: # - "./policies" # redis: # host: "localhost" # port: 6379 # db: 0 # --- # Load configuration (e.g., from examples/policies.yaml or a custom path) config = ConfigLoader().load_config() # Initialize the middleware with policy directories and optionally a Redis client middleware = MacaroonMiddleware( policy_directories=config.get("policy_directories", []), redis_config=config.get("redis") ) app = FastMCPServer() @app.route("greet", middleware=middleware) async def greet(name: str): # This route will be protected by the middleware. # The macaroon must satisfy policies configured for "greet" (or default ones). return f"Hello, {name}!" @app.route("secure_data", middleware=middleware.enforce("my_service:read_data")) async def secure_data(): # This route specifically requires the "my_service:read_data" capability return {"data": "This is highly sensitive information."} async def main(): await app.start() print("FastMCP server started on port 8000") if __name__ == "__main__": asyncio.run(main())
Note: The
METADATA_ENFORCERis a default enforcer that can be used directly or extended. -
Client-Side with Macaroons: On the client side, you would obtain a macaroon (e.g., from an authentication service) and attach it to your FastMCP requests.
Example (conceptual client interaction):
import httpx # Assuming you have a way to generate/obtain macaroons # from pymacaroons import Macaroon, MACAROON_V2 # m = Macaroon( # location='myloc', # identifier='we used this for an id', # key='this is our super secret key for signing', # version=MACAROON_V2 # ) # m.add_first_party_caveat('has_permission = read') # serialized_macaroon = m.serialize() async def make_request(macaroon_token: str): async with httpx.AsyncClient() as client: headers = {"Authorization": f"Bearer {macaroon_token}"} # Example for "greet" endpoint response = await client.post("http://localhost:8000/greet", json={"name": "World"}, headers=headers) print(response.json()) # Example for "secure_data" endpoint response = await client.post("http://localhost:8000/secure_data", headers=headers) print(response.json()) # asyncio.run(make_request(serialized_macaroon))
Configuration
The middleware can be configured via a YAML file (or other methods you integrate) to specify:
policy_directories: A list of paths where your policy modules are located. TheConfigLoaderwill automatically discover and load policies from these directories.redis: Configuration for the Redis client (host, port, db) for caching and session management.
Refer to examples/policies.yaml for a typical configuration structure.
Contributing
We welcome contributions! Please see our CONTRIBUTING.md for guidelines on how to contribute to this project.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_macaroon_middleware-1.1.0.tar.gz.
File metadata
- Download URL: mcp_macaroon_middleware-1.1.0.tar.gz
- Upload date:
- Size: 16.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47a04f9a60ca58869c72a360136a01a388e4aa704a4cf63addce9ccbf852e80b
|
|
| MD5 |
03e46259aa90fa8206327783c75bfb87
|
|
| BLAKE2b-256 |
bd864fc3279f1ee9d6324d6c4b06fede4821b86d96ffc9c275f3031c0071b952
|
Provenance
The following attestation bundles were made for mcp_macaroon_middleware-1.1.0.tar.gz:
Publisher:
release.yaml on indreshp135/CSE-227-OPENMCP
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_macaroon_middleware-1.1.0.tar.gz -
Subject digest:
47a04f9a60ca58869c72a360136a01a388e4aa704a4cf63addce9ccbf852e80b - Sigstore transparency entry: 722695394
- Sigstore integration time:
-
Permalink:
indreshp135/CSE-227-OPENMCP@099200c2394f23b2cfd1213cfe6c9b3e996decbe -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/indreshp135
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@099200c2394f23b2cfd1213cfe6c9b3e996decbe -
Trigger Event:
release
-
Statement type:
File details
Details for the file mcp_macaroon_middleware-1.1.0-py3-none-any.whl.
File metadata
- Download URL: mcp_macaroon_middleware-1.1.0-py3-none-any.whl
- Upload date:
- Size: 18.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
24e77030bbb182e50e131f3eab4180eff4be535cd1cb177ae43f4d87f74457c4
|
|
| MD5 |
157f1e4f2fb205f0b45049aa364dba8d
|
|
| BLAKE2b-256 |
3a996b3a17ae85c552dcc022c64ec3938d558e08d5ed2f8f04c09624e9a6efca
|
Provenance
The following attestation bundles were made for mcp_macaroon_middleware-1.1.0-py3-none-any.whl:
Publisher:
release.yaml on indreshp135/CSE-227-OPENMCP
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_macaroon_middleware-1.1.0-py3-none-any.whl -
Subject digest:
24e77030bbb182e50e131f3eab4180eff4be535cd1cb177ae43f4d87f74457c4 - Sigstore transparency entry: 722695430
- Sigstore integration time:
-
Permalink:
indreshp135/CSE-227-OPENMCP@099200c2394f23b2cfd1213cfe6c9b3e996decbe -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/indreshp135
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@099200c2394f23b2cfd1213cfe6c9b3e996decbe -
Trigger Event:
release
-
Statement type: