feat: operation-level privacy gating instead of broad service-level
All checks were successful
CI / lint-and-test (push) Successful in 21s
All checks were successful
CI / lint-and-test (push) Successful in 21s
- Replace broad service-level hiding with fine-grained operation-level gating
- PRIVACY_SENSITIVE_OPERATIONS config: hide specific operations across ALL services
- PRIVACY_SERVICES still works for broad service-level blocking (optional)
- Users without PRIVACY_SERVICE_ROLES:
* Don't see sensitive operations in /api/filter-options
* Can't query sensitive operations via /api/events or /api/ask
* Get 403 on /api/events/{id}/explain for sensitive events
- Exchange/Teams services remain visible; only privacy ops are hidden
- Update .env.example with new operation-level config docs
This commit is contained in:
@@ -13,6 +13,7 @@ from config import (
|
||||
LLM_MAX_EVENTS,
|
||||
LLM_MODEL,
|
||||
LLM_TIMEOUT_SECONDS,
|
||||
PRIVACY_SENSITIVE_OPERATIONS,
|
||||
PRIVACY_SERVICES,
|
||||
)
|
||||
from database import events_collection
|
||||
@@ -596,7 +597,9 @@ async def explain_event(event_id: str, user: dict = Depends(require_auth)):
|
||||
if not event:
|
||||
raise HTTPException(status_code=404, detail="Event not found")
|
||||
|
||||
if event.get("service") in PRIVACY_SERVICES and not user_can_access_privacy_services(user):
|
||||
if (
|
||||
event.get("service") in PRIVACY_SERVICES or event.get("operation") in PRIVACY_SENSITIVE_OPERATIONS
|
||||
) and not user_can_access_privacy_services(user):
|
||||
raise HTTPException(status_code=403, detail="Access to this event is restricted")
|
||||
|
||||
event.pop("_id", None)
|
||||
@@ -689,7 +692,8 @@ async def ask_question(body: AskRequest, user: dict = Depends(require_auth)):
|
||||
# -----------------------------------------------------------------------
|
||||
# Build and run query
|
||||
# -----------------------------------------------------------------------
|
||||
privacy_excluded = [] if user_can_access_privacy_services(user) else list(PRIVACY_SERVICES)
|
||||
privacy_excluded_services = [] if user_can_access_privacy_services(user) else list(PRIVACY_SERVICES)
|
||||
privacy_excluded_ops = [] if user_can_access_privacy_services(user) else list(PRIVACY_SENSITIVE_OPERATIONS)
|
||||
query = _build_event_query(
|
||||
entity,
|
||||
start,
|
||||
@@ -701,8 +705,13 @@ async def ask_question(body: AskRequest, user: dict = Depends(require_auth)):
|
||||
include_tags=body.include_tags,
|
||||
exclude_tags=body.exclude_tags,
|
||||
)
|
||||
if privacy_excluded:
|
||||
query["$and"] = query.get("$and", []) + [{"service": {"$nin": privacy_excluded}}]
|
||||
extra_filters = []
|
||||
if privacy_excluded_services:
|
||||
extra_filters.append({"service": {"$nin": privacy_excluded_services}})
|
||||
if privacy_excluded_ops:
|
||||
extra_filters.append({"operation": {"$nin": privacy_excluded_ops}})
|
||||
if extra_filters:
|
||||
query["$and"] = query.get("$and", []) + extra_filters
|
||||
|
||||
try:
|
||||
total = events_collection.count_documents(query)
|
||||
|
||||
Reference in New Issue
Block a user