diff --git a/MANIFEST.in b/MANIFEST.in index 27b81c041..9812b408f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -169,7 +169,7 @@ exclude plugins/external/opa/.env.template exclude plugins/external/opa/.ruff.toml exclude plugins/external/opa/Containerfile exclude plugins/external/opa/MANIFEST.in -exclude plugins/external/opa/opaserver/rego/example.rego +exclude plugins/external/opa/opaserver/rego/policy.rego exclude plugins/external/opa/pyproject.toml exclude plugins/external/opa/run-server.sh @@ -179,6 +179,5 @@ exclude plugins/external/llmguard/.env.template exclude plugins/external/llmguard/.ruff.toml exclude plugins/external/llmguard/Containerfile exclude plugins/external/llmguard/MANIFEST.in -exclude plugins/external/llmguard/opaserver/rego/example.rego exclude plugins/external/llmguard/pyproject.toml exclude plugins/external/llmguard/run-server.sh diff --git a/plugins/external/opa/.env.template b/plugins/external/opa/.env.template index 6d9faf358..b46620b71 100644 --- a/plugins/external/opa/.env.template +++ b/plugins/external/opa/.env.template @@ -21,3 +21,6 @@ PLUGINS_CONFIG=./resources/plugins/config.yaml # Configuration path for chuck mcp runtime CHUK_MCP_CONFIG_PATH=./resources/runtime/config.yaml + +# Path to the repo policy file (optional, default: ./opaserver/rego/policy.rego) +# POLICY_PATH=./opaserver/rego/policy.rego diff --git a/plugins/external/opa/README.md b/plugins/external/opa/README.md index 12ba74e62..3c385411d 100644 --- a/plugins/external/opa/README.md +++ b/plugins/external/opa/README.md @@ -3,21 +3,40 @@ > Author: Shriti Priya > Version: 0.1.0 -An OPA plugin that enforces rego policies on requests and allows/denies requests as per policies. +An OPA (Open Policy Agent) plugin that enforces Rego policies on requests and allows or denies requests based on policy evaluation. The OPA plugin is composed of two components: -1. OPA server -2. The pre hooks on tools that talks to OPA server running as background service within the same container. Whenever a tool is invoked, if OPA Plugin is in action, a policy will be applied on the tool call to allow/deny it. +1. **OPA Server**: Runs as a background service evaluating policies +2. **Plugin Hooks**: Intercepts tool invocations and communicates with the OPA server for policy decisions + +Whenever a tool is invoked with the OPA Plugin active, a policy is applied to the tool call to allow or deny execution. ### OPA Server -To define a policy file you need to go into opaserver/rego and create a sample policy file for you. -Example -`example.rego` is present. -Once you have this file created in this location, when building the server, the opa binaries will be downloaded and a container will be build. -In the `run_server.sh` file, the opa server will run as a background service in the container with the rego policy file. +To define a policy file, create a Rego policy file in `opaserver/rego/`. An example `policy.rego` file is provided. + +When building the server, the OPA binaries will be downloaded and a container will be built. The `run_server.sh` script starts the OPA server as a background service within the container, loading the specified Rego policy file. ### OPA Plugin -The OPA plugin runs as an external plugin with pre/post tool invocations. So everytime, a tool invocation is made, and if OPAPluginFilter has been defined in config.yaml file, the tool invocation will pass through this OPA Plugin. +The OPA plugin runs as an external plugin with pre/post tool invocations. So everytime a tool invocation is made, and if OPAPluginFilter has been defined in config.yaml file, the tool invocation will pass through this OPA Plugin. + +## Configuration + +### MCP Server Container + +The following enviornment variables can be used to customize the server container deployment. + +- `API_SERVER_SCRIPT`: Path to the server script (optional, auto-detected) +- `PLUGINS_CONFIG_PATH`: Path to the plugin config (optional, default: ./resources/plugins/config.yaml) +- `CHUK_MCP_CONFIG_PATH`: Path to the chuck-mcp-runtime config (optional, default: ./resources/runtime/config.yaml) +- `POLICY_PATH`: Path to the repo policy file (optional, default: ./opaserver/rego/policy.rego) + +### MCP Runtime + +Changes to the MCP runtime configurations can be made in `resources/runtime/config.yaml`. + +### OPA Plugin Configuration +The OPA plugin and loader configuration can be customized in `resources/plugins/config.yaml`. ## Installation @@ -64,7 +83,7 @@ Under `extensions`, you can specify which policy to run and what endpoint to cal In the `config` key in `config.yaml` for the OPA plugin, the following attribute must be set to configure the OPA server endpoint: `opa_base_url` : It is the base url on which opa server is running. -3. Now suppose you have a sample policy in `example.rego` file that allows a tool invocation only when "IBM" key word is present in the repo_path. Add the sample policy file or policy rego file that you defined, in `plugins/external/opa/opaserver/rego`. +3. Now suppose you have a sample policy in `policy.rego` file that allows a tool invocation only when "IBM" key word is present in the repo_path. Add the sample policy file or policy rego file that you defined, in `plugins/external/opa/opaserver/rego`. 3. Once you have your plugin defined in `config.yaml` and policy added in the rego file, run the following commands to build your OPA Plugin external MCP server using: * `make build`: This will build a docker image named `opapluginfilter` diff --git a/plugins/external/opa/opaserver/rego/example.rego b/plugins/external/opa/opaserver/rego/policy.rego similarity index 100% rename from plugins/external/opa/opaserver/rego/example.rego rename to plugins/external/opa/opaserver/rego/policy.rego diff --git a/plugins/external/opa/run-server.sh b/plugins/external/opa/run-server.sh index d15cfe53c..9c4d1fb26 100755 --- a/plugins/external/opa/run-server.sh +++ b/plugins/external/opa/run-server.sh @@ -11,6 +11,7 @@ # API_SERVER_SCRIPT : Path to the server script (optional, auto-detected) # PLUGINS_CONFIG_PATH : Path to the plugin config (optional, default: ./resources/plugins/config.yaml) # CHUK_MCP_CONFIG_PATH : Path to the chuck-mcp-runtime config (optional, default: ./resources/runtime/config.yaml) +# POLICY_PATH : Path to the repo policy file (optional, default: ./opaserver/rego/policy.rego) # # Usage: # ./run-server.sh # Run server @@ -36,7 +37,7 @@ fi #──────────────────────────────────────────────────────────────────────────────── echo "Running OPA server" -opa run --server opaserver/rego/example.rego & +opa run --server "${POLICY_PATH:-opaserver/rego/policy.rego}" & #──────────────────────────────────────────────────────────────────────────────── # SECTION 2: Run the API server @@ -48,4 +49,4 @@ CHUK_MCP_CONFIG_PATH=${CHUK_MCP_CONFIG_PATH:-./resources/runtime/config.yaml} echo "✓ Using plugin config from: ${PLUGINS_CONFIG_PATH}" echo "✓ Running API server with config from: ${CHUK_MCP_CONFIG_PATH}" -python ${API_SERVER_SCRIPT} +python "${API_SERVER_SCRIPT}" diff --git a/tests/integration/test_translate_echo.py b/tests/integration/test_translate_echo.py index d48552889..ad4720458 100644 --- a/tests/integration/test_translate_echo.py +++ b/tests/integration/test_translate_echo.py @@ -436,6 +436,10 @@ async def stop(self): """Mock stop method - does nothing.""" self._proc = None + def is_running(self) -> bool: + """Check if the mock process is running.""" + return self._proc is not None and self._proc.returncode is None + stdio = MockStdio() app = _build_fastapi(pubsub, stdio)