Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ The project follows a modular, three-layer, Hexagonal-like architecture that cle
* `tests/common.rs`
* `tests/fixtures/` (sample Dockerfiles, scan results, etc.)
* Documentation for user-facing capabilities is under `docs/features/`.
* Planned features are described in `docs/roadmap.md`; each entry is linked from the README feature table. When a roadmap feature is implemented, move its section to a `docs/features/*.md` document and update the README table with the release version.
* Build tooling and shortcuts are defined in `Justfile` and `flake.nix`.

### 2.2 Domain Layer (`src/domain/`)

The domain layer contains pure business logic and domain models.

Key module:
Key modules:

* `scanresult/`: defines core entities and value objects:
* `ScanResult`: core aggregate representing a full scan result.
Expand All @@ -53,6 +54,11 @@ Key module:
* `Layer`: container image layer information.
* `Policy`: policy evaluation results.
* Value objects such as `Severity`, `Architecture`, `OperatingSystem`.
* `iacscanresult/`: light domain model for IaC scan results:
* `IacScanResult`: aggregate with the list of findings.
* `IacFinding`: rule name, severity, affected resources.
* `IacResource`: source file, location, resource type and name.
* `IacSeverity`: High/Medium/Low/Unknown value object.

### 2.3 Application Layer (`src/app/`)

Expand All @@ -62,12 +68,13 @@ Key components:

* **`LSPServer` (`lsp_server/`)** – main LSP implementation built on `tower-lsp`:
* `lsp_server_inner.rs`: core LSP protocol handlers (initialize, text sync, code lenses, commands, diagnostics, hover, etc.).
* `commands/`: concrete LSP command implementations (e.g. `scan_base_image`, `build_and_scan`).
* `commands/`: concrete LSP command implementations (e.g. `scan_base_image`, `build_and_scan`, `iac_scan`).
* `command_generator.rs`: generates Code Lens entries and associated commands.
* `supported_commands.rs`: registry of available commands exposed to the client.
* **`LspInteractor`** – manages communication with the LSP client and document state.
* **`ImageScanner`** – trait for scanning container images (implemented by infrastructure components).
* **`ImageBuilder`** – trait for building Docker images.
* **`IacScanner`** – trait for scanning IaC files/directories for misconfigurations.
* **`DocumentDatabase` (`document_database.rs`)** – in-memory store for:
* Document text
* Diagnostics (LSP warnings/errors for vulnerabilities)
Expand All @@ -86,6 +93,11 @@ Key components:
* Downloads and manages scanner binary versions.
* Parses JSON scan results (e.g. via `sysdig_image_scanner_json_scan_result_v1.rs`).

* **`SysdigIacScanner`**
* Runs the Sysdig CLI scanner in `--iac` mode over a file or directory (recursive).
* Shares the `ScannerBinaryManager` with `SysdigImageScanner` (single shared `Arc<Mutex<...>>` created in `ConcreteComponentFactory`), so the CLI binary is installed only once.
* Reads the report from a temp `--output-json` file and parses it via `sysdig_iac_scanner_json_result_v1.rs`.

* **`DockerImageBuilder`**
* Builds container images using Bollard (Docker API client).

Expand Down Expand Up @@ -121,7 +133,7 @@ The high-level LSP flow is:
1. **Initialize** – Client sends configuration (e.g. `api_url`, `api_token`) via `initializationOptions`.
2. **`didOpen` / `didChange`** – Document updates trigger parsing and analysis.
3. **`codeLens`** – The server generates “Scan base image” code lenses on relevant lines (e.g. Dockerfile `FROM` instructions).
4. **`executeCommand`** – Clicking a lens triggers commands like `scan_base_image` or `build_and_scan`.
4. **`executeCommand`** – Clicking a lens triggers commands like `scan_base_image`, `build_and_scan` or `iac_scan` (`sysdig-lsp.execute-iac-scan`, which also runs workspace-wide when invoked without arguments).
5. **`publishDiagnostics`** – Vulnerability findings are sent as diagnostics to the editor.
6. **`hover`** – Hovering on diagnostics or vulnerable elements shows detailed vulnerability information.

