Skip to content

Enforce API-only endpoint restrictions on /debug/* routes#49607

Open
lukeheath wants to merge 1 commit into
mainfrom
lukeheath/debug-api-only-restriction
Open

Enforce API-only endpoint restrictions on /debug/* routes#49607
lukeheath wants to merge 1 commit into
mainfrom
lukeheath/debug-api-only-restriction

Conversation

@lukeheath

@lukeheath lukeheath commented Jul 20, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves fleetdm/confidential#16879

Summary

A global-admin API-only token that was scoped to an api_endpoints allowlist could still reach every /debug/* route. The debug handler is served separately from the main API (debugMuxMakeDebugHandler) and its middleware only checked for a valid bearer token plus the global-admin role. It never ran APIOnlyEndpointCheck, so the token's endpoint restrictions were ignored there.

This is admin-gated, so it is not a cross-role privilege escalation. It is a least-privilege / defense-in-depth gap: it breaks the guarantee of the api_endpoints feature ("this token can do only these things") for tokens that also hold the global-admin role.

Debug routes are intentionally not part of the public API catalog, so they can never appear in any token's allowlist. The fix denies restricted API-only tokens (api_only with a non-empty api_endpoints list) in the debug middleware, right after the existing global-admin check. Unrestricted API-only admin tokens (empty api_endpoints) still pass, matching how APIOnlyEndpointCheck is a no-op for unrestricted tokens on the main API path.

Checklist for submitter

  • Changes file added for user-visible changes in changes/.
  • Input data is properly validated, SELECT * is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters.

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

For unreleased bug fixes in a release candidate, one of:

  • Confirmed that the fix is not expected to adversely impact load test results

Summary by CodeRabbit

  • Bug Fixes
    • Restricted API-only credentials can no longer access debug endpoints.
    • Unauthorized debug requests now return a 403 Forbidden response.
    • Unrestricted administrative access to debug endpoints remains available.

A global-admin API-only token scoped to an api_endpoints allowlist could
still reach every /debug/* route, because the debug handler's middleware
only checked for the global-admin role and never consulted the token's
endpoint restrictions like the main API path does.

Debug routes are not in the public API catalog, so they can never appear
in an allowlist. Deny restricted API-only tokens (api_only with a
non-empty api_endpoints list) at the debug middleware, matching the
least-privilege scoping APIOnlyEndpointCheck enforces elsewhere.
Copilot AI review requested due to automatic review settings July 20, 2026 19:57
@lukeheath
lukeheath requested a review from a team as a code owner July 20, 2026 19:57
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b0f02f21-8288-4eee-b2c2-0e2b697d07fb

📥 Commits

Reviewing files that changed from the base of the PR and between fb0e817 and dca7b19.

📒 Files selected for processing (3)
  • changes/16879-debug-api-only-restriction
  • server/service/debug_handler.go
  • server/service/debug_handler_test.go

Walkthrough

Debug authentication now rejects API-only users with a non-empty endpoint allowlist before serving debug routes. Tests cover the forbidden response for restricted tokens and successful responses for regular admin sessions, unrestricted API-only users, and API-only users with an empty endpoint list.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change to debug-route authorization.
Description check ✅ Passed The description follows the template well with related issue, summary, checklist, testing, and release notes filled in.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lukeheath/debug-api-only-restriction

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

Closes a least-privilege gap where global-admin API-only tokens restricted via api_endpoints could still access /debug/* routes because the debug handler path did not enforce endpoint allowlisting.

Changes:

  • Add a guard in the debug authentication middleware to deny restricted API-only users (APIOnly && len(APIEndpoints) > 0) from accessing any /debug/* routes.
  • Add/adjust unit tests to cover the new forbidden path for restricted API-only users and to ensure unrestricted admin/API-only users still succeed.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

File Description
server/service/debug_handler.go Deny restricted API-only users from all /debug/* routes in debug middleware.
server/service/debug_handler_test.go Add coverage for restricted API-only denial and keep success cases for unrestricted admin/API-only users.
changes/16879-debug-api-only-restriction User-visible change note (content excluded from review).
Files excluded by content exclusion policy (1)
  • changes/16879-debug-api-only-restriction

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +51 to +53
if v.User.APIOnly && len(v.User.APIEndpoints) > 0 {
http.Error(w, "Unauthorized", http.StatusForbidden)
return
@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.81%. Comparing base (fb0e817) to head (dca7b19).

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #49607      +/-   ##
==========================================
- Coverage   67.81%   67.81%   -0.01%     
==========================================
  Files        3890     3890              
  Lines      247635   247638       +3     
  Branches    12982    12982              
==========================================
- Hits       167943   167940       -3     
- Misses      64529    64532       +3     
- Partials    15163    15166       +3     
Flag Coverage Δ
backend 69.22% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants