# Spec: OPA Policy Engine Integration **Status**: Pending CEO approval **Workstream**: 5 of 8 ## Scope - New `OpaMiddleware` replacing static scope check in `auth.ts` - `@openpolicyagent/opa-wasm` integration (embedded Wasm, no sidecar) - `policies/authz.rego` — main allow/deny policy - `policies/data/scopes.json` — scope to permission mapping - SIGHUP handler to hot-reload policies without restart - New env var: `POLICY_DIR` (default: `./policies`) ## Policy interface ``` input = { "method": "GET", "path": "/api/v1/agents", "scopes": ["agents:read"], "agentId": "uuid" } output = { "allow": true | false, "reason": "string" // populated when allow=false } ``` ## Acceptance Criteria - [ ] All existing scope checks replaced by OPA evaluation - [ ] Policy files hot-reloadable on SIGHUP (no restart required) - [ ] OPA Wasm loaded at startup — fail-fast if `POLICY_DIR` invalid - [ ] `allow=false` responses return `403` with `reason` in error body - [ ] Existing test suite passes unchanged (OPA evaluates same rules as before) - [ ] New unit tests for OPA middleware: allow/deny cases, missing scope, invalid input - [ ] `POLICY_DIR` env var documented in `docs/devops/environment-variables.md`