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
2 changes: 1 addition & 1 deletion src/pages/docs/api.astro
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ curl -s -H "Authorization: Bearer $OM_API_SECRET" \\
<p>
<code>GET /v1/graph/query?name=internet-to-datastore</code> returns <code>query</code>,
<code>summary</code>, and <code>paths</code>. Each path is an array of nodes. When a
CloudTrail or Activity Log event’s resource node is on a path, <code>audits</code> lists that
CloudTrail, Activity Log, or Admin Activity event’s resource node is on a path, <code>audits</code> lists that
event with <code>index</code> set to the path’s position. Unknown names
are 400. The six names are listed by <code>GET /v1/graph/queries</code> as
<code>{`{"queries":[{"name":"...","description":"..."}]}`}</code>. See
Expand Down
4 changes: 2 additions & 2 deletions src/pages/docs/architecture.astro
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
<p>
Core is one Go module. The CLI and the API share <code>internal/graph</code>,
<code>internal/rules</code>, and the collectors. PostgreSQL is the graph store. Phase 3 adds
the plugin SDK, the embedded rule pack, a Helm chart, CloudTrail management events on
the AWS collector, and Activity Log events on the Azure collector, on top of the Phase 2 feature set.
the plugin SDK, the embedded rule pack, a Helm chart, and cloud audit context from
CloudTrail, Activity Log, and Admin Activity logs, on top of the Phase 2 feature set.
</p>
<pre><code>{`Cloud / Kubernetes APIs
│
Expand Down
14 changes: 8 additions & 6 deletions src/pages/docs/attack-paths.astro
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
{
question: 'Where do cloud audit events show up on a path?',
answer:
'om scan aws stores recent CloudTrail management events, and om scan azure stores recent Activity Log events, on the identity and resource they name. GET /v1/graph/query returns those events in audits when the resource node is on a path. om paths run prints the same lines under the path.',
'om scan aws stores recent CloudTrail management events, om scan azure stores recent Activity Log events, and om scan gcp stores recent Admin Activity audit logs, on the identity and resource they name. GET /v1/graph/query returns those events in audits when the resource node is on a path. om paths run prints the same lines under the path.',
},
]}
related={[
Expand Down Expand Up @@ -180,8 +180,9 @@ import DocsLayout from '@/layouts/DocsLayout.astro';

<h2>Audit events on a path</h2>
<p>
<code>om scan aws</code> reads CloudTrail management events, and <code>om scan azure</code>
reads administrative Activity Log events, from the last 24 hours. A match is stored as
<code>om scan aws</code> reads CloudTrail management events, <code>om scan azure</code>
reads administrative Activity Log events, and <code>om scan gcp</code> reads Admin Activity
audit logs, from the last 24 hours. A match is stored as
<code>audit_events</code> 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
Expand All @@ -194,9 +195,10 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
<code>paths</code>. The same event stored on two nodes of one path is listed once.
<code>om paths run</code> prints the time, event name, principal, and resource under that
path. The console does the same. <code>GetObject</code> is an S3 data event and is not in
this slice. Entra ID sign-in logs and GCP Cloud Audit Logs are not collected. See the
<a href="/docs/collectors/aws/">AWS collector</a> and the
<a href="/docs/collectors/azure/">Azure collector</a>.
this slice. Entra ID sign-in logs and GCP Data Access logs are not collected. See the
<a href="/docs/collectors/aws/">AWS collector</a>, the
<a href="/docs/collectors/azure/">Azure collector</a>, and the
<a href="/docs/collectors/gcp/">GCP collector</a>.
</p>

<h2>Reading an empty result</h2>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/docs/cli.astro
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
</tr>
<tr>
<td><code>om scan gcp</code></td>
<td>GCE, GCS, and service accounts in <code>GCP_PROJECT_ID</code>.</td>
<td>GCE, GCS, service accounts, and Admin Activity audit logs from the last 24 hours in <code>GCP_PROJECT_ID</code>.</td>
</tr>
<tr>
<td><code>om scan k8s</code></td>
Expand All @@ -77,7 +77,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
</tr>
<tr>
<td><code>om paths run &lt;name&gt;</code></td>
<td>Run one named query and print paths. A CloudTrail or Activity Log event whose resource is on a path is printed under that path.</td>
<td>Run one named query and print paths. A CloudTrail, Activity Log, or Admin Activity event whose resource is on a path is printed under that path.</td>
</tr>
<tr>
<td><code>om graph stats</code></td>
Expand Down
5 changes: 3 additions & 2 deletions src/pages/docs/collectors/aws.astro
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
<p>
<code>GET /v1/graph/query</code> and <code>om paths run</code> list those events in
<code>audits</code> when the resource node is on the returned path. The console prints the
same lines under the path. GCP Cloud Audit Logs are not collected. Azure Activity Log events
are collected by <a href="/docs/collectors/azure/">om scan azure</a>.
same lines under the path. Azure Activity Log events are collected by
<a href="/docs/collectors/azure/">om scan azure</a>. GCP Admin Activity logs are collected by
<a href="/docs/collectors/gcp/">om scan gcp</a>.
</p>

<h2>Read-only actions</h2>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/docs/collectors/azure.astro
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ az login
<code>GET /v1/graph/query</code> and <code>om paths run</code> list those events in
<code>audits</code> when the resource node is on the returned path. The console prints the
same lines under the path. Entra ID sign-in logs and storage data-plane reads are not in
the Activity Log, so this slice does not collect them. GCP Cloud Audit Logs are not
collected.
the Activity Log, so this slice does not collect them. GCP Admin Activity logs are collected
by <a href="/docs/collectors/gcp/">om scan gcp</a>.
</p>

<h2>Read access</h2>
Expand Down
52 changes: 50 additions & 2 deletions src/pages/docs/collectors/gcp.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';

<DocsLayout
title="GCP security collector"
description="What om scan gcp collects from Compute Engine, Cloud Storage, service accounts, and IAM bindings, and which edges those resources produce."
description="What om scan gcp collects from Compute Engine, Cloud Storage, service accounts, IAM bindings, and Admin Activity audit logs, and which edges those resources produce."
>
<h1>GCP security collector</h1>
<p>
Expand Down Expand Up @@ -38,7 +38,7 @@ gcloud auth application-default login
<tbody>
<tr>
<td>Compute <code>instances.aggregatedList</code></td>
<td><code>Workload</code>. Properties: <code>resource_id</code> (self link), <code>public_ip</code> (NAT IP, or empty), <code>status</code>. A NAT IP adds <code>REACHABLE</code> from <code>internet:global</code>. Firewall rules are not consulted. Each attached service account gets an <code>ASSUMES</code> edge from the instance.</td>
<td><code>Workload</code>. Properties: <code>resource_id</code> (self link), <code>public_ip</code> (NAT IP, or empty), <code>status</code>. A NAT IP or a public load balancer adds <code>REACHABLE</code> from <code>internet:global</code> when a firewall allow is not covered by a higher-priority deny. The firewall is a <code>Network</code> node. Each attached service account gets an <code>ASSUMES</code> edge from the instance.</td>
</tr>
<tr>
<td>Storage bucket list, then each bucket’s IAM policy</td>
Expand All @@ -48,6 +48,14 @@ gcloud auth application-default login
<td>IAM service accounts, then the project IAM policy</td>
<td><code>Identity</code> named by email, with <code>email</code> and <code>admin_access</code>. Project bindings that grant object access add <code>CAN_ACCESS</code> to every bucket in the project.</td>
</tr>
<tr>
<td>Cloud SQL instances</td>
<td><code>Datastore</code> with <code>resource_id</code> (connection name), <code>service: cloudsql</code>, <code>public_access</code>, and <code>sensitivity</code> when a user label names it. A workload gets <code>CAN_ACCESS</code> when it shares the instance’s private-IP network, or its public IP is in an authorized network.</td>
</tr>
<tr>
<td>Logging <code>entries.list</code> for the Admin Activity log, last 24 hours</td>
<td>Up to five <code>audit_events</code> on the identity and the resource the event names. See below.</td>
</tr>
</tbody>
</table>
</div>
Expand Down Expand Up @@ -106,4 +114,44 @@ gcloud auth application-default login
included. A bucket policy that cannot be read is stored as not public and adds no
<code>CAN_ACCESS</code> edges. The scan continues.
</p>

<h2>Cloud Audit Logs</h2>
<p>
After inventory is built, the scan lists Admin Activity log entries for the project from the
last 24 hours. The call is Logging <code>entries.list</code> on
<code>projects/GCP_PROJECT_ID</code>, filtered to
<code>cloudaudit.googleapis.com/activity</code>, newest first, and it stops after four pages.
A failed lookup omits <code>audit_events</code> and does not fail the scan.
</p>
<p>
An event is kept when its method is on a fixed admin list (for example
<code>v1.compute.instances.insert</code>, <code>storage.buckets.update</code>,
<code>v1.compute.firewalls.patch</code>, <code>SetIamPolicy</code>,
<code>cloudsql.instances.update</code>) and its principal email matches an identity already
in the batch. The resource has to sit on an exposed path: 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. Instance and firewall names
match the self link stored on the node. A bucket event uses
<code>projects/_/buckets/NAME</code>. A service-account key walks up to that identity. A
project <code>SetIamPolicy</code> event is stored on the identity, because the project is
not a node. The same event is stored on the identity and the resource, newest first, at
most five per node.
</p>
<p>
<code>GET /v1/graph/query</code> and <code>om paths run</code> list those events in
<code>audits</code> when the resource node is on the returned path. The console prints the
same lines under the path. Data Access logs, including object reads, are a different log, so
this slice does not collect them. CloudTrail events are collected by
<a href="/docs/collectors/aws/">om scan aws</a>. Activity Log events are collected by
<a href="/docs/collectors/azure/">om scan azure</a>.
</p>

<h2>Read access</h2>
<p>
The scan lists instances, firewalls, load-balancer pieces, buckets, bucket IAM, service
accounts, the project IAM policy, Cloud SQL instances, and Admin Activity log entries.
Listing those entries needs <code>logging.logEntries.list</code>. Logs Viewer
(<code>roles/logging.viewer</code>) includes it. The collector does not call mutating APIs
and does not request Data Access logs.
</p>
</DocsLayout>
4 changes: 2 additions & 2 deletions src/pages/docs/collectors/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
</tr>
<tr>
<td><a href="/docs/collectors/gcp/"><code>om scan gcp</code></a></td>
<td>Compute instances, GCS buckets, service accounts</td>
<td>Compute instances, GCS buckets, service accounts, recent Admin Activity audit logs</td>
<td>Application Default Credentials and <code>GCP_PROJECT_ID</code></td>
</tr>
<tr>
Expand Down Expand Up @@ -107,7 +107,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
</tr>
<tr>
<td>GCP</td>
<td>The instance has a NAT IP. Firewall rules are not read.</td>
<td>The instance has a NAT IP or sits behind a public load balancer, and a firewall allow is not covered by a higher-priority deny.</td>
</tr>
<tr>
<td>Kubernetes</td>
Expand Down
9 changes: 5 additions & 4 deletions src/pages/docs/open-source.astro
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
</table>
</div>
<p>
<code>om scan aws</code> stores CloudTrail management events, and <code>om scan azure</code>
stores Activity Log 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.
GCP Cloud Audit Logs are not collected yet. <strong>Platform audit logs</strong> — operator actions in the
<code>om scan aws</code> stores CloudTrail management events, <code>om scan azure</code>
stores Activity Log events, and <code>om scan gcp</code> stores Admin Activity audit logs,
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. Data Access logs are not
collected. <strong>Platform audit logs</strong> — operator actions in the
console/API, SSO identity, retention, and auditor export — belong in the commercial offering.
</p>

Expand Down
2 changes: 1 addition & 1 deletion src/pages/docs/schema.astro
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ import DocsLayout from '@/layouts/DocsLayout.astro';
<li><code>mfa</code>, <code>unused_access_keys</code> — IAM user pack rules</li>
<li><code>public_ip</code>, <code>imdsv2</code> — workload exposure and metadata rules</li>
<li><code>packages</code>, <code>image</code>, <code>images</code> — workload inventory that <code>om enrich cve</code> matches. Rules do not read these keys. See <a href="/docs/enrichment/">CVE enrichment</a>.</li>
<li><code>audit_events</code> — recent CloudTrail or Activity Log events on an identity or resource. Each item has <code>id</code>, <code>name</code>, <code>time</code>, <code>principal</code>, <code>resource</code>, <code>principal_node_id</code>, <code>resource_node_id</code>, and optional <code>source_ip</code> and <code>read_only</code>. <code>om scan aws</code> and <code>om scan azure</code> write 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 <code>audits</code> when its resource node is on the path. Rules do not match this key.</li>
<li><code>audit_events</code> — recent CloudTrail, Activity Log, or Admin Activity events on an identity or resource. Each item has <code>id</code>, <code>name</code>, <code>time</code>, <code>principal</code>, <code>resource</code>, <code>principal_node_id</code>, <code>resource_node_id</code>, and optional <code>source_ip</code> and <code>read_only</code>. <code>om scan aws</code>, <code>om scan azure</code>, and <code>om scan gcp</code> write 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 <code>audits</code> when its resource node is on the path. Rules do not match this key.</li>
<li><code>internet_reachable</code>, <code>path_to_datastore</code>, <code>admin_can_access</code> — graph match keys on YAML rules, computed at run time, not stored by collectors</li>
</ul>

Expand Down
Loading