Skip to content

feat(pip): RFC-005 PEP middleware, proto fields, guard PDP integration (Steps 4-6)#41

Merged
beonde merged 4 commits intomainfrom
feature/rfc005-pep-middleware
Mar 20, 2026
Merged

feat(pip): RFC-005 PEP middleware, proto fields, guard PDP integration (Steps 4-6)#41
beonde merged 4 commits intomainfrom
feature/rfc005-pep-middleware

Conversation

@beonde
Copy link
Member

@beonde beonde commented Mar 20, 2026

Summary

Implements Steps 4-6 of the RFC-005 PIP implementation guide v1.2. Follows PR #40 (Steps 1-3, merged).


Step 4: NewPolicyMiddleware — HTTP PEP (pkg/gateway/)

New NewPolicyMiddleware function implementing the full HTTP-layer PEP flow:

  • PEPConfig struct: PDPClient, EnforcementMode, ObligationRegistry, DecisionCache, BreakGlassKey, PEPID, Workspace, Logger, telemetry callback
  • PEP flow: badge verify → break-glass check → cache lookup → PDP query → decision enforcement per EM → obligation enforcement → telemetry callback
  • ParseBreakGlassJWS added to pkg/pip/breakglass.go (using go-jose/v4)
  • Legacy NewAuthMiddleware preserved (marked Deprecated)

Tests: 33 test cases in policy_middleware_test.go95.2% coverage

  • Badge-only mode (3 cases)
  • PDP allow/deny (all 4 EM modes)
  • PDP unavailable (fail-closed per EM)
  • Decision caching (hit + cached deny)
  • Obligations (success, failure in STRICT, unknown in STRICT)
  • Break-glass (valid bypass, wrong key, expired, scope mismatch)
  • TxnID propagation, environment attrs, header forwarding

Step 5: Proto changes (proto/capiscio/v1/mcp.proto)

New fields for RFC-005 PIP envelope:

EvaluateToolAccessRequest:

Field Number Type
enforcement_mode 8 string
capability_class 10 string
envelope_id 11 string
delegation_depth 12 int32
constraints_json 13 string
parent_constraints_json 14 string

EvaluateToolAccessResponse:

Field Number Type
policy_decision_id 11 string
policy_decision 12 string
enforcement_mode 13 string
obligations 14 repeated MCPObligation

New MCPObligation message: type (1), params_json (2)

Generated via make proto (buf v2). Field 9 reserved per implementation guide.


Step 6: Guard PDP integration (pkg/mcp/)

Wired PDP into the existing Guard using the functional options pattern for backward compatibility:

  • GuardOption: WithPDPClient, WithEnforcementMode, WithObligationRegistry, WithGuardLogger
  • evaluateWithPDP: builds PIP request, queries PDP, handles unavailability per EM (OBSERVE → allow, others → fail-closed), enforces decision per EM matrix, runs obligation enforcement
  • evaluateInlinePolicy: refactored legacy trust level + tool glob checks
  • Design: PDP replaces inline policy; authentication always runs first
  • NewGuard signature: ...GuardOption variadic — fully backward compatible

Tests: 15 PDP-specific test cases in guard_pdp_test.go:

  • PDP ALLOW (verifies PIP request structure)
  • PDP DENY (all 4 EM modes)
  • PDP unavailable (all 4 EM modes, fail-closed)
  • PDP skips inline policy (auth still required)
  • Obligations (succeed, fail in STRICT, unknown in STRICT)
  • Evidence always emitted
  • Backward compatibility (no PDP = inline policy works)

Coverage: evaluateWithPDP 100%, EvaluateToolAccess 96.2%, all options 100%


Files changed (8 files, +2285/-88)

File Change
pkg/gateway/middleware.go +288 — NewPolicyMiddleware, PEPConfig, helpers
pkg/gateway/policy_middleware_test.go +1021 — 33 test cases
pkg/mcp/guard.go +184/-6 — PDP integration, GuardOption pattern
pkg/mcp/guard_pdp_test.go +533 — 15 PDP test cases
pkg/mcp/types.go +6 — PolicyDecisionID, PolicyDecision fields
pkg/pip/breakglass.go +24 — ParseBreakGlassJWS
pkg/rpc/gen/capiscio/v1/mcp.pb.go +293/-88 — regenerated
proto/capiscio/v1/mcp.proto +24 — RFC-005 fields

Test results

All packages pass with zero regressions:

ok  pkg/gateway   95.2% coverage
ok  pkg/mcp       67.5% coverage (evaluateWithPDP 100%)
ok  pkg/pip       89.5% coverage

Related

Step 4: NewPolicyMiddleware in pkg/gateway/
- PEPConfig with PDPClient, EnforcementMode, ObligationRegistry, DecisionCache
- Full PEP flow: badge verify, break-glass, cache, PDP, enforce, obligations
- 95.2% test coverage (33 test cases)

Step 5: Proto changes in proto/capiscio/v1/mcp.proto
- EvaluateToolAccessRequest: enforcement_mode, capability_class, envelope_id,
  delegation_depth, constraints_json, parent_constraints_json
- EvaluateToolAccessResponse: policy_decision_id, policy_decision,
  enforcement_mode, repeated MCPObligation obligations
- New MCPObligation message

Step 6: Guard PDP integration in pkg/mcp/
- GuardOption pattern: WithPDPClient, WithEnforcementMode, WithObligationRegistry
- evaluateWithPDP: builds PIP request, queries PDP, handles EM matrix
- evaluateInlinePolicy: refactored legacy trust level + tool glob checks
- PDP replaces inline policy (authentication always runs first)
- 15 PDP-specific test cases, evaluateWithPDP 100% coverage

Implements Steps 4-6 of the RFC-005 PIP implementation guide v1.2.
Copilot AI review requested due to automatic review settings March 20, 2026 15:11
@codecov
Copy link

codecov bot commented Mar 20, 2026

Codecov Report

❌ Patch coverage is 69.47115% with 127 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/rpc/gen/capiscio/v1/mcp.pb.go 0.00% 61 Missing ⚠️
pkg/gateway/middleware.go 87.55% 21 Missing and 7 partials ⚠️
pkg/mcp/guard.go 77.31% 23 Missing and 4 partials ⚠️
pkg/pip/breakglass.go 0.00% 11 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements RFC-005 PIP integration steps 4–6 by adding a full HTTP-layer PEP middleware, extending MCP proto messages with PDP/envelope fields, and wiring a PDP-backed authorization path into the MCP Guard while preserving backward compatibility.

Changes:

  • Added NewPolicyMiddleware in pkg/gateway/ implementing badge verification, break-glass, caching, PDP evaluation, obligations, and telemetry callbacks.
  • Extended EvaluateToolAccess request/response protos (and regenerated Go bindings) with RFC-005 decision context + RFC-008 envelope placeholders.
  • Integrated a PDP client into pkg/mcp/Guard via functional options and added PDP-focused tests.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
proto/capiscio/v1/mcp.proto Adds RFC-005/RFC-008 fields and MCPObligation message.
pkg/rpc/gen/capiscio/v1/mcp.pb.go Regenerated bindings reflecting the proto changes.
pkg/pip/breakglass.go Adds ParseBreakGlassJWS helper for verifying break-glass JWS tokens.
pkg/gateway/middleware.go Introduces PEPConfig + NewPolicyMiddleware PEP flow and helpers.
pkg/gateway/policy_middleware_test.go Adds comprehensive PEP middleware tests (badge-only, PDP, cache, obligations, break-glass, txn_id, etc.).
pkg/mcp/guard.go Adds PDP integration via GuardOption and PDP/inline policy split.
pkg/mcp/guard_pdp_test.go Adds Guard PDP integration tests.
pkg/mcp/types.go Extends EvaluateResult with PDP decision metadata fields.

beonde added 2 commits March 20, 2026 11:21
Split NewPolicyMiddleware (complexity 25) into pep struct with methods:
- serveHTTP (5), evaluatePolicy (7), handleCachedDecision (7),
  handleBreakGlass (3), handlePDPUnavailable (2), handlePDPDeny (3),
  enforceObligations (4), buildPIPRequest (2)

All functions now well under gocyclo threshold of 15.
No behavioral changes — all 33 tests pass unchanged.
- Validate PDP response (Decision + DecisionID) in gateway and guard
- Guard nil logger safety in WithGuardLogger
- Replace uuid.Must(uuid.NewV7()) with error-handled fallback
- Restrict ParseBreakGlassJWS to EdDSA only
- Add panic recovery to emitPolicyEvent callbacks
Copilot AI review requested due to automatic review settings March 20, 2026 15:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

- Cached DENY in EM-OBSERVE now allows through with ALLOW_OBSERVE
- Use cached PDP reason in 403 response when available
- Fix PolicyEventCallback comment: synchronous, not non-blocking
@beonde beonde merged commit c3ceeb4 into main Mar 20, 2026
4 checks passed
@beonde beonde deleted the feature/rfc005-pep-middleware branch March 20, 2026 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants