diff --git a/docs/content/sensei/about_sensei.md b/docs/content/sensei/about_sensei.md index 931c887909..1f22ec481b 100644 --- a/docs/content/sensei/about_sensei.md +++ b/docs/content/sensei/about_sensei.md @@ -16,6 +16,8 @@ weight: 1 - **Short-lived credentials:** Sensei runs entirely through a GitHub App and uses short-lived installation tokens. There is nothing to paste and nothing to rotate. - **Metered and license-gated:** Sensei is a Pro feature with per-instance quotas for fixes and onboarded repositories. +> **â˜ī¸ Beyond code — cloud posture (CSPM):** the same scan-and-fix flow applies to **cloud accounts**. Connect an AWS account, Azure subscription, or GCP project; Sensei scans it for misconfigurations, imports them as findings, and remediates them by an IaC pull request or a **reversible change to the live resource**. AppSec and CSPM share one hub, selected by a capability card. See [Cloud Security Posture (CSPM)](/sensei/cloud_posture/). + > **🧠 Before the code exists:** Sensei also generates a threat model, attack paths and security requirements from a feature *design*, with no repository involved — see [Threat Modeling](/sensei/threat_modeling/). > **🔎 BETA:** Sensei is under active development and is labeled **BETA** throughout the UI. Behavior and screens may change between releases. diff --git a/docs/content/sensei/cloud_posture.md b/docs/content/sensei/cloud_posture.md new file mode 100644 index 0000000000..1ba9ee23c5 --- /dev/null +++ b/docs/content/sensei/cloud_posture.md @@ -0,0 +1,135 @@ +--- +title: "Cloud Security Posture (CSPM)" +description: "Onboard cloud accounts, scan them for misconfigurations, and remediate directly in the cloud or by IaC pull request" +draft: false +audience: pro +weight: 4 +--- +Note: Sensei is a DefectDojo Pro-only feature and is currently in BETA. + +Sensei has two capabilities that share one hub. **AppSec** scans and fixes source-code repositories (see [About Sensei](/sensei/about_sensei/)). **Cloud Security Posture (CSPM)** does the same for **cloud accounts**: connect an AWS account, Azure subscription, or GCP project; Sensei scans it for misconfigurations with [Prowler](https://github.com/prowler-cloud/prowler), imports the results as DefectDojo findings, and remediates them — either by opening an infrastructure-as-code pull request or by applying a **reversible change to the live cloud resource**. + +> **🧭 One hub, two capabilities.** Open **Sensei** from the left-hand navigation and choose the **CSPM** capability card (or **AppSec**, or **All** to see every target together). A cloud account is the CSPM analog of an onboarded repository: it is the thing you scan and fix, and it is linked to a DefectDojo **Asset** so its findings live alongside the rest of your data. + +![The Sensei hub with the CSPM capability selected](images/cspm_hub.png) + +## How CSPM works + +1. **Connect a cloud provider** with a read-only credential, either once per account or once for many accounts via a **Cloud Connection**. +2. **Onboard a cloud account** (an AWS account, an Azure subscription, or a GCP project) and link it to an Asset. +3. **Sensei scans the account** with Prowler, on demand from the hub, and imports each misconfiguration as a DefectDojo finding recorded against the **cloud resource** it concerns. +4. **Remediate a finding** two ways: open an **IaC pull request** on a linked repository, or apply a **direct, reversible fix** to the live resource ("Fix in Cloud"). + +## Requirements + +- A **DefectDojo Pro** license that includes the **Sensei** feature, with a **cloud-account quota** (`sensei_cloud_account_limit`). +- The **Cloud Posture** feature flag enabled, and the **Locations** feature enabled — a cloud finding is identified by the cloud *resource* it concerns rather than a file and line, and Locations is what records that. Without Locations, cloud onboarding is not offered (see [Troubleshooting](#troubleshooting)). +- A **read-only scan credential** for each provider (details below). +- To **onboard** accounts and **manage connections**: a global **Maintainer** or **Owner** role. To **run a direct fix or revert one**: at least **Writer** access to the finding's Asset — a direct fix mutates live cloud state, so it is an edit of the finding. + +## Cloud connections + +A **Cloud Connection** holds one shared credential and, optionally, an organization/folder scope. From a single connection Sensei can **discover** every account the credential can see and **onboard** many of them at once — the cloud analog of a source-control connection that lists many repositories. Reach connections from **Add Accounts → Manage Connections** in the hub header, or the **Connections** page. + +![Adding a cloud connection](images/cspm_connection_setup.png) + +The setup wizard walks three steps: + +1. **Connect** — choose the provider (AWS, Azure, or GCP), give the connection a label, and paste the credential and (optionally) an org/folder scope. +2. **Discover** — Sensei enumerates the accounts the credential can reach (AWS Organizations member accounts, Azure subscriptions, or GCP projects) and proposes an Asset name for each, mapping to an existing Asset by name where one matches. +3. **Onboard** — pick which discovered accounts to onboard; each becomes a cloud account linked to its Asset. + +> **🔑 One credential, many accounts.** A connection's credential is reused by every account onboarded under it (`effective_credential`). Onboarding a single account without a connection is also supported — see below — in which case the account carries its own credential. + +## Onboard a cloud account + +To onboard one account directly, use **Add Accounts → Onboard a single account** in the hub header, choose the provider, and supply the account identifier and its read-only scan credential. + +![The cloud accounts list](images/cspm_accounts_list.png) + +The **Cloud Accounts** list mirrors the AppSec repository list: the account identifier links out to the provider console, and each row shows its provider, linked Asset, **Active Findings** (linking to that Asset's findings), last scan time, and a row menu (**Scan now**, **Configure**, **Remove**). + +### Provider identity and scan credentials + +The scan credential should be **read-only** — Sensei only needs to *read* posture to scan. (Applying a *direct* fix uses a separate write credential; see [Fix in Cloud](#fix-in-cloud-direct-remediation).) + +| Provider | Account identity | Read-only scan credential | +|----------|------------------|---------------------------| +| **AWS** | The 12-digit **account ID** (resource ARNs derive from it). | Access keys for a principal with `SecurityAudit` + `ViewOnlyAccess`. Base access keys are required; organization-wide scanning additionally assumes a role (`role_arn` / `organizations_role_arn`) on top of those keys. | +| **Azure** | The **subscription ID**. | A **service principal** (client ID, client secret, tenant ID) with **Reader** + **Security Reader**, plus the Microsoft Graph read permissions Prowler needs (`Directory.Read.All`, `Policy.Read.All`, `UserAuthenticationMethod.Read.All`). | +| **GCP** | The **project ID**. | A **service-account key** for an SA with `roles/viewer` + `roles/iam.securityReviewer`. | + +> **🔐 Credentials are encrypted at rest.** Every credential — connection or account, scan or write — is stored with DefectDojo's encrypted field storage. Enter it once; there is nothing to paste again. + +## Scan a cloud account + +Open a cloud account's row menu and choose **Scan now**. Sensei runs Prowler against the account and imports the results. A large account is scanned in **shards** (by service group) when a single scan would run long; the shards are reconciled into one set of findings. + +Each imported finding is a **cloud-posture finding** recorded against the **cloud resource** it concerns (an S3 bucket, a security group, a storage account, and so on) rather than a file. Its identity comes from Prowler's own per-finding id, so re-scanning the account updates the same findings rather than duplicating them, and a resource that reports several distinct checks produces several distinct findings. + +![A cloud-posture finding](images/cspm_finding.png) + +> **🕒 Scan activity.** Cloud scans appear on the hub's **Scan Activity** ledger alongside repository scans, with their status and duration. + +## Fixing a cloud finding + +A cloud finding has **two** remediation paths, and the right one depends on how the resource is managed: + +- **IaC pull request** — when the resource is provisioned by infrastructure-as-code, Sensei can open a pull request on a linked IaC repository, exactly like an AppSec fix. This is the same **Fix with Sensei** flow described in [Fixing findings with Sensei](/sensei/fixing_findings/); for a cloud finding it opens the PR on the account's linked IaC repository. The finding stays open until the change is applied *and the next scan sees it*, because the scanner reads the account, not your repository. +- **Fix in Cloud (direct remediation)** — a live, **reversible** change applied straight to the cloud resource through the provider API, with no repository and no deploy. This is the fastest path for click-ops resources that no IaC provisions. + +### Fix in Cloud (direct remediation) + +When a finding is directly remediable and the account is set up for it, the fix button reads **Fix in Cloud** (with a cloud icon) instead of the AppSec **Fix** / **Configure Asset** label. Clicking it opens the **Apply Direct Fix** dialog. + +![The Fix in Cloud button and Apply Direct Fix dialog](images/cspm_fix_in_cloud.png) + +The dialog is an **approval preview**: it states the exact action, the resource it will change, whether the change is reversible, and the **cloud permissions the action requires**, so you can confirm the write credential can perform it before anything runs. Approving dispatches the change; the finding's fix badge moves to **Applied in Cloud** once the provider confirms it. + +Direct remediation is **v1-limited to non-destructive, reversible actions**. Destructive changes stay on the IaC-pull-request path. The v1 actions are: + +| Provider | Action | What it does | +|----------|--------|--------------| +| **AWS** | Block S3 public access | Enables the bucket-level public-access block. | +| **AWS** | Revoke public security-group ingress | Removes an internet-facing (`0.0.0.0/0`) ingress rule. | +| **Azure** | Disable public blob access | Sets `allowBlobPublicAccess = false` on the storage account. | +| **GCP** | Remove public bucket IAM | Removes the `allUsers` / `allAuthenticatedUsers` binding from a GCS bucket. | + +To enable direct remediation on an account, turn on **remediation** for it and supply a **write credential** — separate from, and never widening, the read-only scan credential: + +- **AWS** — an assume-role or a scoped write principal with the action's permissions (for example `s3:PutBucketPublicAccessBlock` + `s3:GetBucketPublicAccessBlock`, or `ec2:RevokeSecurityGroupIngress` + `ec2:DescribeSecurityGroups` + `ec2:AuthorizeSecurityGroupIngress` for revert). +- **Azure** — a service principal with a write role scoped to the resource group (for example **Contributor** on the RG). +- **GCP** — a service-account key with `roles/storage.admin` on the project. + +> **â†Šī¸ Every direct fix is reversible and human-approved.** Sensei captures the resource's prior state before it changes anything and records a revert plan, so a direct fix can be undone. It also fingerprints the resource before and after: if the live state has drifted since the fix, a revert refuses rather than clobbering an out-of-band change. There is always a human in the loop — nothing is applied without the approval dialog. + +### Cloud Remediations ledger + +The CSPM hub adds a **Cloud Remediations** tab (alongside Cloud Accounts, Auto-fix Candidates, and Scan Activity) — the audit ledger of every direct fix. Each row shows the action, the resource, the provider, its status, and who applied it. An **Applied in Cloud** row that is still reversible offers a **Revert** button. + +![The Cloud Remediations ledger](images/cspm_remediations.png) + +Direct-remediation statuses: + +| Status | Meaning | +|--------|---------| +| **In Progress** | The change has been dispatched to the provider and is being applied. | +| **Applied in Cloud** | The provider confirmed the change; the prior state and fingerprints are recorded. This is the direct-path analog of an AppSec fix's *PR open* — a landed fix, without a pull request. | +| **Revert in Progress** | A revert was requested and is being applied. | +| **Reverted** | The prior state was restored (drift-checked first). | +| **Failed** | The change could not be applied (or the revert refused because the resource drifted). | + +## Quotas + +CSPM meters against two quotas, both shown as cards at the top of the hub: + +- **Onboarded Cloud Accounts** — the number of cloud accounts onboarded against your cloud-account limit (`sensei_cloud_account_limit`), the CSPM analog of the onboarded-repositories meter. Onboarding is blocked when the limit is reached. +- **Fixes** — the **shared** Sensei fix quota (`sensei_fix_limit`). A fix is a fix: a cloud remediation — whether an IaC pull request or a direct in-cloud change — consumes from the same fix pool as an AppSec fix. The Fixes card breaks the total down by capability (AppSec vs CSPM) so you can see the split against the one limit. + +## Troubleshooting + +- **Cloud onboarding is not offered / the CSPM capability is missing.** CSPM requires both the **Cloud Posture** feature flag and the **Locations** feature. A cloud finding has no identity without a resource location, so with Locations off, onboarding is refused. Ask a DefectDojo administrator to enable them. +- **"No cloud-account quota is available."** Your license carries no `sensei_cloud_account_limit`, or it is used up. Contact your DefectDojo administrator to raise it. +- **The fix button shows "Fix" or "Configure Asset" on a cloud finding, not "Fix in Cloud."** The finding is not directly remediable — either the account has no write credential / remediation is not enabled, or the finding's check has no v1 direct action. It can still be fixed by an IaC pull request. +- **A revert failed with a drift error.** The live resource changed out-of-band since the fix was applied, so the recorded prior state no longer matches. Reconcile the resource manually; Sensei refuses to overwrite an unexpected state. +- **A direct fix says the credential lacks a permission.** The Apply Direct Fix dialog lists the permissions each action needs. Grant them to the account's write credential (not the read-only scan credential) and try again. diff --git a/docs/content/sensei/fixing_findings.md b/docs/content/sensei/fixing_findings.md index 055adae96f..c19c53cdf0 100644 --- a/docs/content/sensei/fixing_findings.md +++ b/docs/content/sensei/fixing_findings.md @@ -9,6 +9,16 @@ weight: 3 Once a repository is onboarded, Sensei surfaces directly on your findings and on the Sensei hub. This page covers scanning a repository, triaging auto-fix candidates, and remediating individual findings. You need at least **Writer** access to a finding's Asset to trigger a fix. +## Finding your way around the Sensei hub + +The hub's toggle selects which **view** you are looking at: + +- **Repositories** — the repositories onboarded to Sensei, with their status and row actions. +- **Auto-fix Candidates** — findings staged for approval. +- **Scan Activity** — the ledger of every scan and fix run. + +If an administrator enabled in-repo CI scanning, the Repositories view also offers a **Scanning** choice between **DefectDojo-hosted** and **In-repo CI**. This selects where scans run for the repositories listed; it is not a separate view, so auto-fix candidates and scan activity always cover every onboarded repository regardless of where its scans run. With CI mode off (the default) there is nothing to choose and the control is not shown. + ## Scan a repository Scans import findings into an engagement named after the branch. You can trigger a scan on demand from the Sensei hub: open a repository's row actions and choose **Scan now**. @@ -34,12 +44,23 @@ Clicking **Fix** (on the findings table or in a finding's detail header) opens t ![Fix with Sensei dialog](images/fix_with_sensei_dialog.png) -Sensei generates a remediation and opens a pull request. The finding's fix status is shown as a badge that moves through *in progress* → *PR open* (or *failed*). Once the pull request is open, the badge links straight to it. +Sensei generates a remediation and opens a pull request. The finding's fix status is shown as a badge that moves through *in progress* → *PR open* → *PR merged* (or *failed*). Once the pull request is open, the badge links straight to it. ![Finding detail with fix status badge](images/finding_detail_fix.png) > **💡 One fix, one PR:** each approved fix consumes one fix from your quota and opens one pull request. Review and merge the PR in GitHub as you would any other. +### A fix does not close the finding on its own + +The pull request changes your code; it does not change what is running. So the finding **stays open** after Sensei fixes it, and the badge says which step is still outstanding: + +- **PR open** — the change is waiting to be reviewed and merged. +- **PR merged** — merged, but not yet deployed. + +What closes the finding is the next scan that sees the fix in place. For code scanning that is the next scan of the branch you merged into. For findings that come from a cloud account, it is the next scan *after the infrastructure change is applied* — the scanner reads the account, not your repository, so merging Terraform does not change what it reports. + +While a fix is outstanding, the same finding may keep being reported by each new scan. Sensei recognises those as the same underlying issue and will not stage another candidate or open a second pull request for it, so a slow review or deploy does not consume extra fixes. + ## Auto-fix candidate triage When a repository has automated fixes enabled, each scan stages matching findings as **candidates** on the **Auto-fix Candidates** tab of the Sensei hub. This is Sensei's preview-first model: findings are staged, but **nothing runs (no LLM cost) until you approve**. Approving opens fix pull requests and consumes fixes. diff --git a/docs/content/sensei/images/cspm_accounts_list.png b/docs/content/sensei/images/cspm_accounts_list.png new file mode 100644 index 0000000000..bd0dd5dba8 Binary files /dev/null and b/docs/content/sensei/images/cspm_accounts_list.png differ diff --git a/docs/content/sensei/images/cspm_connection_setup.png b/docs/content/sensei/images/cspm_connection_setup.png new file mode 100644 index 0000000000..c62626c0f8 Binary files /dev/null and b/docs/content/sensei/images/cspm_connection_setup.png differ diff --git a/docs/content/sensei/images/cspm_finding.png b/docs/content/sensei/images/cspm_finding.png new file mode 100644 index 0000000000..d19aff9457 Binary files /dev/null and b/docs/content/sensei/images/cspm_finding.png differ diff --git a/docs/content/sensei/images/cspm_fix_in_cloud.png b/docs/content/sensei/images/cspm_fix_in_cloud.png new file mode 100644 index 0000000000..2bfd625294 Binary files /dev/null and b/docs/content/sensei/images/cspm_fix_in_cloud.png differ diff --git a/docs/content/sensei/images/cspm_hub.png b/docs/content/sensei/images/cspm_hub.png new file mode 100644 index 0000000000..923920e176 Binary files /dev/null and b/docs/content/sensei/images/cspm_hub.png differ diff --git a/docs/content/sensei/images/cspm_remediations.png b/docs/content/sensei/images/cspm_remediations.png new file mode 100644 index 0000000000..ef4fbac76c Binary files /dev/null and b/docs/content/sensei/images/cspm_remediations.png differ diff --git a/docs/content/sensei/sensei_reference.md b/docs/content/sensei/sensei_reference.md index 687a88b068..b107be5c1e 100644 --- a/docs/content/sensei/sensei_reference.md +++ b/docs/content/sensei/sensei_reference.md @@ -3,7 +3,7 @@ title: "Sensei Reference" description: "Statuses, row actions, quotas, and troubleshooting" draft: false audience: pro -weight: 5 +weight: 6 --- Note: Sensei is a DefectDojo Pro-only feature and is currently in BETA. @@ -32,6 +32,8 @@ Auto-fix candidates and fix records move through these states: | **PR Open** | A fix pull request is open; the badge links to it. | | **Failed** | The fix could not be completed; it stays listed so it doesn't disappear silently. | +A cloud finding fixed *directly* (see [CSPM](/sensei/cloud_posture/#cloud-remediations-ledger)) adds three more, tracked on the hub's **Cloud Remediations** tab: **Applied in Cloud** (the change landed on the live resource — the direct-path analog of *PR Open*), **Revert in Progress**, and **Reverted**. + ## Repository row actions Each onboarded repository has a row-actions menu on the Sensei hub: @@ -50,6 +52,7 @@ Sensei is metered against your DefectDojo Pro license, shown as meters at the to - **Fixes:** remediations applied against your prepaid limit. Approving a candidate or triggering a fix consumes from this quota; when it is exhausted, further fixes are blocked (a warning banner appears) until the limit is raised. - **Onboarded Repositories:** repositories onboarded against your repository limit. When it is reached, onboarding new repositories is blocked. +- **Onboarded Cloud Accounts:** cloud accounts onboarded against your cloud-account limit (`sensei_cloud_account_limit`), shown when CSPM is enabled. When it is reached, onboarding new accounts is blocked. The Fixes quota is **shared** — an AppSec fix and a cloud remediation both spend `sensei_fix_limit` — and the Fixes card breaks its total down by capability. See [CSPM → Quotas](/sensei/cloud_posture/#quotas). To raise a limit, contact your DefectDojo account team. @@ -92,6 +95,13 @@ GitHub Enterprise Server uses the **same GitHub App** model as github.com; only - **Coexistence:** a github.com App connection and a GHES App connection can be configured on the same instance; each repository resolves to the connection it was onboarded through. - **Reachability:** DefectDojo must reach the GHES API host, and GHES must reach DefectDojo's `â€Ļ/sensei/webhooks` endpoint (internal hosts are fine if both sides can connect). +## Cloud (CSPM) specifics + +Cloud accounts are the CSPM analog of onboarded repositories; the full flow is on the [Cloud Security Posture (CSPM)](/sensei/cloud_posture/) page. Two reference points worth calling out: + +- **Two credentials, two jobs.** The **scan** credential is read-only (it only reads posture). A **direct fix** ("Fix in Cloud") uses a *separate* **write** credential, supplied per account and never widening the scan credential. A read-only account can be scanned but not directly remediated. +- **Direct fixes are reversible and drift-checked.** Sensei snapshots the resource's prior state before applying a change and fingerprints it; a **Revert** restores that state but refuses if the resource has drifted out-of-band since the fix. Statuses (**Applied in Cloud** / **Reverted** / **Failed**) live on the hub's **Cloud Remediations** tab. + ## Troubleshooting - **The Sensei button on a finding says "Configure Asset."** The finding's Asset isn't onboarded. Click it to onboard a repository for that Asset, then return to the finding. @@ -99,5 +109,8 @@ GitHub Enterprise Server uses the **same GitHub App** model as github.com; only - **A repository isn't listed when onboarding.** Only repositories the connection can access are shown. On **GitHub**, confirm the App is installed on the correct organization and its repository access includes the repository. On **GitLab**, confirm the access token's scope covers the project. On **Bitbucket Cloud**, confirm the **workspace** is set (tokens are workspace-scoped). On **Azure DevOps**, confirm the PAT's organization matches and its **Code** scope is granted. - **Scans or fixes never start after a webhook.** Confirm the repository's webhook points at the provider's receiver (`â€Ļ/sensei/{gitlab,bitbucket,azure}/webhooks`, or `â€Ļ/sensei/webhooks` for GitHub) with the correct secret/credentials, and subscribes to push + pull-request (+ comment) events. The provider's **recent deliveries** should show `HTTP 200`. Webhook-driven runs fire only for repositories onboarded in **hosted** mode; a push to a non-default branch is scanned via its pull request, not on its own. - **Nothing is happening after a scan.** Check that automated fixes are enabled (and your severity/risk thresholds match findings) on the repository's configuration, and that your **Fixes** quota isn't exhausted. +- **Approve is disabled on every candidate.** The hub says which of the two reasons applies, and they need different actions. *"Your fix quota is exhausted"* means the fixes on your license have all been used, so ask your DefectDojo administrator to raise the limit. *"No fixes are included in this license"* means no fix quota was ever provisioned: scanning and candidate staging still work so you can see what Sensei would fix, but approving needs a quota to be added. +- **A finding is still open after Sensei fixed it.** Expected: the pull request changes your code, not what is running. The badge says whether the change is waiting to be merged or waiting to be deployed, and the finding closes on the next scan that sees the fix in place — for cloud findings, the next scan after the infrastructure change is applied. See [A fix does not close the finding on its own](/sensei/fixing_findings/#a-fix-does-not-close-the-finding-on-its-own). +- **A fixed finding keeps reappearing in new scans.** Also expected while the fix is outstanding, and it does not cost you extra fixes: Sensei links each reappearance back to the original and will not stage a second candidate or open a second pull request for it. > **🔎 Still in BETA:** Sensei is evolving quickly. If behavior doesn't match this guide, check the [Pro changelog](/releases/pro/changelog/) for recent changes. diff --git a/docs/content/sensei/threat_modeling.md b/docs/content/sensei/threat_modeling.md index f4e8431aad..5d0c5feda7 100644 --- a/docs/content/sensei/threat_modeling.md +++ b/docs/content/sensei/threat_modeling.md @@ -3,7 +3,7 @@ title: "Threat Modeling" description: "Generate a threat model, attack paths and security requirements from a feature design, before the code exists" draft: false audience: pro -weight: 4 +weight: 5 --- Note: Threat Modeling is a DefectDojo Pro-only feature and is currently in BETA.