﻿---
title: Cross-project search and detection rules
description: With cross-project search, detection rules query the origin and any linked projects, and create alerts on the origin project.
url: https://www.elastic.co/elastic/docs-builder/docs/4116/solutions/security/detect-and-alert/cross-project-search-detection-rules
products:
  - Elastic Security
applies_to:
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Unavailable
---

# Cross-project search and detection rules
If your data spans ECH, ECE, ECK, or self-managed clusters rather than linked Serverless projects, refer to [Cross-cluster search and detection rules](https://www.elastic.co/elastic/docs-builder/docs/4116/solutions/security/detect-and-alert/cross-cluster-search-detection-rules) instead.

## Cross-project search scope for rules

When [cross-project search](https://www.elastic.co/elastic/docs-builder/docs/4116/explore-analyze/cross-project-search) is enabled and you have [linked projects](https://www.elastic.co/elastic/docs-builder/docs/4116/deploy-manage/cross-project-search-config/cps-config-link-and-manage), rules query data across linked projects based on the **space-level cross-project search scope**.

### Which projects rules query by default

The [CPS scope selector](/elastic/docs-builder/docs/4116/explore-analyze/cross-project-search/cross-project-search-manage-scope#cps-in-kibana) in the header is read-only when you create or edit a rule. To change that default, update the [cross-project search scope configured for the space](/elastic/docs-builder/docs/4116/deploy-manage/cross-project-search-config/cps-config-access-and-scope#cps-default-search-scope).
To link projects and configure that default, refer to [Cross-project search](https://www.elastic.co/elastic/docs-builder/docs/4116/explore-analyze/cross-project-search) and [Manage access and scope for cross-project search](https://www.elastic.co/elastic/docs-builder/docs/4116/deploy-manage/cross-project-search-config/cps-config-access-and-scope).

### Which rule types can override the default scope

These rule types can override the space-level scope:
- **ES|QL rules:** Add [`SET project_routing`](https://www.elastic.co/elastic/docs-builder/docs/4116/explore-analyze/cross-project-search/cross-project-search-project-routing) at the start of the rule query.
- **Rules that use index patterns:** Use [qualified index expressions](/elastic/docs-builder/docs/4116/explore-analyze/cross-project-search/cross-project-search-search#search-expressions) in the index pattern to target specific projects.
- **Machine learning rules:** These rules alert on anomaly detection job results, so the job's scope determines what the rule can detect. Set [`project_routing`](/elastic/docs-builder/docs/4116/explore-analyze/machine-learning/anomaly-detection/ml-ad-run-jobs#ml-ad-cps-scope) on the job's datafeed.


### Where alerts are stored

The rule writes every alert it generates to the origin project, no matter which project the matching data came from. The origin project's **Alerts** page shows those alerts. It doesn't show alerts generated by rules defined in other projects.

## API keys and linked-project access

Within the rule's [cross-project search scope](#cps-scope-for-rules), it can search only the linked projects the user who last saved it can access. For how keys are created, how role changes apply, and how to update a key, refer to [Rules and Elastic Cloud API keys in Serverless](https://www.elastic.co/elastic/docs-builder/docs/4116/explore-analyze/alerting/alerts/rules-and-elastic-cloud-api-keys).

### When a rule searches the origin project only

If you create or update a rule through the API with an Elasticsearch API key, the rule keeps that credential and searches the origin project only:
- If the origin project has no matching indices, the rule doesn't run and its last-run status shows a warning.
- If those patterns exist on the origin, the rule still runs and reports success. The last-run status doesn't indicate that linked projects were skipped.

Plan for this when you migrate rules from another environment or create rules through automation. Rules still running on an Elasticsearch API key are tagged **Missing Elastic Cloud API Key** on the **Detection rules (SIEM)** page.

## How the alert limit applies across linked projects

The **Max alerts per run** [advanced setting](/elastic/docs-builder/docs/4116/solutions/security/detect-and-alert/common-rule-settings#rule-ui-advanced-params) limits the number of alerts a rule creates in a single execution. Under cross-project search, that limit covers the combined results from every project the rule queries in that run, rather than each project separately. By default, the rule queries the origin project and all linked projects in the space-level scope. The default limit is 100.
A rule that stayed under the limit on a single project can reach the limit after you link projects, which leaves matching events without alerts. Review the limit for rules that run across a broad scope. To search fewer projects instead of raising the limit, update the [space-level cross-project search scope](/elastic/docs-builder/docs/4116/deploy-manage/cross-project-search-config/cps-config-access-and-scope#cps-default-search-scope), add a query-level override, or change the anomaly detection job's datafeed scope. For which options apply to each rule type, refer to [which rule types can override the default](#cps-rules-query-overrides).

## Cross-project search context in alerts and the event log

When a detection rule runs with cross-project search enabled, the scope in effect at execution time is recorded on generated alerts and in rule execution events. During investigations, use the scope and linked project fields on the alert or in the event log to confirm which linked projects were in scope when an alert was created.

### When scope fields appear

Scope fields are written at rule execution time, not added to existing documents later. You need [linked projects](https://www.elastic.co/elastic/docs-builder/docs/4116/deploy-manage/cross-project-search-config/cps-config-link-and-manage), a [configured space-level cross-project search scope](https://www.elastic.co/elastic/docs-builder/docs/4116/deploy-manage/cross-project-search-config/cps-config-access-and-scope), and at least one enabled detection rule that has run successfully with cross-project search enabled.
On **alert documents**, `kibana.cps_scope.expression` and `kibana.cps_scope.linked_projects` are present only when that run generated an alert. Alerts created before cross-project search was enabled are not updated retroactively.
On **event log entries**, `kibana.cps_scope_expression` and `kibana.cps_scope_linked_projects` are recorded for every cross-project search-scoped execution, including runs that created no alerts.

### Alert documents

When a detection rule runs with cross-project search enabled, each generated alert can include:

| Field                              | Description                                                                                            |
|------------------------------------|--------------------------------------------------------------------------------------------------------|
| `kibana.cps_scope.expression`      | The cross-project search scope that was in effect when the rule generated the alert.                   |
| `kibana.cps_scope.linked_projects` | The linked projects that were in scope. Each entry includes `id`, `alias`, `type`, and `organization`. |

For the full list of alert fields, refer to the [alert schema](https://www.elastic.co/elastic/docs-builder/docs/4116/reference/security/fields-and-object-schemas/alert-schema).

### Event log

Rule execution events in the [event log index](https://www.elastic.co/elastic/docs-builder/docs/4116/explore-analyze/alerting/alerts/event-log-index) record the same scope and linked project information:

| Field                              | Description                                                                                            |
|------------------------------------|--------------------------------------------------------------------------------------------------------|
| `kibana.cps_scope_expression`      | The cross-project search scope that was in effect during the rule execution.                           |
| `kibana.cps_scope_linked_projects` | The linked projects that were in scope. Each entry includes `id`, `alias`, `type`, and `organization`. |

To find rule executions that ran with a particular scope, run a search against the event log in [Dev Tools](https://www.elastic.co/elastic/docs-builder/docs/4116/explore-analyze/query-filter/tools/console) or your own API client. The following example returns recent detection rule execution events that include cross-project search scope fields:
```txt
GET .kibana-event-log-*/_search
{
  "size": 5,  
  "query": {
    "match": { "kibana.cps_scope_expression": "_alias:*" }  
  },
  "_source": [  
    "event.action",
    "message",
    "kibana.cps_scope_expression",
    "kibana.cps_scope_linked_projects",
    "kibana.space_ids"
  ]
}
```

This request searches the event log indices (`.kibana-event-log-*`) for documents that have a `kibana.cps_scope_expression` value. It limits the response to five events and returns only the fields listed in `_source`, including the cross-project search scope, linked projects, and space ID for each execution. The event log is a system index, so by default only users with a `superuser` role can run this search. For more example queries and details on required privileges, refer to the [event log index](https://www.elastic.co/elastic/docs-builder/docs/4116/explore-analyze/alerting/alerts/event-log-index).