Skip to content

[Feature Request]: Runtime capability preflight — distinguish "missing scope" from "not entitled" #571

Description

@1689er

Feature Description

Scope information today is static: generated docs describe what each tool requires (#237, #545, #552, #553). There's no way for an operator to ask the running server what their credential can actually do.

I'd like the server to be able to probe its own credential and report, per module:

  • granted — the key can call this module
  • missing scope — the key lacks the scope (and which one to add)
  • not entitled — the product isn't provisioned for this CID, so adding scopes won't help

The useful part is that the Falcon API already distinguishes the last two, and the signal is easy to read:

Response Meaning Fix
403 with an x-cs-region header Reached the region; the key lacks the scope Add the scope to the API client
404 without an x-cs-region header Answered at the edge; product not provisioned/routed for the CID Entitlement conversation — scopes won't help
400 / 415 / 422 Reached the service, payload rejected The credential is authorized

That last row is what makes probing cheap and safe: a deliberately invalid request proves authorization without creating anything.

This complements #231 (enhanced error messages) rather than duplicating it. #231 improves what an error says, this provides the signal to say it with, and lets an operator get the answer before making the call.

Use Case

A newly issued API key. Someone is handed a client id/secret and asked to stand the server up. Today they discover the gaps one failing tool at a time. A preflight prints the answer in one shot: which modules work, which need a scope added, which aren't entitled.

Triage that currently looks like a bug report. A tool returns 404 and the user cannot tell whether the server is broken, the scope is missing, or the tenant doesn't have the product. #330 asks exactly this — whether the Incidents module's 404 relates to the move to Cases. #351, #221 and #362 read like variants of "which of these three problems do I have". Classifying the response turns those into self-service answers.

Shared deployments. Anyone running this centrally rather than per-analyst repeatedly hits "will this tool work with the credential we were issued?" Surfacing it once, at startup or on demand, replaces a lot of trial and error.

Honest agent answers. With a falcon_check_capabilities tool, an assistant asked "can you look at our cloud posture?" can answer from fact rather than discovering the limitation through a failure mid-investigation.

Related Module/Area

Core functionality

Proposed Solution (Optional)

  1. --preflight (or falcon-mcp preflight) — one cheap read per enabled module, printing module → state, plus the scope to request when it's missing. Useful in CI and immediately after issuing a key.
  2. Optional falcon_check_capabilities tool — the same probe exposed to the agent, with results cached for a few minutes.
  3. Feed the classification into errors (the [Feature Request]: Enhanced Error Messages with Actionable Guidance #231 tie-in): on a 403, name the missing scope; on a region-less 404, say the product doesn't appear provisioned for this CID rather than implying the tool is broken.

Sketch of the classifier:

def classify(status: int, has_region_header: bool) -> str:
    if status in (200, 201, 400, 415, 422):
        return "granted"          # reached the service
    if status == 403:
        return "missing-scope"    # region denied the scope
    if status == 404:
        return "missing-scope" if has_region_header else "not-entitled"
    return "unknown"

Implementation notes:

  • Probes should be read-only by default. Write-scope probing is possible with invalid payloads, but that shouldn't happen implicitly. If offered at all, make it opt-in and only for endpoints where a malformed body cannot partially succeed.
  • One probe per scope is enough; pick the cheapest read in each module (limit=1).
  • Cache it — the answer only changes when the API client's scopes change.
  • In my implementation this is roughly 120 lines: a table of scope → {method, path, body?}, the classifier above, and a short-lived cache. The table is the only part needing per-module curation.

Alternatives Considered (Optional)

  • Static scope documentation alone (today's approach, [Feature Request]: Complete API Scope Mappings #237). Necessary but not sufficient — it describes what tools need, not what your key has.
  • Better error messages alone ([Feature Request]: Enhanced Error Messages with Actionable Guidance #231). Helps after the fact, but the user still discovers each gap by hitting it, and a 404 remains ambiguous without the region-header signal.
  • Have operators check the Falcon console. Works for scopes, but it's manual, out of band, and doesn't answer the entitlement question in the same place.
  • Doing nothing. Reasonable if the intended deployment is one analyst with their own key and a small module set. It gets expensive as the module count grows, since every additional module is another way for a mis-scoped key to fail confusingly.

Additional Context (Optional)

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions