Skip to content

security(api): gate the 14 remaining ungated mutating routers — sign-in for reads, admin for shared-state writes (#16375) - #18351

Merged
mrveiss merged 1 commit into
mainfrom
issue-16375-router-auth-gates
Oct 12, 2026
Merged

mrveiss merged 1 commit into
mainfrom
issue-16375-router-auth-gates

Conversation

@mrveiss

@mrveiss mrveiss commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Thinking Path

#16375 (priority: critical): config-registered routers declared no auth gate. Before this PR, the #16370 guard's KNOWN_UNGATED baseline held 16 of them, most of them mutating routes with no evidence of being public, the validation dashboard first. This slice gates every one of them except the two still waiting on an owner ruling. It uses the same mechanism #17729 and #16896 used: no new auth path, and no dependency on the still-open #18338.

What Changed

  • 14 routers get router-level dependencies=[Depends(get_current_user)]. Every route that changes shared state additionally requires Depends(check_admin_permission); server-wide operations are admin-only per the owner's rule.
Router (autobot-backend/…) Gate Admin routes
api/validation_dashboard.py :63 POST /generate
api/development_speedup.py :44 none
api/system_validation.py :31 none
api/code_search.py :49 POST /index, DELETE /cache
api/natural_language_search.py :54 none
api/search.py :41 POST /optimize
api/analytics_llm_patterns.py :63 none
api/analytics_pattern_learning.py :56 POST /patterns, POST /learn
api/error_resilience.py :37 both resets
api/knowledge_eval.py :20 POST /test/rebuild_index
api/phases.py :35 POST /validation/run
routers/code_completion.py :27 POST /extract
routers/feedback.py :22 POST /retrain
routers/model_management.py :28 POST /train, POST /models/{version}/activate
  • One deviation from the issue's table: phases POST /validation/run is admin-only, because it writes the same shared project state that project_state already protects with admin.
  • Callers checked for every route prefix: the frontend, the SLM frontend and backend, workers, plugins, scripts and docker. The frontend callers (PhaseProgressionIndicator.vue, useDevSpeedup.ts, SystemRepository.ts, useLLMPatternData.ts) already send the bearer token. No service-to-service caller exists, so nothing broke.
  • Baseline: KNOWN_UNGATED / _MAX_KNOWN_UNGATED went from 16 to 2 (repo_tests/config_router_auth_coverage_test.py), under its equality rule.
  • Six files sat at their size ceiling, so code was split into siblings rather than raising the ceiling: code_search_examples.py, analytics_llm_prompt_patterns.py, analytics_pattern_learning_records.py and dev_speedup_analysis.py. Ceilings were lowered in both baselines.

Verification

  • tests/api/test_router_auth_16375.py now covers 21 routers and 94 routes, 14 of them admin:
    • anonymous gets 401 on every route; a non-admin gets 403 on every admin route;
    • contrasts show the gate passes permitted callers through: 422 from body routes for non-admins and admins, and 200 for stubbed handlers;
    • 163 passed.
  • Mutation check: with the knowledge_eval gate removed, the anonymous test fails; the gate was then restored.
  • Hand run on the rebased tree: 276 passed. It covered the fix(security): authenticate every skills route, and require admin to change, fetch or execute (#16368) #16370 guard, router_auth_coverage, reach_scope_claim_17844, the size ratchet and the pre-push selection. The hook's pytest timed out (222s, loaded host), so the push used AUTOBOT_PREPUSH_ALLOW_TIMEOUT=1 after that run.

Not done, stated rather than implied

So this PR is Refs #16375.

Refs #16375
Refs #18349

Model Used

Claude Opus 5.5 (master session: brief, PR). Implementation by a Claude Opus subagent.

🤖 Generated with Claude Code

…te writes (#16375)

Slice 1 of the config-registered remainder. Each router now depends on
auth_middleware.get_current_user at router level, the mechanism #17729 used,
so every route needs a signed-in caller. Routes that change state shared by
every user also depend on check_admin_permission:

- validation_dashboard: POST /generate (mutates the shared generator)
- code_search: POST /index, DELETE /cache
- search: POST /optimize
- analytics_pattern_learning: POST /patterns, POST /learn
- error_resilience: both resets
- knowledge_eval: POST /test/rebuild_index
- phases: POST /validation/run (persists project state, as project_state does)
- code_completion: POST /extract
- feedback: POST /retrain
- model_management: POST /train, POST /models/{version}/activate

Every frontend caller already goes through ApiClient, ApiRepository or
useFetchEndpoint, which send the bearer token; no SLM or internal HTTP
caller exists for these prefixes.

KNOWN_UNGATED shrinks 16 -> 2 (prometheus_endpoint and rum stay, parked on
an owner ruling). Six of the routers sat at their size ceiling, so static
tables and records moved to sibling modules and the ceilings were lowered.

test_router_auth_16375.py now covers all 21 routers: anonymous 401 on
every route, non-admin 403 on every admin route, and 422 contrasts proving
the gate admits users and admins without running handlers.
@coderabbitai

coderabbitai Bot commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 22 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: mrveiss/AutoBot-AI/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 7d239d18-82d0-4368-b51e-ea32441c7216

📥 Commits

Reviewing files that changed from the base of the PR and between f194061 and fe3feed.


⛔ Files ignored due to path filters (2)
  • repo_tests/python_file_size_ratchet_baseline.py is excluded by !repo_tests/python_file_size_ratchet_baseline.py
  • scripts/python_file_size_known_large.py is excluded by !scripts/python_file_size_known_large.py

📒 Files selected for processing (20)
  • autobot-backend/api/analytics_llm_patterns.py
  • autobot-backend/api/analytics_llm_prompt_patterns.py
  • autobot-backend/api/analytics_pattern_learning.py
  • autobot-backend/api/analytics_pattern_learning_records.py
  • autobot-backend/api/code_search.py
  • autobot-backend/api/code_search_examples.py
  • autobot-backend/api/dev_speedup_analysis.py
  • autobot-backend/api/development_speedup.py
  • autobot-backend/api/error_resilience.py
  • autobot-backend/api/knowledge_eval.py
  • autobot-backend/api/natural_language_search.py
  • autobot-backend/api/phases.py
  • autobot-backend/api/search.py
  • autobot-backend/api/system_validation.py
  • autobot-backend/api/validation_dashboard.py
  • autobot-backend/routers/code_completion.py
  • autobot-backend/routers/feedback.py
  • autobot-backend/routers/model_management.py
  • autobot-backend/tests/api/test_router_auth_16375.py
  • repo_tests/config_router_auth_coverage_test.py

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

✅ SSOT Configuration Compliance: Passing

🎉 No new hardcoded values of either class — ssot and other both block.

Known backlog in pipeline-scripts/hardcoded_values_baseline.txt is suppressed and tracked in #14371.

@mrveiss
mrveiss merged commit 969057f into main Oct 12, 2026
64 of 80 checks passed
@mrveiss
mrveiss deleted the issue-16375-router-auth-gates branch October 12, 2026 09:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant