@@ -67,6 +67,31 @@ It evaluates:
6767* Bioinformatics dataset protection rules
6868* Model registry immutability rules
6969
70+ ### 🔑 Permission-aware authorization
71+
72+ A second, additive gate alongside role-name/action-string RBAC
73+ (` app/core/rbac.py ` ): ` app/core/permissions.py ` 's ` ACTION_PERMISSION_MAP `
74+ checks the requester's ` permissions ` claim (forwarded by
75+ ` omnibioai-api-gateway ` 's ` PolicyMiddleware ` on every ` /policy/evaluate `
76+ call) against the same permission-registry strings ` omnibioai-auth `
77+ reserves (` workflow.execute ` , ` model.use ` , ` dataset.read ` , etc.) —
78+ this is the receiving end of the gateway's own
79+ ` SERVICE_PERMISSION_MAP ` (see
80+ [ omnibioai-api-gateway's README] ( ../omnibioai-api-gateway#authentication-pipeline ) ).
81+ Deliberately opt-in: a caller with ` permissions=[] ` falls back to the
82+ pre-existing role-based check, so nothing changes for traffic that
83+ predates permission-awareness.
84+
85+ ### 🏢 Org-tenancy scoping
86+
87+ ` app/core/tenancy.py ` adds an opt-in tenancy gate: if a request names
88+ which organization owns the resource being acted on
89+ (` context["resource_org_id"] ` ), the requester's own ` org_id ` must match
90+ it. This service has no database of its own to look resource ownership
91+ up in, so it can only enforce this when a caller explicitly supplies it
92+ — a no-op for every caller today (no real caller populates
93+ ` resource_org_id ` yet). See [ Roadmap] ( #roadmap ) below.
94+
7095---
7196
7297## 🚀 API Overview
@@ -144,6 +169,32 @@ curl http://localhost:8001/health
144169
145170---
146171
172+ ## Repository Structure
173+
174+ ``` text
175+ app/
176+ ├── main.py
177+ ├── api/
178+ │ ├── routes_policy.py # POST /policy/evaluate — the only route
179+ │ └── deps.py
180+ ├── core/
181+ │ ├── engine.py # Orchestrates RBAC → ABAC → permissions → tenancy → rules
182+ │ ├── rbac.py # Role-name/action-string check
183+ │ ├── abac.py # Attribute-based checks (GPU, HPC node, dataset sensitivity)
184+ │ ├── permissions.py # ACTION_PERMISSION_MAP — see "Permission-aware authorization" above
185+ │ ├── tenancy.py # Opt-in org_id scoping gate — see "Org-tenancy scoping" above
186+ │ └── rules.py # Domain-specific policy rules
187+ ├── services/
188+ │ ├── policy_service.py # Service-layer orchestration
189+ │ └── cache.py # Redis-backed decision cache
190+ ├── models/
191+ │ ├── request.py, policy.py, decision.py # Pydantic request/response models
192+ └── db/ # Present but unused today — this service has no
193+ # database of its own (see "Org-tenancy scoping")
194+ ```
195+
196+ ---
197+
147198## 🧠 Policy Evaluation Flow
148199
1492001 . ** RBAC check**
@@ -181,8 +232,8 @@ This service is used by:
181232cd ~ /Desktop/machine/omnibioai-policy-engine
182233pytest tests/ -v --cov=.
183234
184- # 48 tests passing
185- # 93 % coverage
235+ # 90 tests passing
236+ # 95 % coverage
186237# Covers: RBAC, ABAC, rule engine, cache, policy service, routes
187238```
188239
@@ -225,9 +276,11 @@ pytest tests/ -v --cov=.
225276| Redis caching for policy decisions | ✓ Implemented |
226277| RBAC/ABAC evaluation | ✓ Stable |
227278| Custom rule engine | ✓ Stable |
279+ | Permission-aware authorization (` app/core/permissions.py ` ) | ✓ Implemented — see [ Permission-aware authorization] ( #permission-aware-authorization ) below |
280+ | Org-tenancy scoping gate (` app/core/tenancy.py ` ) | ✓ Implemented, opt-in — activates only once a caller supplies ` context["resource_org_id"] ` ; no real caller does yet |
228281| OPA (Open Policy Agent) backend | Planned |
229282| Policy versioning system | Planned |
230- | Org-level multi-tenancy | Planned v0.5 |
283+ | Org-level multi-tenancy enforced by default | Planned v0.5 |
231284
232285---
233286
0 commit comments