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
3 changes: 2 additions & 1 deletion doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
| [Hive & Data Stores](cli/hive-data.md) | hive, secret, lookup, playbook, note, sop, adapter, cloud-sensor, extension |
| [Infrastructure](cli/infrastructure.md) | sync, output, artifact, payload, yara, integrity, logging, exfil |
| [Cloud Security & Code Security](cli/cloud-security.md) | cloudsec (findings, inventory, graph, compliance, CAASM, code lane, container images, fleet, exports) |
| [Email Security](cli/email-security.md) | mailsec (triage queue, EML, remediation, campaigns, reports, hunts, rules, tenant purge) |
| [Email Security](cli/email-security.md) | mailsec (onboarding, coverage, triage, EML, remediation, campaigns, reports, rules, tenant purge) |
| [Other Commands](cli/other-commands.md) | api, arl, usp, spotcheck, job, schema, completion, help/discover |

## SDK Reference
Expand All @@ -34,6 +34,7 @@
| [Search & Insight](sdk/search-insight.md) | Search (LCQL), Insight (IOC) |
| [Streaming](sdk/streaming.md) | Spout, Firehose |
| [Configuration Sync](sdk/configs.md) | Configs (IaC) |
| [Security Products](sdk/security-products.md) | CloudSec, Mailsec, onboarding, and pagination |
| [Other Classes](sdk/other-classes.md) | Extensions, Artifacts, Payloads, Outputs, AI, Billing, CloudSec, etc. |

## External Resources
Expand Down
17 changes: 10 additions & 7 deletions doc/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,22 @@ limacharlie sensor list -W # All columns untruncated

```bash
# List all commands grouped by use-case
limacharlie discover
limacharlie discover --profile detection_engineering
limacharlie discover --profile incident_response
limacharlie help discover
limacharlie help discover --profile cloud_security
limacharlie help discover --profile email_security

# Concept guides
limacharlie help d&r-rules
limacharlie help hive
limacharlie help lcql
limacharlie help cloud-security
limacharlie help code-security
limacharlie help email-security

# Quick-reference cheat sheets
limacharlie cheatsheet common-operations
limacharlie cheatsheet detection-engineering
limacharlie cheatsheet incident-response
limacharlie help cheatsheet --name cloud-security
limacharlie help cheatsheet --name code-security
limacharlie help cheatsheet --name email-security

# Detailed explanation of any command
limacharlie dr create --ai-help
Expand All @@ -147,7 +150,7 @@ limacharlie schema dr create
| [Hive & Data Stores](hive-data.md) | hive, secret, lookup, playbook, note, sop, adapter, cloud-sensor, extension |
| [Infrastructure](infrastructure.md) | sync, output, artifact, payload, yara, integrity, logging, exfil |
| [Cloud Security & Code Security](cloud-security.md) | cloudsec (findings, inventory, graph, compliance, CAASM, code lane, container images, fleet, exports) |
| [Email Security](email-security.md) | mailsec (triage queue, EML, remediation, campaigns, reports, hunts, rules, tenant purge) |
| [Email Security](email-security.md) | mailsec (onboarding, coverage, triage, EML, remediation, campaigns, reports, rules, tenant purge) |
| [Other Commands](other-commands.md) | api, arl, usp, spotcheck, job, schema, completion, help/discover, case |

## See Also
Expand Down
70 changes: 65 additions & 5 deletions doc/cli/cloud-security.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

# Cloud Security (CNAPP) & Code Security

Install or upgrade with `python -m pip install --upgrade limacharlie`. See [installation](../getting-started.md#installation) for setup.

Commands for the LimaCharlie Cloud Security surface: the merged, risk-ranked findings worklist (CSPM misconfigurations + attack paths + CIEM + code and container-image vulnerabilities), the cloud resource inventory and security graph, compliance assessment (live and audit-grade), the risk overview, CAASM (third-party asset attack surface), the AppSec code lane and container-image inventory, sensor↔cloud-asset resolution, finding triage, CSV exports, and the multi-org fleet overview.

Reads usually require `cloudsec.get`. Most writes require `cloudsec.set`; AutoFix and remediation decisions require `cloudsec.respond`, and reading an IaC map receipt requires `cloudsec.set`. Every command requires the org to be subscribed to the Cloud Security extension:
Reads usually require `cloudsec.get`. Local `code scan` without ingestion and
`code iac-map extract` work offline; they do not require a subscription or API key. Most writes require `cloudsec.set`; AutoFix and remediation decisions require `cloudsec.respond`, and reading an IaC map receipt requires `cloudsec.set`. API commands require the org to be subscribed to the Cloud Security extension:

```bash
limacharlie extension subscribe --name ext-cloud-security
Expand All @@ -14,6 +17,10 @@ Provider credentials and the cloudsec policies are hive records — manage them

