SafetyCard Request a review

Prowler MCP Server

Cloud security posture platform; ships the Prowler MCP Server and Lighthouse AI assistant

github.com/prowler-cloud/prowler › mcp_server · 2026-10-03 · 383a9bf

Defense-in-depth score

4.7 / 10

The server is a thin, well-typed wrapper over the Prowler API with careful error masking, but it ships every read and write tool at once, with no risk annotations, no read-only mode, no confirmation or dry-run, and almost no record of what was called. A hijacked model can delete providers, replace the mutelist (hiding findings), change user roles, and create export integrations that send scan data to a destination it names. The cloud credentials used to onboard providers also pass through the model as plain tool arguments. Safety rests almost entirely on the host's approval step and the permissions of the Prowler API key.

Safest setup

Prowler MCP Server masks internal errors from the model and keeps fixed limits on page sizes and timeouts. It also registers every read and write tool at once, with no read-only mode, no confirmation step and no risk labels, and there is nothing to turn on inside the server. The safest setup narrows the Prowler key and puts tool selection and approval in your MCP host.

SetupHowWhat it gives you
A least-privilege Prowler keySet PROWLER_API_KEY to a key whose Prowler role grants only what the task needs, read-only where it allows and with no user or role managementThe Prowler API itself refuses deletions, role changes and integration writes outside that role C1
Credentials entered in ProwlerConnect cloud providers and integrations in the Prowler app directly, outside the agentCloud keys and integration tokens stay out of the model and the host's transcripts C8
Only the tools neededIn your MCP host, enable just the Prowler tools the task uses, such as the read and search toolsThe model sees no delete, role or integration tools it has no use for C3
Per-call approvalSet your MCP host to ask before every Prowler tool callA person decides on each deletion, role change, mutelist write and new integration before it runs C2
A kept server logSend the server's standard log stream to storage the agent can't modifyA lasting record of failed calls and of the write tools that log C9

Approving with confidence

  • Read each prompt and approve calls one at a time; no tool is marked read-only or destructive, so the tool name and arguments are the only cue.
  • Deleting a provider or the mutelist can't be undone, and a new export integration sends scan data to the destination in its arguments, so check those closely.

Handling data

  • The server log keeps upstream error bodies without redaction; store it like other sensitive logs.

Key gaps (3)

  1. set_user_role can reassign any user's role, including the role of the key the server runs as, with no restriction or logging in the server. C1 · Identity & least privilege
  2. A hijacked model could combine tenant data reads with deletions, mutelist replacement and export integrations to an arbitrary bucket, with no server-side approval or egress control. C5 · Untrusted input blast radius
  3. Cloud and integration secrets are supplied as model-written tool arguments, so they pass through the model and the host's transcripts. C8 · Secrets & sensitive-data protection

Criteria

C1 Identity & least privilege

0.23 / 1.00

The server holds no identity of its own: in stdio mode it uses one Prowler API key from the environment, and in HTTP mode it forwards whatever bearer token or API key the caller sends to the Prowler API. Every tool, read or write, uses that same credential, so authority is whatever role the key has and the server does nothing to narrow it. One tool, set_user_role, lets the agent change any user's role (including the key owner's) with no check beyond the API's own permissions. The Prowler API's own role checks are the only remaining layer.

C2 Approval gates

0.05 / 1.00

No tool carries any risk annotation (read-only, destructive, idempotent hints), so a host cannot tell the read tools from tools that delete providers or replace the mutelist. There is no dry-run, preview, confirmation step or read-only mode. Destructive tools describe their danger only in docstrings, which a host cannot enforce. Deletions of providers (with their scans and findings), the mutelist and Jira work items cannot be undone.

C3 Tool & action scoping

0.40 / 1.00

Arguments are typed and validated in several places: non-blank identifiers, page sizes capped at 1000, date formats and ranges, enumerations, and an HTTPS plus single-host allowlist for the one external fetch. The Prowler Hub client encodes path segments safely. Most app tools, however, join model-supplied IDs into API paths with plain f-strings, and credential and mutelist arguments are free-form dictionaries. Every tool, read and write, is enabled with no way to disable groups.

C4 Code-execution isolation

N/A · full credit 1.00 / 1.00

The server contains no code path that runs model-supplied text as code: no shell, subprocess, eval, exec or deserialization of untrusted data. Attack-path queries are chosen by ID and run by the Prowler API, not interpreted here. The only dynamic import loads tool modules from the server's own package.

C5 Untrusted input blast radius

0.07 / 1.00

Tools return tenant data an outsider can influence: finding text, resource names and tags, scan and documentation excerpts, all passed through as plain structured fields with no provenance or untrusted marker. The server cannot see what the host does with it and offers no mode that removes the write or egress tools after such content is read. A hijacked model could therefore chain reads of attacker-influenced data into deletions, mutelist replacement, or an export integration pointing at a destination it names, with no server-side gate.

C6 Memory, context & configuration integrity

N/A · full credit 1.00 / 1.00

The server has no memory, retrieval store or auto-loaded configuration: it reads no workspace files, no dotenv file and no instruction files, and keeps no state between stateless HTTP requests. Settings come from environment variables and command-line flags only. Persisted Prowler mutelist and mute rules are stored in the tenant, and are scored as state-changing actions elsewhere.

C7 Third-party extensions

N/A · full credit 1.00 / 1.00

The server loads no third-party code at runtime: tools are discovered from its own package, it installs nothing, and the external content it fetches (Prowler Hub JSON, docs pages, check source from raw.githubusercontent.com) is returned as text and never executed. Dependencies are pinned in the lockfile and the container build uses a frozen sync with a digest-pinned base image.

C8 Secrets & sensitive-data protection

0.17 / 1.00

The server's own key comes from an environment variable and is not logged. Error handling is careful: upstream error bodies are logged but not relayed to the model, and unhandled failures are masked. However, onboarding cloud providers and integrations requires the model to write the cloud secrets (AWS keys, Azure client secrets, GCP private keys, kubeconfigs, Jira tokens) as tool arguments, so they travel through the model and the host's transcripts. There is no redaction of logged upstream bodies, and the stored secrets are long-lived.

C9 Audit & traceability

0.30 / 1.00

There is no per-call record of tool use. Some write tools (providers, integrations, mutelist, scan trigger) log an info line to the server's standard log, and failures are logged by a shared middleware, but roles, users, findings and resources tools log nothing, including set_user_role. Logs carry no caller identity or arguments, and nothing is tamper-evident or exported. The process log is outside the model's control.

C10 Limits & kill switch

0.50 / 1.00

The server enforces some bounds on its own work: page size capped at 1000 (50 for events, 20 for docs search), 30 second HTTP timeouts, 60 second and Jira dispatch polling timeouts, and a two-day window on historical finding queries. It has no rate limits, concurrency limits, size cap on write inputs such as finding_ids, or explicit cancellation of in-flight work, and callers choose how close to the ceiling to run.