mrapids 0.1.31

Your OpenAPI, but executable
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# MCP Policy Integration

## Overview

This document describes how the Policy Engine integrates with the MCP (Model Context Protocol) server to provide **agent access control** following the **Semantic + Guidance** pattern.

---

## Core Principle: Proactive Policy Disclosure

The agent learns about policy restrictions **upfront**, not reactively after failures.

```
Traditional (Reactive):
Agent → api_preview → 403 Denied → "What happened?"

Semantic + Guidance (Proactive):
Agent → api_help → "Policy: 3 rules, only GET/HEAD/OPTIONS allowed"
Agent → api_show → "This DELETE operation is blocked by policy"
Agent → (knows not to try DELETE operations)
```

---

## Policy File Locations

The MCP server auto-detects policy files in this priority order:

| Priority | Location | Description |
|----------|----------|-------------|
| 1 | `--policy <path>` | Explicit CLI flag |
| 2 | `.mrapids/policy.yaml` | Project-local |
| 3 | `.mrapids/policy.toml` | Project-local (TOML) |
| 4 | `policy.yaml` | Current directory |
| 5 | `policy.toml` | Current directory |

### Startup Behavior

```bash
# With policy file found:
[MCP] Policy auto-loaded from: .mrapids/policy.yaml

# Without policy file:
[MCP] No policy file found, running in permissive mode
```

---

## Policy in Semantic + Guidance

### Where Policy Appears

| MCP Tool | Policy Information | Purpose |
|----------|-------------------|---------|
| `api_help` | Full policy summary | Agent learns restrictions upfront |
| `api_auth` | Policy status with auth | Combined security view |
| `api_show` | Per-operation policy status | Check before attempting |
| `api_preview` | Blocker if denied | Enforcement gate 1 |
| `api_run` | Blocker if denied | Enforcement gate 2 (defense in depth) |

---

## Response Examples

### 1. api_help (Policy Active)

```json
{
  "data": {
    "version": "0.1.30",
    "commands": [...],
    "workflow": [...],
    "policy": {
      "active": true,
      "name": "petstore-agent-policy",
      "rules_count": 3,
      "default_methods": ["GET", "HEAD", "OPTIONS"],
      "require_auth": false,
      "message": "Policy active: 3 rules. Default methods: GET, HEAD, OPTIONS. Check api_show for per-operation policy status."
    }
  },
  "guidance": {
    "ready": true,
    "next_action": {
      "tool": "api_find",
      "reason_code": "start_discovery"
    }
  }
}
```

### 2. api_help (No Policy - Permissive Mode)

```json
{
  "data": {
    "policy": {
      "active": false,
      "message": "No policy configured. All operations are allowed (permissive mode)."
    }
  }
}
```

### 3. api_show (Operation Allowed)

```json
{
  "data": {
    "operation_id": "getPetById",
    "method": "GET",
    "path": "/pet/{petId}",
    "policy": {
      "active": true,
      "allowed": true,
      "rule": "allow-read-operations"
    }
  }
}
```

### 4. api_show (Operation Denied)

```json
{
  "data": {
    "operation_id": "deletePet",
    "method": "DELETE",
    "path": "/pet/{petId}",
    "policy": {
      "active": true,
      "allowed": false,
      "rule": "deny-delete-operations",
      "reason": "Delete operations are not allowed for agents"
    }
  }
}
```

### 5. api_preview (Policy Denied)

```json
{
  "data": {
    "operation_id": "deletePet",
    "denied": true,
    "policy_active": true
  },
  "guidance": {
    "ready": false,
    "blockers": [{
      "code": "policy_denied",
      "message": "Delete operations are not allowed for agents",
      "field": "policy",
      "resolution": {
        "tool": "api_auth",
        "reason_code": "configure_auth"
      }
    }],
    "display_hint": "Operation blocked by policy. Contact administrator for access."
  }
}
```

### 6. api_auth (With Policy Status)

```json
{
  "data": {
    "environment": "development",
    "spec_auth_schemes": ["api_key", "oauth2"],
    "config_status": {
      "current_environment": "development",
      "config_exists": true
    },
    "policy": {
      "active": true,
      "name": "petstore-agent-policy",
      "rules_count": 3,
      "default_methods": ["GET", "HEAD", "OPTIONS"],
      "require_auth": false
    }
  }
}
```

---

## Enforcement Architecture

```
┌─────────────────────────────────────────────────────────────────────┐
│                        MCP Server Startup                            │
├─────────────────────────────────────────────────────────────────────┤
│  1. Load policy from --policy flag or auto-detect                   │
│  2. Validate policy structure (rules, patterns, actions)            │
│  3. Create PolicyEngine with pre-compiled glob patterns             │
│  4. Store PolicySet for reporting                                   │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│                          api_help                                    │
├─────────────────────────────────────────────────────────────────────┤
│  SEMANTIC: Policy summary                                           │
│  ├── active: true/false                                             │
│  ├── name: "petstore-agent-policy"                                  │
│  ├── rules_count: 3                                                 │
│  ├── default_methods: ["GET", "HEAD", "OPTIONS"]                    │
│  └── message: guidance for agent                                    │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│                          api_show                                    │
├─────────────────────────────────────────────────────────────────────┤
│  SEMANTIC: Per-operation policy status                              │
│  ├── policy.active: true                                            │
│  ├── policy.allowed: true/false                                     │
│  ├── policy.rule: "allow-read-operations"                           │
│  └── policy.reason: null or "Delete not allowed"                    │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│                        api_preview                                   │
├─────────────────────────────────────────────────────────────────────┤
│  ENFORCEMENT GATE 1: Policy check before token creation             │
│  ├── If ALLOWED → Create preview token, return preview_id           │
│  └── If DENIED  → Return blocker, no token created                  │
│                                                                      │
│  Audit: policy_denied logged with operation_id, rule, reason        │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│                          api_run                                     │
├─────────────────────────────────────────────────────────────────────┤
│  ENFORCEMENT GATE 2: Policy re-check at execution                   │
│  ├── Defense in depth (policies may change)                         │
│  ├── If ALLOWED → Execute operation                                 │
│  └── If DENIED  → Return blocker                                    │
│                                                                      │
│  Audit: api_execute logged with operation_id, environment           │
└─────────────────────────────────────────────────────────────────────┘
```

