Cloud Detection & Response
Overview
ARMO Cloud Detection & Response (CDR) for Google Cloud delivers continuous threat detection on your GCP environment. ARMO deploys a lightweight collector inside your GCP project that consumes Cloud Audit Logs (Admin Activity), evaluates every entry against ARMO's CEL-based detection rules, and forwards only matched security alerts to the ARMO Platform, where they appear as Runtime Incidents.
GCP CDR uses the same detection rule engine as ARMO's AWS and Azure CDR, so detections, incident workflows, and custom rules behave consistently across your clouds.
Cloud Detection and ResponseTo view all incidents related to your connected cloud environments, go to Runtime Incidents in the left navigation menu.
How It Works
- In the ARMO onboarding wizard, you enter your project (or organization) details and ARMO generates a ready-to-run Terraform module (or, for a single project, an equivalent
gcloud CLIcommand) with every parameter pre-filled. - You run it once in Cloud Shell. It provisions a Log Router sink that routes Admin Activity audit logs to a dedicated Pub/Sub topic in your project.
- Pub/Sub pushes each log entry, over an authenticated (OIDC) request, to an ARMO collector running on Cloud Run in your project.
- The collector evaluates every entry against ARMO's detection rules inside your project.
- Only matched alerts, each carrying the single log record that triggered it, are sent to the ARMO Platform and surfaced as Runtime Incidents.
Your logs stay in your projectRaw audit logs are processed by the collector in your own project (or your own security project, for an organization connection) and never leave your GCP environment. Only detection alerts and the minimal context needed to investigate them are transmitted to ARMO.
No credential is handed to ARMOUnlike the Compliance (CSPM) connection, CDR needs no service-account key. The collector runs under a service account the deployment creates, and it authenticates to ARMO with a per-connection access key stored in Secret Manager in your project. ARMO stores no GCP credential.
What ARMO Detects
ARMO's detection rules cover suspicious and high-risk activity in your GCP environment, for example:
- Creation of service account keys or impersonation of privileged service accounts
- IAM policy changes that grant privilege escalation paths
- Cloud Storage buckets made publicly accessible
- Firewall rules opened to the internet (0.0.0.0/0)
- Tampering with audit log configuration or log sinks
- Unusual or unauthorized API activity patterns
Detection rules are written in CEL (Common Expression Language) and managed under Policies → Threat Detection in the ARMO Platform. You can also author your own rules. See Custom Rules.
The collector downloads its rule set from ARMO and refreshes it periodically, so rule updates do not require redeploying anything in your project.
Log Coverage & Cost
| Log type | Default | Notes |
|---|---|---|
| Admin Activity audit logs | ✅ Ingested | Always enabled in GCP, free of charge, records administrative API calls. This is the only log type CDR evaluates today. |
| Data Access audit logs | Not yet | Data-plane visibility is planned for a later release. |
The CDR components run in your project, so their cost is billed to your GCP account:
- Pub/Sub, charged by message throughput. Admin Activity log volume is typically modest.
- Cloud Run, running the collector. The collector is kept always on (one minimum instance) so it can report its health to ARMO continuously.
- Secret Manager, one secret.
Prerequisites
| Item | Requirement |
|---|---|
| ARMO Platform | You have Admin or Manager access to the ARMO Platform. |
| GCP access (single project) | Project Owner or Editor, plus Service Account Admin (roles/iam.serviceAccountAdmin) and Logs Configuration Writer (roles/logging.configWriter) on the project. |
| GCP access (entire organization) | The above on the security project, plus Logs Configuration Writer at the organization to create the organization-level sink. In many companies this is a separate org admin, so the deployment may be a two-person hand-off. |
| GCP APIs | The deployment enables the Pub/Sub, Cloud Run, and Logging APIs in the target project if needed. |
| Host project | A billing-enabled project to host the collector. For an entire-organization connection, a dedicated security project. |
| Tooling | Google Cloud Shell, or a terminal with Terraform or gcloud signed in to the target project. |
| Connectivity | Outbound HTTPS (port 443) from the collector to the ARMO Platform. |
Single Project Onboarding
Step 1: Start the GCP CDR connection in ARMO
- In the ARMO Platform, go to Settings → Accounts → GCP and click Connect GCP.
- Select the Cloud Detection & Response feature.
- Under What will be the integration scope?, select Single Project and click Next.
The wizard walks through two steps — Configure (the details below) and Deploy (the module to run).
Step 2: Enter the connection details
| Field | Where to find it |
|---|---|
| Project ID | Google Cloud Console project picker. Use the project ID, not the display name or number. |
| Region | The region for the collector's Cloud Run service and Pub/Sub resources (default us-central1). |
| Name | A display name for this connection in ARMO. |
ARMO creates the connection and marks it Pending. No call to GCP is made at this point.
Step 3: Copy the deployment artifact
On the Deploy step, ARMO shows the module to run, pre-filled with every value it needs (your project ID, your ARMO tenant ID, the collector image, the ARMO alert and rule endpoints, and the connection's access key).
The default is a Terraform module — a provider "google" block followed by a module "armo_cdr" block whose source is pinned to a fixed version of ARMO's public gcp-templates modules:
provider "google" {
project = "<PROJECT_ID>"
region = "<REGION>"
}
module "armo_cdr" {
source = "github.com/armosec/gcp-templates//gcp/terraform/single-project?ref=<version>"
# project_id, region, customer_guid, collector_image_ref,
# alert_export_url, rule_endpoint_url, and access_key are pre-filled by ARMO.
}Where a gcloud CLI alternative is available, a Terraform / gcloud CLI toggle appears above the module. The gcloud CLI option is a single shell command that downloads the same version-pinned gcp-templates bundle and runs its deploy.sh with your parameters — use it if you would rather not manage Terraform state. Click Copy on the option you want.
The artifact contains a secretBoth the Terraform module and the
gcloud CLIcommand embed the access key for this connection. Treat it as a secret: do not share it, commit it to source control, or leave it in your shell history.
Step 4: Run it in Cloud Shell
Open Cloud Shell (the >_ icon in the Google Cloud Console top bar), or any terminal with gcloud installed (plus Terraform, if you use the Terraform option). Sign in and select the right project:
gcloud auth login
gcloud config set project <PROJECT_ID>Then run whichever option you copied:
-
Terraform — Terraform needs application-default credentials, so also run
gcloud auth application-default login. Save the block to a file namedmain.tfin an empty directory, then run:terraform init && terraform apply -
gcloud CLI — paste and run the copied command directly.
The module takes about two minutes to finish.
Step 5: Return to ARMO
The connection appears as Pending and flips to Connected once the collector reports that a real audit log has travelled the pipe (sink → Pub/Sub → collector). The deployment fires a small self-test so this usually happens 2–4 minutes after the module finishes, even in a quiet project. A few minutes of Pending is expected, not a failure.
What the deployment creates in your project
- A Log Router sink scoped to the project, filtered to Admin Activity audit logs.
- A Pub/Sub topic the sink publishes to, plus a dead-letter topic and subscription for undeliverable messages.
- A Pub/Sub push subscription that delivers each log entry to the collector over an authenticated (OIDC) push.
- A Cloud Run service running the ARMO collector, always on.
- Two service accounts: one the collector runs as, and one Pub/Sub uses to invoke the collector.
- A Secret Manager secret holding the connection's ARMO access key, mounted into the collector.
All resource names share a prefix (default armo-cdr) so they are easy to find and remove.
Entire Organization Onboarding
Connects your entire GCP organization, every project including ones created later, through one central collector in a security project of your choice. Detection still runs inside your organization; only matched alerts leave.
Coverage model: capture everything, exclude afterOne organization-level log sink routes every project's Admin Activity log to the central collector. You narrow scope by giving ARMO a list of excluded project IDs — alerts from those projects are dropped by ARMO and never become incidents. Because the sink captures the whole organization, an excluded project's logs still reach your own collector; the exclusion is applied by ARMO after capture, not on the sink (a GCP sink can only include, never exclude). Exclusion is by project ID: GCP log entries carry no folder information, so there is no folder-level scoping.
Step 1: Start the connection in ARMO
Click Connect GCP, select Cloud Detection & Response, choose Entire Organization, and click Next.
Step 2: Enter the connection details
| Field | Where to find it |
|---|---|
| Organization ID | Google Cloud Console → IAM & Admin → Settings (numeric organization ID, for example 123456789012). |
| Security project ID | The project the shared collector, topic, and secret are deployed into. It must not already hold a single-project CDR connection. |
| Region | The region for the central collector. |
| Excluded projects (optional) | Comma-separated project IDs whose alerts should be ignored. Leave empty to capture every project. Editable later without redeploying. |
| Name | A display name for this connection in ARMO. |
Step 3: Copy and run the deployment artifact
On the Deploy step, ARMO shows a Terraform module (entire-organization onboarding is Terraform-only; the gcloud CLI option is offered for single-project connections). Run it once, signed in to the security project. The single module does everything:
- Deploys the central collector stack (Pub/Sub topic, push subscription, Cloud Run collector, secret) into the security project.
- Creates an organization-level Log Router sink (Admin Activity,
include_children, covering all child projects) pointing at the central topic, and grants the sink's writer identity permission to publish to it.
New projects created anywhere in the organization are covered automatically. No re-onboarding.
Save the block to main.tf, sign in, and run it. Terraform needs application-default credentials, and the module also runs a connectivity check with gcloud, so sign in both ways:
gcloud auth login
gcloud auth application-default login
terraform init && terraform applyStep 4: Return to ARMO
The organization appears as a single connection and flips to Connected on the collector's first heartbeat that reports real log traffic.
How an entire-organization connection appears
An Entire Organization connection is one entry in the accounts list. Alerts and incidents are attributed to the originating project, because each audit entry carries its project ID, so you can still see which project an incident belongs to. Connected reflects the central collector, not that every project has produced an event.
Editing the exclude list
Excluding or re-including a project is done in ARMO and takes effect on the next alert. Nothing is redeployed and the sink is never touched.
Connection Status
| Status | Meaning |
|---|---|
| Pending | The connection exists in ARMO; there is no evidence yet that logs reach the collector. |
| Connected | The collector has reported that at least one audit log traversed the pipe. |
| Disconnected | ARMO has received no heartbeat from the collector for 12 hours. The collector heartbeats every few minutes, so a quiet-but-healthy project does not disconnect. Check that the Cloud Run service is running. A collector that resumes reporting reconnects automatically. |
Permissions Reference
| Identity | Role | Granted on | Purpose |
|---|---|---|---|
| Log sink writer identity (created by GCP) | roles/pubsub.publisher | CDR topic | Publish routed logs to the topic. |
| Pub/Sub pusher service account | roles/run.invoker | Collector service | Authenticated push into the collector. Nothing else can invoke it. |
| Collector service account | roles/secretmanager.secretAccessor | The access-key secret only | Read its ARMO access key. |
| Collector service account | outbound HTTPS only | Download rules from and push alerts to ARMO. |
The collector reads only its own Pub/Sub topic. It never touches your workloads, data, or IAM.
After Onboarding
- New audit log events are evaluated continuously; matched detections appear under Runtime Incidents.
- Incidents include the triggering event, the identity involved, and the affected resource, with links to the relevant detection rule.
- Detection rules can be tuned, disabled, or extended under Policies → Threat Detection.
Removing the Integration
CDR runs a collector, a log sink, and a Pub/Sub pipeline inside your GCP. Removing the connection in ARMO does not delete them, because ARMO has no access to your environment. Removal is a two-step flow: run the teardown ARMO gives you, then remove the connection in ARMO.
Run the teardown firstThe teardown commands are generated from your stored connection details, so they are only available while the connection still exists in ARMO.
- In ARMO, go to Settings → Accounts → GCP and choose Remove on the connection. ARMO shows the teardown with two variants:
- gcloud — the universal path, and the one to use if you deployed with the
gcloudcommand. A sequence ofgcloud … deletecommands that, in order, deletes the log sink first so no new logs flow, waits a short drain window, then deletes the push subscription, the Cloud Run service, both service accounts, and the secret, and finally the dead-letter subscription and the topics. - Terraform — if you deployed with Terraform, run
terraform destroyin the module directory you applied from instead. It removes the same resources and keeps your Terraform state consistent.
- gcloud — the universal path, and the one to use if you deployed with the
- Run the teardown in Cloud Shell with the same access you used to onboard (organization-level for an entire-organization connection).
- Confirm removal in ARMO.
Troubleshooting
| Issue | Likely Cause | Suggested Fix |
|---|---|---|
| Deployment fails creating the sink | Missing Logs Configuration Writer at the project or organization | Grant roles/logging.configWriter at the right scope, or have an org admin run the deployment. |
| Deployment fails creating service accounts or IAM bindings | Missing Service Account Admin, or an organization policy constraint | Grant roles/iam.serviceAccountAdmin; review organization policy constraints on Cloud Run and service accounts. |
| Connection stays Pending after a successful deployment | No audit log has traversed the pipe yet | Perform any administrative action in the project (for example, view and save an IAM binding). Check the Cloud Run service logs and that the sink exists under Logging → Log Router. |
| Entire organization: a project never produces incidents | The project is on the exclude list | Review the exclude list on the connection in ARMO. |
| Connection shows Disconnected | Collector stopped, or the Cloud Run service was deleted | Redeploy the collector; the connection reconnects on the next heartbeat. |
Updated about 2 hours ago
