diff --git a/src/pages/docs/api.astro b/src/pages/docs/api.astro index 2fb65d4..4532e8b 100644 --- a/src/pages/docs/api.astro +++ b/src/pages/docs/api.astro @@ -127,7 +127,9 @@ curl -s -H "Authorization: Bearer $OM_API_SECRET" \\ }`}

GET /v1/graph/query?name=internet-to-datastore returns query, - summary, and paths. Each path is an array of nodes. Unknown names + summary, and paths. Each path is an array of nodes. When a + CloudTrail management event’s resource node is on a path, audits lists that + event with index set to the path’s position. Unknown names are 400. The six names are listed by GET /v1/graph/queries as {`{"queries":[{"name":"...","description":"..."}]}`}. See Attack paths for depth and row limits. diff --git a/src/pages/docs/architecture.astro b/src/pages/docs/architecture.astro index fb567c5..39529ef 100644 --- a/src/pages/docs/architecture.astro +++ b/src/pages/docs/architecture.astro @@ -34,7 +34,8 @@ import DocsLayout from '@/layouts/DocsLayout.astro';

Core is one Go module. The CLI and the API share internal/graph, internal/rules, and the collectors. PostgreSQL is the graph store. Phase 3 adds - the plugin SDK, the embedded rule pack, and a Helm chart on top of the Phase 2 feature set. + the plugin SDK, the embedded rule pack, a Helm chart, and CloudTrail management events on + the AWS collector, on top of the Phase 2 feature set.

{`Cloud / Kubernetes APIs
         │
diff --git a/src/pages/docs/attack-paths.astro b/src/pages/docs/attack-paths.astro
index a12dac8..b66ef82 100644
--- a/src/pages/docs/attack-paths.astro
+++ b/src/pages/docs/attack-paths.astro
@@ -6,7 +6,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
 
 
 
+  

CloudTrail on a path

+

+ om scan aws reads CloudTrail management events from the last 24 hours and + stores a match as audit_events on the identity and the resource the event + names. A match requires both nodes to already be in the scan, and the resource has to sit + on an exposed path: an internet-reachable workload, something that workload assumes or can + access, a public datastore, or an identity that can access one. At most five events are + kept on a node, newest first. A failed lookup leaves the property off and the rest of the + scan still ingests. +

+

+ GET /v1/graph/query copies an event into audits when that + resource node is on the returned path. index is the path’s position in + paths. The same event stored on two nodes of one path is listed once. + om paths run prints the time, event name, principal, and resource under that + path. The console does the same. GetObject is an S3 data event and is not in + this slice. Azure and GCP audit logs are not collected. See the + AWS collector. +

+

Reading an empty result

An empty path list means the edges are not there, not that the account is safe. The walk diff --git a/src/pages/docs/cli.astro b/src/pages/docs/cli.astro index 20f379c..08067c1 100644 --- a/src/pages/docs/cli.astro +++ b/src/pages/docs/cli.astro @@ -45,7 +45,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro'; om scan aws - EC2, security groups, IAM, and S3 in AWS_REGION. + EC2, security groups, IAM, and S3 in AWS_REGION, plus CloudTrail management events from the last 24 hours. om scan azure @@ -77,7 +77,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro'; om paths run <name> - Run one named query and print paths. + Run one named query and print paths. A CloudTrail event whose resource is on a path is printed under that path. om graph stats diff --git a/src/pages/docs/collectors/aws.astro b/src/pages/docs/collectors/aws.astro index 43396c8..0243cb1 100644 --- a/src/pages/docs/collectors/aws.astro +++ b/src/pages/docs/collectors/aws.astro @@ -6,7 +6,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';

AWS security collector

@@ -51,6 +51,10 @@ import DocsLayout from '@/layouts/DocsLayout.astro'; S3 bucket list, public access block, encryption, versioning Datastore with service: s3, public_access, public_access_block (disabled or enabled), encryption, versioning, and sensitivity when a bucket tag names it. + + CloudTrail LookupEvents + Up to five audit_events on the identity and the resource the event names. See below. + @@ -98,11 +102,35 @@ import DocsLayout from '@/layouts/DocsLayout.astro'; account-wide. EC2 and security groups are the one region in AWS_REGION.

+

CloudTrail

+

+ After inventory is built, the scan calls cloudtrail:LookupEvents for the last 24 + hours in AWS_REGION. IAM and S3 management events are recorded in + us-east-1, so a scan of another region also looks there. Each lookup stops after + four pages. A failed lookup omits audit_events and does not fail the scan. +

+

+ An event is kept when its name is on a fixed management-event list (for example + AssumeRole, PutBucketPolicy, AuthorizeSecurityGroupIngress) + and it names an identity already in the batch plus a resource on an exposed path. Exposed + means an internet-reachable workload, a node that workload assumes or can access, a network + that workload affects, a public datastore, or an identity that can access a public datastore. + The same event is stored on both nodes, newest first, at most five per node. + GetObject is an S3 data event. LookupEvents does not return it, so + this slice does not. +

