diff --git a/product/admin/expressions-examples.mdx b/product/admin/expressions-examples.mdx
index 6f51989a..0170d8a2 100644
--- a/product/admin/expressions-examples.mdx
+++ b/product/admin/expressions-examples.mdx
@@ -616,5 +616,6 @@ The `appOwners` variable is always available in policy step expressions and neve
- **[CEL expressions reference](/product/admin/expressions-reference)** - Complete reference for all available objects, functions, and time functions
- **[Workflow expressions](/product/admin/expressions-workflows)** - Pass data between automation steps using the ctx object
- **[Troubleshooting expressions](/product/admin/expressions-troubleshooting)** - Debug common errors and understand failure modes
+- **[Use external insights in CEL policy conditions](/product/admin/external-insights#use-external-insights-in-cel-policy-conditions)** - Reference security findings and risk scores from Wiz and CrowdStrike in access decisions
diff --git a/product/admin/expressions-reference.mdx b/product/admin/expressions-reference.mdx
index 0bb6af8b..85257e06 100644
--- a/product/admin/expressions-reference.mdx
+++ b/product/admin/expressions-reference.mdx
@@ -389,6 +389,35 @@ time.format(now(), TimeFormat.DATETIME, "Europe/London")
The `now()` function returns the same value throughout a single expression evaluation. All timestamps are stored in UTC internally; timezone parameters only affect parsing and formatting.
+### External insights functions
+
+These functions are available in policy conditions when [external insights](/product/admin/external-insights) are configured. They let you reference security findings and risk scores from connected tools directly in access decisions.
+
+#### Issue insights
+
+Issue insights are discrete security findings (for example, critical CVEs or misconfigurations) synced from Wiz Insights.
+
+| Function | Accepts | Returns | Availability |
+|:----------|:---------|:---------|:--------------|
+| `c1.app_user.v1.HasSecurityInsight(account)` | account | `bool` | Policy conditions |
+| `c1.app_user.v1.GetSecurityInsights(account, source)` | account, source name | `list` | Policy conditions |
+| `c1.app_user.v1.HasSecurityInsightWithSeverity(account, source, severity)` | account, source name, severity | `bool` | Policy conditions |
+
+Severity values: `"CRITICAL"`, `"HIGH"`, `"MEDIUM"`, `"LOW"`, `"INFORMATIONAL"`. The `HasSecurityInsightWithSeverity` comparison is case-insensitive; direct field comparisons are not.
+
+#### Risk scores
+
+Risk scores are normalized values (0–100, higher = more risk) synced from CrowdStrike.
+
+| Function | Accepts | Returns | Availability |
+|:----------|:---------|:---------|:--------------|
+| `c1.app_user.v1.HasRiskScore(account)` | account | `bool` | Policy conditions |
+| `c1.app_user.v1.GetRiskScore(account, source)` | account, source name | `c1.risk_score.v1` | Policy conditions |
+
+The source name must exactly match the connector app's display name in your tenant (for example, `"Wiz Insights"` or `"CrowdStrike"`). The match is case-sensitive.
+
+For full examples and best practices, see [Use external insights in CEL policy conditions](/product/admin/external-insights#use-external-insights-in-cel-policy-conditions).
+
## Objects
### Subject object
diff --git a/product/admin/external-insights.mdx b/product/admin/external-insights.mdx
index 0263aac2..616ab6af 100644
--- a/product/admin/external-insights.mdx
+++ b/product/admin/external-insights.mdx
@@ -59,14 +59,130 @@ The task log includes an **Insights** column. Hovering over the insights indicat
Approvers can see an identity's current risk score and risk factors in a request task before submitting their decision.
+## Use external insights in CEL policy conditions
+
+Beyond surfacing risk data in the UI, you can reference external insights directly in [CEL policy conditions](/product/admin/expressions-reference#external-insights-functions) to automate access decisions based on a user's security posture.
+
+External insights expose two data types through CEL, each from a different connector:
+
+| Data type | Connector | CEL path | Description |
+|-----------|-----------|----------|-------------|
+| Issue insights | Wiz Insights | `account.security_insights` | Discrete security findings such as critical CVEs, misconfigurations, and exposed secrets |
+| Risk scores | CrowdStrike | `account.risk_score` / `account.risk_scores` | Normalized identity risk scores (0–100, higher = more risk) |
+
+
+All CEL functions that accept a source app name use the **display name** of the connector app in your tenant. The defaults are `"Wiz Insights"` and `"CrowdStrike"`. If you've renamed a connector app, use the renamed name instead. The match is **exact and case-sensitive**.
+
+
+### Issue insights (Wiz)
+
+Issue insights represent discrete security findings synced from Wiz. Each insight has three fields: `source` (the connector app name), `value` (a description like `"3 Critical CVEs"`), and `severity` (`"CRITICAL"`, `"HIGH"`, `"MEDIUM"`, `"LOW"`, or `"INFORMATIONAL"`).
+
+**Helper functions**
+
+| Function | Returns | Description |
+|----------|---------|-------------|
+| `c1.app_user.v1.HasSecurityInsight(account)` | `bool` | `true` if the account has any issue insights from any source |
+| `c1.app_user.v1.GetSecurityInsights(account, source)` | `list` | All issue insights from the named source |
+| `c1.app_user.v1.HasSecurityInsightWithSeverity(account, source, severity)` | `bool` | `true` if the account has at least one issue from the named source at the given severity (case-insensitive) |
+
+**Examples**
+
+Deny access when critical Wiz findings exist:
+
+```go
+c1.app_user.v1.HasSecurityInsightWithSeverity(account, "Wiz Insights", "CRITICAL")
+```
+
+Block privileged access on HIGH or CRITICAL Wiz issues:
+
+```go
+c1.app_user.v1.HasSecurityInsightWithSeverity(account, "Wiz Insights", "CRITICAL")
+ || c1.app_user.v1.HasSecurityInsightWithSeverity(account, "Wiz Insights", "HIGH")
+```
+
+Auto-approve when no Wiz issues exist:
+
+```go
+c1.app_user.v1.GetSecurityInsights(account, "Wiz Insights").size() == 0
+```
+
+### Risk scores (CrowdStrike)
+
+Risk scores are normalized values from 0 (no risk) to 100 (highest risk). Each score has two fields: `source` (the connector app name) and `normalized_score` (the integer score).
+
+You can access scores in two ways:
+- **Map** — `account.risk_score` is keyed by source display name and returns the score as an integer.
+- **List** — `account.risk_scores` returns a list of score objects, useful for cross-source queries.
+
+**Helper functions**
+
+| Function | Returns | Description |
+|----------|---------|-------------|
+| `c1.app_user.v1.HasRiskScore(account)` | `bool` | `true` if the account has risk scores from any source |
+| `c1.app_user.v1.GetRiskScore(account, source)` | `c1.risk_score.v1` | The risk score object for the named source (returns `normalized_score` of `0` if missing) |
+
+**Examples**
+
+Block access when the CrowdStrike score exceeds a threshold:
+
+```go
+c1.app_user.v1.GetRiskScore(account, "CrowdStrike").normalized_score > 70
+```
+
+Require extra approval for elevated risk:
+
+```go
+c1.app_user.v1.HasRiskScore(account)
+ && c1.app_user.v1.GetRiskScore(account, "CrowdStrike").normalized_score > 50
+```
+
+Auto-approve when CrowdStrike reports low risk:
+
+```go
+"CrowdStrike" in account.risk_score && account.risk_score["CrowdStrike"] <= 20
+```
+
+Deny access if no CrowdStrike score exists (device may be unmanaged):
+
+```go
+!("CrowdStrike" in account.risk_score)
+```
+
+### Combining sources
+
+You can combine Wiz issue insights and CrowdStrike risk scores in a single condition.
+
+Escalate when CrowdStrike risk is elevated and Wiz has critical findings:
+
+```go
+("CrowdStrike" in account.risk_score && account.risk_score["CrowdStrike"] > 50)
+ && c1.app_user.v1.HasSecurityInsightWithSeverity(account, "Wiz Insights", "CRITICAL")
+```
+
+Require a clean posture from both sources for sensitive access:
+
+```go
+("CrowdStrike" in account.risk_score && account.risk_score["CrowdStrike"] <= 30)
+ && !c1.app_user.v1.HasSecurityInsightWithSeverity(account, "Wiz Insights", "HIGH")
+ && !c1.app_user.v1.HasSecurityInsightWithSeverity(account, "Wiz Insights", "CRITICAL")
+```
+
+### CEL best practices for external insights
+
+- **Put cheap checks first.** Place simple attribute comparisons (like `subject.department`) before insight or risk-score lookups, which trigger lazy data loads.
+- **Guard with existence checks.** Use `HasRiskScore` or `"CrowdStrike" in account.risk_score` before reading scores to avoid zero-default edge cases. Use `HasSecurityInsight` before iterating insights.
+- **Use the correct source name.** The source name must exactly match the app display name in your tenant.
+- **Prefer helper functions for severity checks.** `HasSecurityInsightWithSeverity` compares severity case-insensitively, but direct field comparisons like `i.severity == "CRITICAL"` are case-sensitive.
+
## Supported external insights sources
- Ingest Falcon identity risk scores into ConductorOne.
+ Ingest Falcon identity risk scores into C1.
- Ingest Wiz identity risk scores into ConductorOne.
+ Ingest Wiz identity risk scores into C1.