Skip to content

Proxy-log endpoints: enforce per-project (team-scoped) authorization #403

Description

@dviejokfs

Context

Follow-up from PR #402, which closed the anonymous-access CRITICAL by adding RequireAuth + permission_guard! (LogsRead/AnalyticsRead) to all 12 /api/proxy-logs* handlers. Authentication is now enforced.

Remaining gap (MEDIUM; HIGH for Temps Cloud multi-tenant)

None of the proxy-log handlers scope reads to the caller's team membership. An authenticated user with logs:read/analytics:read — or a deployment token with analytics:read — can read another project's data:

  • (a) project_id/project_ids filter handlers: get_proxy_logs, get_today_stats, get_time_bucket_stats, get_projects_health, get_ai_agent_breakdown, get_ai_agent_timeline, get_ai_page_breakdown, get_ai_status_breakdown, get_ai_agent_pages — pass an arbitrary project id and read that project's data.
  • (b) by-id / by-request-id lookups: get_proxy_log_by_id, get_proxy_log_by_request_id carry no project filter at all — must check the returned row's project_id post-fetch.
  • (c) deployment-token cross-project: project_scope_guard! is not called in any handler.

For single-tenant self-hosted this is low-risk (all authenticated users co-operate the instance). For Temps Cloud multi-tenant it is a real HIGH and must be fixed before other tenants are onboarded to these endpoints.

Plan

  1. Thread Option<Arc<dyn temps_core::ProjectAccessChecker>> onto the proxy plugin's route state (resolve in configure_routes via context.get_service::<dyn ProjectAccessChecker>()); the handlers currently take State<Arc<ProxyLogService>>.
  2. For (a): add project_scope_guard!(auth, project_id) + project_access_guard!(auth, project_id, checker) after permission_guard!.
  3. For (b): post-fetch check of log.project_id before returning.
  4. Add "temps-proxy" to expected_crates in project_access_guard_coverage_snapshot (temps-auth/src/permission_guard.rs) so the ADR-028 coverage test enforces it.

There is an in-code NOTE at get_projects_health marking the spot.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions