mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-11-05 02:44:49 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e256438928 | ||
|
|
74408f9015 | ||
|
|
5ad12b5ee8 |
No files matched your search
@@ -26,7 +26,7 @@ There are two ways to connect. Both end with the same MCP Server connection, the
|
||||
| | 🔌 **Prowler Plugin** | ⚙️ **MCP Connection Only** |
|
||||
|---|---|---|
|
||||
| **What you get** | The MCP connection **plus** the official Prowler skills for cloud security tasks | The MCP connection |
|
||||
| **Setup** | Two slash commands, prompts for the API key | One `claude mcp add` command |
|
||||
| **Setup** | Add it from the [Claude directory](https://claude.ai/directory/prowler-cloud-for-claude-code), or run two slash commands. Prompts for the API key | One `claude mcp add` command |
|
||||
| **Guided workflows** | ✅ Skills drive multi-step security work end to end | ❌ You drive the conversation |
|
||||
| **Best for** | Structured cloud security work, such as taking an account to compliance | Ad-hoc queries and your own workflows |
|
||||
| **Where to use it** | Claude Code CLI | Claude Code CLI, and the **recommended setup for the desktop app's [Code tab](#claude-code-in-the-desktop-app-code-tab)** |
|
||||
@@ -64,10 +64,16 @@ End-to-end cloud security from inside Claude Code, powered by the Prowler MCP se
|
||||
More skills are on the way. Installing the plugin keeps you current — new skills arrive with plugin updates, no extra configuration required.
|
||||
</Note>
|
||||
|
||||
## Installation (Claude Code CLI)
|
||||
## Installation
|
||||
|
||||
Prowler Cloud is listed in the official [Claude directory](https://claude.ai/directory/prowler-cloud-for-claude-code). Installing from the directory is the preferred method.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="From GitHub (recommended)">
|
||||
<Tab title="From the Claude directory (recommended)">
|
||||
1. Open the [Prowler Cloud listing](https://claude.ai/directory/prowler-cloud-for-claude-code) in the Claude directory. You can also find it in Claude under **Customize > Plugins > Discover** by searching for **Prowler Cloud**.
|
||||
2. Select **Add**.
|
||||
</Tab>
|
||||
<Tab title="From GitHub">
|
||||
Inside a Claude Code session:
|
||||
|
||||
```text
|
||||
@@ -85,7 +91,7 @@ More skills are on the way. Installing the plugin keeps you current — new skil
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
On first install, Claude Code prompts for your **Prowler API key**. The value is stored securely (macOS keychain or `~/.claude/.credentials.json`) and used to authenticate against Prowler Cloud.
|
||||
On first install, Claude Code prompts for your [**Prowler API key**](/user-guide/tutorials/prowler-app-api-keys#creating-api-keys). The value is stored securely (macOS keychain or `~/.claude/.credentials.json`) and used to authenticate against Prowler Cloud.
|
||||
|
||||
## Verify the Installation
|
||||
|
||||
@@ -125,6 +131,8 @@ Claude tracks progress in a markdown report under `.prowler/` at your project ro
|
||||
|
||||
## Uninstalling
|
||||
|
||||
If you installed the plugin from GitHub or a local clone, run:
|
||||
|
||||
```text
|
||||
/plugin uninstall prowler@prowler-plugins
|
||||
/plugin marketplace remove prowler-plugins
|
||||
|
||||
@@ -258,6 +258,27 @@ describe.each([
|
||||
});
|
||||
});
|
||||
|
||||
describe("crossProviderToMapperInput through the generic mapper", () => {
|
||||
it("joins extras onto every requirement of a framework without a dedicated mapper", () => {
|
||||
const attributes = csaAttributes as CrossProviderOverviewAttributes;
|
||||
const mapper = getComplianceMapper("Registry-Framework-Without-Mapper");
|
||||
const { attributesData, requirementsData } =
|
||||
crossProviderToMapperInput(attributes);
|
||||
const mapped = collectRequirements(
|
||||
mapper.mapComplianceData(attributesData, requirementsData),
|
||||
);
|
||||
const extras = buildRequirementExtrasMap(attributes);
|
||||
|
||||
expect(mapped).toHaveLength(attributes.requirements.length);
|
||||
for (const requirement of mapped) {
|
||||
expect(
|
||||
extras.get(requirement.name),
|
||||
`no extras for "${requirement.name}"`,
|
||||
).toBeDefined();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("CSA grouping through the real mapper", () => {
|
||||
it("groups requirements by Section into categories with correct counters", () => {
|
||||
const mapper = getComplianceMapper("CSA-CCM");
|
||||
|
||||
@@ -12,21 +12,7 @@ import type {
|
||||
CrossAccountRequirementExtras,
|
||||
} from "../_types";
|
||||
|
||||
/** Candidate display names a framework mapper may give this requirement.
|
||||
*
|
||||
* Unlike the cross-provider view (whose three universal frameworks all
|
||||
* compose `id - name`), cross-account serves EVERY framework, and mappers
|
||||
* disagree on the composed name: CSA/CIS-Controls/DORA use `id - name`,
|
||||
* CIS/CCC/PCI use the bare `id`, the generic mapper uses the bare `name`.
|
||||
* The extras map registers every candidate so the join works regardless of
|
||||
* which mapper renders the framework. */
|
||||
const candidateRequirementNames = (id: string, name: string): string[] => {
|
||||
const candidates = [id];
|
||||
if (name) {
|
||||
candidates.push(name, `${id} - ${name}`);
|
||||
}
|
||||
return candidates;
|
||||
};
|
||||
import { candidateRequirementNames } from "./requirement-names";
|
||||
|
||||
/** Display label for an account column: alias when set, uid otherwise. */
|
||||
export const accountDisplayLabel = (account: CrossAccountAccountRef): string =>
|
||||
|
||||
@@ -14,11 +14,7 @@ import type {
|
||||
ProviderCheckIdsMap,
|
||||
} from "../_types";
|
||||
|
||||
/** The composed display name the per-scan mappers give every requirement.
|
||||
* Shared with `buildRequirementExtrasMap` so the extras join never parses
|
||||
* strings back apart. */
|
||||
const composeRequirementName = (id: string, name: string): string =>
|
||||
name ? `${id} - ${name}` : id;
|
||||
import { candidateRequirementNames } from "./requirement-names";
|
||||
|
||||
/**
|
||||
* Convert a cross-provider overview into the `{AttributesData,
|
||||
@@ -84,8 +80,8 @@ export const crossProviderToMapperInput = (
|
||||
};
|
||||
|
||||
/**
|
||||
* Cross-provider context for each requirement, keyed by the exact composed
|
||||
* name the mappers produce, so renderers can join per-provider statuses and
|
||||
* Cross-provider context for each requirement, keyed by every name a mapper
|
||||
* may give it, so renderers can join per-provider statuses and
|
||||
* scan/check splits onto mapped requirements without touching the mappers.
|
||||
*/
|
||||
export const buildRequirementExtrasMap = (
|
||||
@@ -94,12 +90,21 @@ export const buildRequirementExtrasMap = (
|
||||
const extras = new Map<string, CrossProviderRequirementExtras>();
|
||||
|
||||
for (const requirement of attrs.requirements) {
|
||||
extras.set(composeRequirementName(requirement.id, requirement.name), {
|
||||
const entry: CrossProviderRequirementExtras = {
|
||||
requirementId: requirement.id,
|
||||
providers: requirement.providers,
|
||||
checkIdsByProvider: requirement.check_ids_by_provider ?? {},
|
||||
scanIdsByProvider: attrs.scan_ids_by_provider,
|
||||
});
|
||||
};
|
||||
for (const name of candidateRequirementNames(
|
||||
requirement.id,
|
||||
requirement.name,
|
||||
)) {
|
||||
// First registration wins, so a bare-name key never hijacks an id key.
|
||||
if (!extras.has(name)) {
|
||||
extras.set(name, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return extras;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/** Display names a framework mapper may give a requirement.
|
||||
* Dedicated mappers compose `id - name`, CIS/CCC/PCI use the bare `id` and the
|
||||
* generic mapper (any framework without a dedicated one, including registry
|
||||
* frameworks) uses the bare `name`, so extras maps register all of them. */
|
||||
export const candidateRequirementNames = (
|
||||
id: string,
|
||||
name: string,
|
||||
): string[] => {
|
||||
const candidates = [id];
|
||||
if (name) {
|
||||
candidates.push(name, `${id} - ${name}`);
|
||||
}
|
||||
return candidates;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
Cross-provider compliance view shows the per-provider breakdown for frameworks without a dedicated UI mapper instead of "No per-provider breakdown is available"
|
||||
Reference in new issue
Block a user