Skip to content

Commit d2fa7f1

Browse files
authored
Merge pull request #2 from oracle-samples/rigebha/policy
feat: add policy evaluation example
2 parents 3b81b0a + 3218542 commit d2fa7f1

File tree

15 files changed

+949
-1
lines changed

15 files changed

+949
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ Prototypes and proofs-of-concept
66

77
| Project | Description |
88
|---------|-------------|
9-
| [server](./server) | Example of MCP authentication using OCI IDCS and Oauth |
109
| [agent](./agent) | An example agent developed using LangGraph that drives the OCI CLI |
10+
| [policy](./policy) | Demonstration of out-of-band policy enforcement for MCP servers/tools |
11+
| [server](./server) | Example of MCP authentication using OCI IDCS and OAuth |
1112

1213
## Contributing
1314

agent/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ curl -s --request POST \
5757
--header 'Content-Type: application/json' \
5858
--data @payload.json
5959
```
60+
## License
61+
Copyright (c) 2025 Oracle and/or its affiliates.
62+
63+
Released under the Universal Permissive License v1.0 as shown at
64+
<https://oss.oracle.com/licenses/upl/>.
65+
66+
## Third-Party APIs
67+
68+
Developers choosing to distribute a binary implementation of this project are responsible for obtaining and providing all required licenses and copyright notices for the third-party code used in order to ensure compliance with their respective open source licenses.
69+
6070
## Disclaimer
6171

6272
Users are responsible for their local environment and credential safety. Different language model selections

policy/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.venv/
2+
venv/
3+
bundles/

policy/.mcphost/hooks.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
hooks:
2+
PreToolUse:
3+
- matcher: "oci_*"
4+
hooks:
5+
- type: command
6+
command: "uv run ./hooks/opa.py"

policy/.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13

policy/Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.PHONY: all build test test clean
2+
3+
all: build
4+
5+
build:
6+
mkdir -p bundles
7+
opa build -o bundles/bundle.tar.gz policies
8+
9+
test: .
10+
opa test -v policies
11+
12+
clean:
13+
rm -rf bundles/*

policy/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Policy
2+
3+
Demonstration of out-of-band policy enforcement for MCP servers/tools
4+
5+
## Getting started
6+
7+
### Install dependencies
8+
```bash
9+
brew install ollama python3 uv go opa podman podman-compose
10+
```
11+
12+
### Create container VM for running containers via podman
13+
```bash
14+
podman machine init
15+
podman machine start
16+
```
17+
18+
### Build policies
19+
```
20+
make build
21+
```
22+
23+
### Install Ollama and fetch model
24+
25+
Where `$MODEL` is the name of the model you prefer (ex: `gpt-oss`)
26+
27+
```bash
28+
ollama pull $MODEL
29+
```
30+
31+
### Install mcphost
32+
```bash
33+
go install github.com/mark3labs/mcphost@latest
34+
export PATH=$PATH:~/.go/bin
35+
```
36+
37+
### Authenticate
38+
39+
```bash
40+
oci session authenticate --profile-name <profile name, ex: DEFAULT> --region <region name: us-sanjose-1>
41+
```
42+
43+
### Start external policy engine (Open Policy Agent)
44+
```bash
45+
podman compose up -d
46+
```
47+
48+
### Run mcphost
49+
50+
Where `$MODEL` is the name of the model you prefer (ex: `gpt-oss`)
51+
52+
```bash
53+
OCI_CONFIG_PROFILE=<profile name, ex: DEFAULT> mcphost -m ollama:$MODEL --config ./mcp.json
54+
```
55+
56+
You can now interact with the servers via the mcphost prompt:
57+
58+
```
59+
what tools are available to you?
60+
```
61+
or
62+
```
63+
list my instances
64+
```
65+
66+
## Testing
67+
68+
```bash
69+
make test
70+
```

policy/compose.yaml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
version: "2"
2+
services:
3+
opa:
4+
image: openpolicyagent/opa:latest
5+
ports:
6+
- 8181:8181
7+
# WARNING: OPA is NOT running with an authorization policy configured. This
8+
# means that clients can read and write policies in OPA. If you are
9+
# deploying OPA in an insecure environment, be sure to configure
10+
# authentication and authorization on the daemon. See the Security page for
11+
# details: https://www.openpolicyagent.org/docs/security.html.
12+
command:
13+
- "run"
14+
- "--server"
15+
- "--addr=0.0.0.0:8181"
16+
- "--log-format=json-pretty"
17+
- "--set=decision_logs.console=true"
18+
- "--set=services.nginx.url=http://bundle_server"
19+
- "--set=bundles.nginx.service=nginx"
20+
- "--set=bundles.nginx.resource=bundles/bundle.tar.gz"
21+
depends_on:
22+
- bundle_server
23+
api_server:
24+
image: openpolicyagent/demo-restful-api:0.3
25+
ports:
26+
- 5000:5000
27+
environment:
28+
- OPA_ADDR=http://opa:8181
29+
- POLICY_PATH=/v1/data/httpapi/authz
30+
depends_on:
31+
- opa
32+
bundle_server:
33+
image: nginx:1.20.0-alpine
34+
ports:
35+
- 8888:80
36+
volumes:
37+
- ./bundles:/usr/share/nginx/html/bundles

policy/hooks/opa.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import json
2+
import sys
3+
4+
from opa_client.opa import OpaClient
5+
6+
# Initialize the OPA client
7+
client = OpaClient(host="localhost", port=8181)
8+
9+
# Evaluate a policy
10+
input_data = json.load(sys.stdin)
11+
result = client.query_rule(input_data=input_data, package_path="mcp", rule_name="allow")
12+
print(input_data)
13+
14+
print(result)
15+
16+
# Print the decision
17+
if result.get("result"):
18+
print("Access granted.")
19+
sys.exit(0)
20+
else:
21+
print("Access denied.")
22+
sys.exit(2)

policy/mcp.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"mcpServers": {
3+
"oracle-oci-api-mcp-server": {
4+
"command": "uvx",
5+
"args": [
6+
"oracle.oci-api-mcp-server"
7+
],
8+
"transport": "stdio"
9+
}
10+
}
11+
}

0 commit comments

Comments
 (0)