---

## Policy Evaluation

### EvaluationContext

The policy engine evaluates each request with:

```rust
EvaluationContext {
    method: "GET" | "POST" | "DELETE" | ...,
    tags: ["pet", "store"],           // From OpenAPI tags
    source_ip: None,                   // Optional IP filtering
    timestamp: "2024-01-20T10:00:00Z", // For time-based rules
}
```

### Decision Flow

```
1. Check defaults.require_auth
   └── If true and no auth_profile → DENY

2. For each rule in order:
   └── If pattern matches URL:
       ├── Check conditions (auth, time_window, environment)
       ├── Check deny FIRST (deny takes precedence)
       └── Then check allow

3. No matching rule → Apply defaults
   └── If method in defaults.allow_methods → ALLOW
   └── Otherwise → DENY
```

### PolicyDecision

```rust
enum PolicyDecision {
    Allow {
        rule: String,           // "allow-read-operations"
        audit: Option<AuditConfig>
    },
    Deny {
        rule: String,           // "deny-delete-operations"
        reason: String,         // "Delete not allowed for agents"
        audit: Option<AuditConfig>
    },
}
```

---

## Example Policy File

```yaml
# .mrapids/policy.yaml
version: "1.0"

metadata:
  name: "petstore-agent-policy"
  description: "Safe defaults for AI agent access"

defaults:
  allow_methods: ["GET", "HEAD", "OPTIONS"]
  deny_external_refs: true
  require_auth: false
  audit_level: "basic"

rules:
  # Allow read operations
  - name: "allow-read-operations"
    description: "Allow safe read-only operations"
    pattern: "*"
    allow:
      methods: ["GET", "HEAD", "OPTIONS"]
      operations: ["get*", "list*", "find*", "search*"]
    audit:
      level: "basic"

  # Deny admin endpoints
  - name: "deny-admin-endpoints"
    pattern: "*/admin/*"
    deny:
      all: true
    explain: "Admin endpoints are restricted"

  # Deny delete operations
  - name: "deny-delete-operations"
    pattern: "*"
    deny:
      methods: ["DELETE"]
      operations: ["delete*", "remove*"]
    explain: "Delete operations require human approval"

  # Allow specific write with conditions
  - name: "allow-create-pet"
    pattern: "*/pet"
    conditions:
      - environment: "development"
    allow:
      methods: ["POST"]
      operations: ["addPet"]
    audit:
      level: "detailed"
      include_body: true
```

---

## Audit Logging

Policy denials are logged to `.mrapids/mcp_audit.log`:

```
2024-01-20T10:30:00Z	policy_denied	{"operation_id":"deletePet","method":"DELETE","rule":"deny-delete-operations","reason":"Delete not allowed"}
```

---

## Security Model

### Why Two Enforcement Gates?

```
┌─────────────────────────────────────────────────────────────────────┐
│  GATE 1: api_preview                                                │
│  ├── Prevents token creation for denied operations                  │
│  └── Agent learns early, saves API calls                            │
├─────────────────────────────────────────────────────────────────────┤
│  GATE 2: api_run                                                    │
│  ├── Defense in depth                                               │
│  ├── Policies may change between preview and run                    │
│  └── Ensures no stale tokens bypass policy                          │
└─────────────────────────────────────────────────────────────────────┘
```

### Permissive Mode

When no policy file exists:

| Aspect | Behavior |
|--------|----------|
| All operations | ALLOWED |
| Audit logging | Still active |
| api_help | Shows `policy.active: false` |
| api_show | `policy: null` (field omitted) |

This ensures:
- Backwards compatibility
- No friction during initial setup
- Opt-in security model

---

## Agent Workflow

### Recommended Agent Behavior

```
1. Call api_help first
   └── Check policy.active and policy.default_methods
   └── If restrictive, inform user about limitations

2. Before attempting operations:
   └── Call api_show to check policy.allowed
   └── If policy.allowed: false, explain to user

3. If blocked at api_preview:
   └── Read blocker.message for reason
   └── Suggest user contact administrator

4. Never retry denied operations:
   └── Policy decisions are deterministic
   └── Retrying wastes resources
```

### Example Agent Logic

```python
# Pseudo-code for agent behavior
def execute_operation(operation_id, params):
    # Check policy status first
    show_result = api_show(operation_id)

    if show_result.policy and not show_result.policy.allowed:
        return f"Operation blocked by policy: {show_result.policy.reason}"

    # Proceed with preview
    preview = api_preview(operation_id, params)

    if preview.guidance.blockers:
        return f"Blocked: {preview.guidance.blockers[0].message}"

    # Execute
    return api_run(preview.preview_id)
```

---

## Summary

| Component | Responsibility |
|-----------|---------------|
| Policy File | Define rules, defaults, conditions |
| PolicyEngine | Evaluate requests against rules |
| api_help | Disclose policy summary to agent |
| api_show | Disclose per-operation policy status |
| api_preview | Enforce policy before token creation |
| api_run | Enforce policy before execution |
| Audit Log | Record all policy denials |

**Key Principle**: Agent learns about restrictions through **Semantic** information, receives **Guidance** on what's allowed, and policy is **Enforced** at multiple gates.