Skip to content
Merged
Changes from 3 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
18 changes: 13 additions & 5 deletions skills/functions-falcon-api/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,16 +237,18 @@ def run_logscale_query(ngsiem, query_string, start, end, logger, max_wait=40):
``start`` / ``end`` accept Humio relative strings ("24h", "7d", "30d",
"now") or epoch-millisecond integers.
"""
body = {"queryString": query_string, "start": start, "end": end, "isLive": False}
started = ngsiem.start_search(repository=REPO, body=body)
payload = {"queryString": query_string, "start": start, "end": end, "isLive": False}
# Must be search=, not body= — see the keyword gotcha below.
started = ngsiem.start_search(repository=REPO, search=payload)

if not isinstance(started, dict) or started.get("status_code", 500) >= 300:
logger.error(f"start_search failed: {started}")
return None

job_id = (started.get("body") or {}).get("id")
# start_search returns "resources"; get_search_status returns "body".
job_id = (started.get("resources") or {}).get("id")
if not job_id:
logger.error(f"start_search returned no job id: {started.get('body')}")
logger.error(f"start_search returned no job id: {started}")
return None

# Poll until done
Expand Down Expand Up @@ -285,6 +287,12 @@ if __name__ == '__main__':
func.run()
```

### The `search=` Keyword Gotcha

**CRITICAL:** Pass the query payload as `search=`, not `body=`. FalconPy's guard reads only `kwargs.get("search")`, so `body=` returns a local error without issuing a request. The docstring lists `body` as accepted, but the guard ignores it ([falconpy#1491](https://github.com/CrowdStrike/falconpy/issues/1491)).

Response keys are asymmetric: `start_search` renames its payload to `resources` (read `started["resources"]["id"]`), while `get_search_status` does not (read `status["body"]`).

### The "search-all" Repository Gotcha

**CRITICAL:** Always pass `repository="search-all"` when querying from Foundry functions. Passing a specific repository name (e.g., `"fusion"`, `"main"`) causes **403 Forbidden** errors at runtime (`"scope not permitted"`), even if the repository exists and the app has `humio-auth-proxy` scopes granted.
Expand Down Expand Up @@ -391,7 +399,7 @@ Each row maps a FalconPy method actually called in a sample function to the scop
| `IdentityProtection` | `graphql`, `query_sensors`, `get_sensor_details` | `identity-graphql:write`, `identity-entities:read` | foundry-sample-idp-notifications |
| `IdentityProtection` | `query_policy_rules`, `get_policy_rules`, `delete_policy_rules` | `identity-policy-rules:read`, `identity-policy-rules:write` | foundry-sample-servicenow-idp |
| `NGSIEM` | `upload_file` | `humio-auth-proxy:write` | foundry-sample-ngsiem-importer |
| `NGSIEM` | `start_search`, `get_search_status` | `humio-auth-proxy:read` | Verified against FalconPy source; see LogScale Queries section |
| `NGSIEM` | `start_search`, `get_search_status` | `humio-auth-proxy:read` | Verified against a live CID (200 + results); see LogScale Queries section |
| `FoundryLogScale` | `ingest_data` | `app-logs:read`, `app-logs:write` | foundry-sample-logscale |
| `FirewallManagement` | `create_rule_group`, `query_events`, `get_events` | `firewall-management:read`, `firewall-management:write` | foundry-sample-category-blocking |
| `HostGroup` | `query_host_groups`, `get_host_groups` | `host-group:read`, `host-group:write` | foundry-sample-category-blocking |
Expand Down