Every command supports `--ai-help` for a detailed description with examples.

For `code pr-check`, GitHub requires `--base-sha`; GitLab.com and Bitbucket
Cloud may omit it because the provider resolves the base. Supply `--head-sha`
and `--action` for every provider. `--action edited` is GitHub-only.

## Overview & posture

```bash
Expand Down Expand Up @@ -249,7 +256,21 @@ Tenant → management group → subscription → resource group → resource con

## CSV exports

The server walks the full filtered set (no pagination), capped at 100k rows; a trailing `#` comment row marks a truncated export.
By default the server walks the full filtered set, capped at 100k rows; a trailing
`#` comment row marks a truncated export. For findings and inventory, use
`--max-rows` to export in bounded requests. The size is rounded up to full
1000-row pages. If more rows remain, the CSV ends with `# next_cursor=<token>`;
pass that token to the next request with the same size, filters and sort. A chunk
without a continuation comment is the end. Each chunk includes its own header.

```bash
limacharlie cloudsec export findings --max-rows 2000 -o findings-1.csv
limacharlie cloudsec export findings --max-rows 2000 --cursor "<token>" -o findings-2.csv
```

`--cursor` requires `--max-rows` so a resumed request cannot silently restart the
export. CSV comments can also report truncation or a mid-stream error; inspect
them before treating an export as complete.

```bash
limacharlie cloudsec export findings -o findings.csv --severity CRITICAL
Expand All @@ -270,12 +291,22 @@ limacharlie cloudsec resolve assets "lcrn:...instance/web-1" # asset -> sensors

```bash
limacharlie cloudsec caasm assets -q laptop --limit 50
limacharlie cloudsec caasm assets --kind device --source ms_graph --posture-encryption ""
limacharlie cloudsec caasm assets --sort last_seen
limacharlie cloudsec caasm coverage --status open --severity HIGH
limacharlie cloudsec caasm policy get
limacharlie cloudsec caasm policy set --input-file policy.yaml
limacharlie cloudsec caasm ingest --source okta --records-file users.json
```

Asset selectors `--kind`, `--source`, `--posture-encryption`,
`--posture-screen-lock`, `--posture-compromised` and `--posture-managed` are
repeatable: values within a selector are OR'd, selectors are AND'd. Use the posture
values your sources report; an empty value selects assets where no source reported
that fact. Unreported posture never means compliant. `--sort urn` is the stable
walk order; `--sort last_seen` shows the newest observations first. Follow
`next_cursor` until absent, including after short pages.

Ingest sources today: `sentinelone`, `crowdstrike`, `defender`, `okta`, `entraid`, `ms_graph`, `wiz` (the registry grows and is validated server-side).

## Providers
Expand All @@ -284,8 +315,20 @@ Ingest sources today: `sentinelone`, `crowdstrike`, `defender`, `okta`, `entraid
limacharlie cloudsec provider test --input-file provider.yaml # credential preflight (ephemeral)
limacharlie cloudsec provider manifest # coverage manifests, all providers
limacharlie cloudsec provider manifest --type gcp
limacharlie cloudsec provider m365-certificate my-entra --client-id "<application-id>" --out connection.cer
```

For Entra/Microsoft 365 certificate authentication, `m365-certificate` requires
both `cloudsec.set` and `secret.set`. It stores the private key in the organization's
secret store and returns only the public certificate and a `credentials` Hive
reference. Upload `connection.cer` under **Certificates & secrets → Certificates**
in your Entra app registration, then use the returned reference as `credentials`
in the provider record. Grant the app the provider permissions before running
`provider test`. Repeating generation returns the same certificate.
`--replace` replaces the stored key pair immediately. An existing connection may
stop authenticating until you upload the replacement public certificate to the
Entra app registration.

Saved provider configs live in the `cloudsec_provider` hive:

```bash
Expand Down Expand Up @@ -372,7 +415,11 @@ limacharlie hive set --hive-name cloudsec_policy --key hub-private-image \