+

+ GET /v1/graph/query and om paths run list those events in + audits when the resource node is on the returned path. The console prints the + same lines under the path. Azure Activity Log and GCP Cloud Audit Logs are not collected. +

+

Read-only actions

A least-privilege policy for this collector needs read access for the calls above, including iam:GetInstanceProfile, iam:ListAttachedRolePolicies, iam:ListRolePolicies, iam:GetRolePolicy, iam:GetPolicy, - iam:GetPolicyVersion, and s3:GetBucketTagging. The scan does not call mutating APIs. + iam:GetPolicyVersion, s3:GetBucketTagging, and + cloudtrail:LookupEvents. The scan does not call mutating APIs.

diff --git a/src/pages/docs/collectors/index.astro b/src/pages/docs/collectors/index.astro index af69d3a..4aa3c96 100644 --- a/src/pages/docs/collectors/index.astro +++ b/src/pages/docs/collectors/index.astro @@ -55,7 +55,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro'; om scan aws - EC2, security groups, IAM roles and users, S3, instance-profile access to S3 + EC2, security groups, IAM roles and users, S3, instance-profile access to S3, recent CloudTrail management events AWS default chain, one region diff --git a/src/pages/docs/console.astro b/src/pages/docs/console.astro index 384d21f..d4fdc69 100644 --- a/src/pages/docs/console.astro +++ b/src/pages/docs/console.astro @@ -21,7 +21,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
  • Read node and edge counts in the stats strip. Those numbers come from GET /v1/graph/stats.
  • Scan the findings list from GET /v1/findings. Each card shows severity, title, and the affected resource. An attack-path card also prints the path node ids. Choosing a card highlights the affected resource when it is in the current snapshot.
  • The dropdown loads every named query. On first paint it selects internet-to-datastore when that query exists, then draws those paths. Choose Full graph snapshot to call GET /v1/graph/snapshot instead (500 nodes and 2000 edges).
  • -
  • A named query still uses the snapshot’s edge list to label each hop. If the connecting edge is past that 2000-edge cap, the hop is drawn as type PATH and any reason property is missing. The nodes themselves come from the query, not from the snapshot cap.
  • +
  • A named query still uses the snapshot’s edge list to label each hop. If the connecting edge is past that 2000-edge cap, the hop is drawn as type PATH and any reason property is missing. The nodes themselves come from the query, not from the snapshot cap. CloudTrail events returned in audits are listed under that path.
  • Select an identity node to load GET /v1/identity/blast-radius. The panel shows the summary and the reachable nodes. See Blast radius. Other node types do not open that panel.
  • Refresh reloads stats, findings, and the current view after you ingest from the CLI. The page does not poll.
  • diff --git a/src/pages/docs/index.astro b/src/pages/docs/index.astro index be9ddb3..1b8ede4 100644 --- a/src/pages/docs/index.astro +++ b/src/pages/docs/index.astro @@ -50,7 +50,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro'; diff --git a/src/pages/docs/open-source.astro b/src/pages/docs/open-source.astro index 9435d67..375f8a7 100644 --- a/src/pages/docs/open-source.astro +++ b/src/pages/docs/open-source.astro @@ -85,8 +85,10 @@ import DocsLayout from '@/layouts/DocsLayout.astro';

    - Cloud provider audit APIs (for example CloudTrail) are Phase 3 graph context: evidence of - exposure and attack paths. Platform audit logs — operator actions in the + om scan aws stores CloudTrail management events from the last 24 hours on the + identity and resource they name, when that resource is on an exposed path. Path queries + return those events with the path. Azure Activity Log and GCP Cloud Audit Logs are not + collected yet. Platform audit logs — operator actions in the console/API, SSO identity, retention, and auditor export — belong in the commercial offering.

    diff --git a/src/pages/docs/schema.astro b/src/pages/docs/schema.astro index d24b80b..5c5a2f1 100644 --- a/src/pages/docs/schema.astro +++ b/src/pages/docs/schema.astro @@ -160,6 +160,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
  • mfa, unused_access_keys — IAM user pack rules
  • public_ip, imdsv2 — workload exposure and metadata rules
  • packages, image, images — workload inventory that om enrich cve matches. Rules do not read these keys. See CVE enrichment.
  • +
  • audit_events — recent CloudTrail management events on an identity or resource. Each item has id, name, time, principal, resource, principal_node_id, resource_node_id, and optional source_ip and read_only. om scan aws writes at most five, newest first, and only when the resource is on an exposed path. A plugin may set the same list. Named path queries copy an event into audits when its resource node is on the path. Rules do not match this key.
  • internet_reachable, path_to_datastore, admin_can_access — graph match keys on YAML rules, computed at run time, not stored by collectors