Expand Down
22 changes: 21 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sysdig-lsp"
version = "0.8.7"
version = "0.9.0"
edition = "2024"
authors = [ "Sysdig Inc." ]
readme = "README.md"
Expand Down Expand Up @@ -34,6 +34,7 @@ tower-lsp = "0.20.0"
tracing = "0.1.41"
tracing-subscriber = "0.3.19"
version-compare = "0.2.0"
tempfile = "3.27.0"

[dev-dependencies]
rstest = "0.26.0"
Expand Down
33 changes: 27 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,19 @@ helping you detect vulnerabilities and misconfigurations earlier in the developm
| Docker-compose image analysis | Supported | [Supported](./docs/features/docker_compose_image_analysis.md) (0.6.0+) |
| Vulnerability explanation | Supported | [Supported](./docs/features/vulnerability_explanation.md) (0.7.0+) |
| K8s Manifest image analysis | Supported | [Supported](./docs/features/k8s_manifest_image_analysis.md) (0.8.0+) |
| Infrastructure-as-code analysis | Supported | In roadmap |
| Infrastructure-as-code analysis | Supported | [Supported](./docs/features/iac_scan.md) (0.9.0+) |
| Structured scan results for clients (tree view data) | Supported | [In roadmap](./docs/roadmap.md#structured-scan-results-for-clients) |
| Policy evaluation results | Supported | [Supported](./docs/features/vulnerability_explanation.md) (0.7.0+) |
| Scan arbitrary image (without document) | Supported | [In roadmap](./docs/roadmap.md#scan-arbitrary-image) |
| Scan result summary notification (status bar data) | Supported | [In roadmap](./docs/roadmap.md#scan-result-summary-notification) |
| Link to scan results in Sysdig Secure | Supported | [In roadmap](./docs/roadmap.md#link-to-scan-results-in-sysdig-secure) |
| Standalone / offline mode | Supported | [In roadmap](./docs/roadmap.md#standalone--offline-mode) |
| Upload scan results to Sysdig Secure | Supported | [In roadmap](./docs/roadmap.md#upload-scan-results-to-sysdig-secure) |
| Custom policies configuration | Supported | [In roadmap](./docs/roadmap.md#custom-policies-configuration) |
| Configurable report detail level | Supported | [In roadmap](./docs/roadmap.md#configurable-report-detail-level) |
| Custom CLI scanner source | Supported | [In roadmap](./docs/roadmap.md#custom-cli-scanner-source) |
| Scan whole manifest at once | Supported | [In roadmap](./docs/roadmap.md#scan-whole-manifest) |
| Build args support in Build and Scan | Supported | [In roadmap](./docs/roadmap.md#build-args-support-in-build-and-scan) |

## Installation

Expand Down Expand Up @@ -175,14 +187,17 @@ Navigate to **Settings > Configure Kate > LSP Client > User Server Settings** an
"highlightingModeRegex": "^(Dockerfile|YAML)$",
"initializationOptions": {
"sysdig": {
"api_url": "https://secure.sysdig.com"
"api_url": "https://secure.sysdig.com",
"api_token": "your token"
}
}
}
}
}
```

If `sysdig.api_token` is omitted, the token is read from the `SECURE_API_TOKEN` environment variable instead.

### JetBrains IDEs

> [!WARNING]
Expand All @@ -209,10 +224,13 @@ Navigate to **Settings > Configure Kate > LSP Client > User Server Settings** an
```json
{
"sysdig": {
"api_url": "https://secure.sysdig.com"
"api_url": "https://secure.sysdig.com",
"api_token": "your token"
}
}
```
If `sysdig.api_token` is omitted, the token is read from the `SECURE_API_TOKEN` environment variable instead.
Note that the IDE must be launched from an environment where the variable is set (e.g. from a terminal), otherwise it won't see it.

### Vim with coc.nvim (to be reviewed)

Expand All @@ -225,13 +243,16 @@ Add the following to your `coc.nvim` configuration:
"filetypes": ["dockerfile", "yaml"],
"initializationOptions": {
"sysdig": {
"api_url": "https://secure.sysdig.com"
"api_url": "https://secure.sysdig.com",
"api_token": "your token"
}
}
}
}
```

If `sysdig.api_token` is omitted, the token is read from the `SECURE_API_TOKEN` environment variable instead.

### Neovim with nvim-lspconfig

Install [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig?tab=readme-ov-file#install):
Expand All @@ -256,7 +277,7 @@ if not configs.sysdig then
init_options = {
sysdig = {
api_url = "https://us2.app.sysdig.com",
-- api_token = "my_token", -- if not specified, will be retrieved from the SYSDIG_API_TOKEN env var.
-- api_token = "my_token", -- if not specified, will be retrieved from the SECURE_API_TOKEN env var.
},
},
},
Expand All @@ -278,7 +299,7 @@ vim.lsp.config.sysdig = {
init_options = {
sysdig = {
api_url = "https://us2.app.sysdig.com",
-- api_token = "my_token", -- if not specified, will be retrieved from the SYSDIG_API_TOKEN env var.
-- api_token = "my_token", -- if not specified, will be retrieved from the SECURE_API_TOKEN env var.
},
},
}
Expand Down
6 changes: 6 additions & 0 deletions docs/features/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,10 @@ Sysdig LSP provides tools to integrate container security checks into your devel
- Displays a detailed summary of scan results when hovering over a scanned image name.
- Provides immediate feedback on vulnerabilities, severities, and available fixes.

## [Infrastructure-as-Code Analysis](./iac_scan.md)
- Scans IaC files (Kubernetes manifests, Terraform, etc.) for misconfigurations.
- Scans the whole workspace recursively or a single file via code lens.

See the linked documents for more details.

For planned features, see the [roadmap](../roadmap.md).
64 changes: 64 additions & 0 deletions docs/features/iac_scan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Infrastructure-as-Code Analysis

Sysdig LSP scans your Infrastructure-as-Code files for misconfigurations and reports the findings as diagnostics in your editor's problems panel.

> [!IMPORTANT]
> Sysdig LSP analyzes IaC files from disk, not from the editor buffer.
>
> Save the file before scanning to analyze unsaved changes.

![Sysdig LSP executing an IaC scan on a Kubernetes manifest](./iac_scan.png)

## Usage

The feature is exposed through a single command, `sysdig-lsp.execute-iac-scan`, which accepts an optional path:

- **Without arguments**: scans the workspace root recursively. All IaC files the scanner understands (Kubernetes
manifests, Terraform, etc.) are analyzed. Requires the client to have sent a workspace root (via `workspaceFolders`
or `rootUri`) during initialization.
- **With a file URI**: scans just that file. This is what the **"Scan IaC file"** code lens (shown at the top of
Kubernetes manifests and Docker Compose files) invokes. The argument must be a valid `file://` URI; anything else is
rejected.

## Example

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: nginx:1.19
```

In this example, Sysdig LSP will offer a **"Scan IaC file"** code lens at the top of the manifest. Running it reports
every misconfiguration found by the scanner (e.g. missing memory limits for the `nginx` container) as a diagnostic on
the file.

## Diagnostics

Each finding is reported as a diagnostic on the affected file with `source: "sysdig-iac"`:

- Message format: `<rule name>: <location> (<resource type>: <resource name>)`
- Severity mapping: `high` → Error, `medium` → Warning, `low`/unknown → Information

Diagnostics from different scan types coexist on the same document: image scan diagnostics are tagged with
`source: "sysdig-vuln"` and are never touched by IaC scans (and vice versa). Re-scanning refreshes only the IaC
diagnostics in scope: a single-file scan replaces that file's findings, a workspace scan replaces them for every file
under the scanned root.

## Limitations

- Findings are anchored at the top of the file (range `0,0`): the CLI scanner reports the location as an opaque string
which is included in the diagnostic message instead.
- No code lens on Terraform files yet: most LSP clients are configured to route only `dockerfile` and `yaml` file types
to Sysdig LSP. Terraform files are still covered by the recursive workspace scan.
- Editing a file does **not** clear its IaC diagnostics (they anchor at the top of the file and stay meaningful);
re-run the scan to refresh them. Vulnerability diagnostics, which anchor to specific lines, are cleared on edits.
- Multi-root workspaces: only the first workspace folder is scanned by the workspace-wide command. Findings for files
outside that folder (e.g. produced by single-file scans) are preserved.
Binary file added docs/features/iac_scan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Roadmap

This document describes the features planned for Sysdig LSP. The goal is for the LSP to become the core engine of the
[Sysdig VSCode Extension](https://github.com/sysdiglabs/vscode-extension) (and other editor plugins), so most of these
features close the gap with what the extension implements today in TypeScript.

Once a feature is implemented, its section should be moved to a dedicated document under [`docs/features/`](./features/README.md)
and the [README feature table](../README.md#features) updated with the release version.

## Structured scan results for clients

Expose the full scan result (packages, vulnerabilities, severities, exploitable/fix-available flags, source locations,
and the policy evaluation tree: Policy → Rule Bundle → Rule → Failure with remediation hints) through a custom LSP
request or notification (e.g. `sysdig/scanResult`). Today the LSP only surfaces results as diagnostics and Markdown
hovers, which is not machine-consumable; clients need structured JSON to render tree views, filters (exploitable /
fix available), and rich UIs like the extension's "Vulnerabilities" and "Policy Evaluation" panels.

## Scan arbitrary image

Allow executing a scan for any image pull string without requiring a document `Location`. The current
`sysdig-lsp.execute-scan` command takes a `Location` argument, so clients cannot trigger a scan from a command palette
prompt (e.g. "Scan Image for Vulnerabilities" in the extension). This needs a command variant that only takes the image
pull string and reports results through the structured scan result channel instead of document diagnostics.

## Scan result summary notification

Send a custom notification with the vulnerability counts per severity (critical/high/medium/low/negligible) and the
policy pass/fail summary after each scan, so clients can render lightweight UI such as a status bar item without
parsing diagnostics.

## Link to scan results in Sysdig Secure

Expose the scan `resultUrl` returned by the scanner so clients can offer an "Open in Sysdig Secure" action. The URL is
already parsed from the scanner JSON output but is currently dropped when mapping to the domain `ScanResult`. Depends on
[uploading results](#upload-scan-results-to-sysdig-secure), since the URL is only meaningful when the result exists in
the backend.

## Standalone / offline mode

Support running the scanner with `--standalone` using a local vulnerability database, with a configurable policy:
always, never, or automatically when the Sysdig backend is unreachable (connectivity check with a short timeout).
Standalone scans skip result upload and policy evaluation.

## Upload scan results to Sysdig Secure

Add a configuration option to upload scan results to the Sysdig Secure backend. The scanner is currently always invoked
with `--skipupload`.

## Custom policies configuration

Allow configuring additional policies to evaluate during scans (scanner `--policy` flag), e.g. via a
`sysdig.policies` initialization option.

## Configurable report detail level

Add a configuration option to toggle detailed CVE tables (CVSS score/vector, exploitability, fix version) in hover
reports, equivalent to the extension's `detailedReports` setting.

## Custom CLI scanner source

Allow configuring a custom download URL for the CLI scanner binary (e.g. for air-gapped environments). The download URL
is currently hardcoded to `download.sysdig.com`.

## Scan whole manifest

Provide a single command that scans all images found in a Docker Compose file or Kubernetes manifest at once, instead of
requiring one command execution per image.

## Build args support in Build and Scan

Accept Dockerfile `ARG` values as arguments of the `sysdig-lsp.execute-build-and-scan` command and forward them as
build args to the Docker build. Prompting the user for the values is client-side UI; the LSP only needs to accept and
apply them.
3 changes: 2 additions & 1 deletion src/app/component_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use serde::Deserialize;
use thiserror::Error;
use tower_lsp::jsonrpc::{Error as LspError, ErrorCode};

use super::{ImageBuilder, ImageScanner};
use super::{IacScanner, ImageBuilder, ImageScanner};

#[derive(Clone, Debug, Default, Deserialize)]
pub struct Config {
Expand All @@ -22,6 +22,7 @@ pub struct SysdigConfig {
pub struct Components {
pub scanner: Box<dyn ImageScanner + Send + Sync>,
pub builder: Box<dyn ImageBuilder + Send + Sync>,
pub iac_scanner: Box<dyn IacScanner + Send + Sync>,
}

pub trait ComponentFactory: Send + Sync {
Expand Down
Loading
Loading