`registry` is `dockerhub`, `quay` or `ghcr`; `repository` is one lowercase `namespace/image` (a GHCR path may be deeper), `username` a registry account or robot name, and `secret_ref` must be `hive://secret/<name>` of an existing secret you can read. Use a read-only token. ECR and ACR images use the cloud connection's own read access instead (`setup_path` `integrations/<provider>`), scoped to one repository per pull.

`code capabilities` covers **GitHub connections only** — a GitLab or Bitbucket connection scans with its own read-only token and has no write plane to detect, so it never appears, not even as `unknown`. Use `provider manifest` for those. A capability of `available` means the control MAY be offered, not that anything fires on its own.
`code capabilities` reports GitHub connections. GitLab.com and Bitbucket Cloud
connections also appear when their workflow support is enabled in your deployment;
an absent connection does not mean repository scanning is off. Use
`provider manifest` for collection coverage. A capability of `available` means the
control can be offered, not that anything fires on its own.

`code fixes` pages differently from the rest of cloudsec: backend default 5, max 20, not the shared 1000-row cap.

Expand Down Expand Up @@ -429,9 +476,10 @@ not a `/cloudsec` API route. It requires `ext.request`. The SDK equivalent is

```bash
limacharlie cloudsec image repos --with-findings --sort risk
limacharlie cloudsec image repo-facets
limacharlie cloudsec image repo-facets --lineage-facet
limacharlie cloudsec image list --findings with --running --sort risk
limacharlie cloudsec image list --tag latest --registry gcr.io --all
limacharlie cloudsec image list --lineage-status unknown --lineage-status ambiguous --all
limacharlie cloudsec image get sha256:<64 hex>
limacharlie cloudsec finding list --image-urn "<urn from image list>"
```
Expand All @@ -440,6 +488,14 @@ An image is keyed on its **digest alone**, so one row is the same artifact every

`repositories`, `memberships`, `workloads` and `source_repositories` are BOUNDED SAMPLES of 100 with no pagination — the paired `*_count` is the truth, and only memberships carry a `_truncated` flag. To get past 100 placements, use `image list --repo-urn ...` instead.

`image list --lineage-status` accepts repeatable `verified`, `asserted`,
`inferred`, `ambiguous` and `unknown` selectors. They select the effective
source-lineage state, separately from image-signature status (`--signed`). A stale
decision counts as `unknown`. The SDK checks `applied_lineage_status`; an older
server that cannot acknowledge the filter raises an error instead of returning an
unfiltered page. `image repo-facets --lineage-facet` adds exact digest-global
`lineage_statuses` counts; repository selectors do not narrow those counts.

`image get` also returns a digest-bound `lineage` decision. Read its `tier`
(`inferred`, `tool_emitted`, or `our_signed_push`), `status`, and `reason`
together: `inferred` and `asserted` do not mean a verified build. The
Expand Down Expand Up @@ -502,7 +558,11 @@ A rule set document holds one entry per rule file, where each `rules` value is a

Before the scan starts, the CLI refuses a document the scanner would not accept: unknown fields, a version other than 1, a record without a unique non-empty `key` or a `rules` object, more than 32 MiB, or no rules at all. The scanner checks each rule, then reports and skips any rule it cannot load.

**Scanner version.** The default image is pinned to scanner v0.16.0. A `--image` or `--binary` running `sast` must be v0.16.0 or newer, because older scanners reject the rule-set flags. That failure is a usage error (exit 2), and the CLI's error message names the version you need. A scan without `sast` passes no rule-set flag, so it still runs on older scanners.
**Scanner version and access.** The default image is pinned to scanner v0.24.0.
Pulling the default image requires registry access. If it is unavailable to your
account, use an accessible scanner image with `--image` or an installed
`scanner-agent` with `--binary`; do not assume an organization API key grants
container-registry access. A `--image` or `--binary` running `sast` must be v0.16.0 or newer, because older scanners reject the rule-set flags. That failure is a usage error (exit 2), and the CLI's error message names the version you need. A scan without `sast` passes no rule-set flag, so it still runs on older scanners.

### Sanitized IaC maps

Expand Down
Loading
Loading