Manage protection policies
Policies decide which assets Elastio protects, how often, and which hunts run on them. This guide shows how to manage policies as code: preview which assets a policy would select, create it on a shared schedule, check its membership, run it on demand, and retire it safely.
Which policy endpoints to use
Section titled “Which policy endpoints to use”Policies are served in three versions. Use v3 (/gateway/shared-services/v3/policies) for new integrations. It covers AWS, Azure and IBM, and adds the per-policy violations selection and the r_rpo recovery RPO target on top of v2. The v1 and v2 policy endpoints still work, but v3 is a superset of both.
Policies are identified by name in the path, for example /v3/policies/{name}. URL-encode the name.
| Need | Endpoint family |
|---|---|
| Scheduled hunt or backup policies | /gateway/shared-services/v3/policies |
| Event-triggered policies | /gateway/shared-services/v3/event-policies |
| Shared cadences that several policies reference | /gateway/shared-services/v1/schedules |
| Which assets a policy selects | /gateway/shared-services/v2/policies/{name}/membership, /v2/policies/scope-preview, /v2/assets/{id}/policies |
| Routing of operational events and unprotected-asset findings | /gateway/shared-services/v3/system-policies |
List policies
Section titled “List policies”The optional platform filter takes AWS, Azure, IBM or GCP. The response wraps the policies in policies and includes a total_count.
curl "https://acme.app.elastio.com/gateway/shared-services/v3/policies?platform=AWS" \ -H "Authorization: Bearer $ELASTIO_TOKEN"import os, requests
BASE = "https://acme.app.elastio.com"HEADERS = {"Authorization": f"Bearer {os.environ['ELASTIO_TOKEN']}"}
resp = requests.get(f"{BASE}/gateway/shared-services/v3/policies", headers=HEADERS, params={"platform": "AWS"}, timeout=30)resp.raise_for_status()for p in resp.json()["policies"]: print(p["name"], p["status"], p["last_run_at"])$Base = "https://acme.app.elastio.com"$Headers = @{ Authorization = "Bearer $env:ELASTIO_TOKEN" }$result = Invoke-RestMethod -Uri "$Base/gateway/shared-services/v3/policies?platform=AWS" -Headers $Headers$result.policies | Format-Table name, platform, status, last_run_atExample response (trimmed):
{ "policies": [ { "name": "prod-s3-scan", "platform": "AWS", "kind": "custom", "status": "enabled", "paused_until": null, "schedule_id": "4c5d6e7f-8a9b-4c0d-9e1f-2a3b4c5d6e7f", "frequency": { "kind_tag": "daily", "monday": true, "tuesday": true, "wednesday": true, "thursday": true, "friday": true, "saturday": true, "sunday": true, "time": { "time": "02:00:00", "timezone": "Etc/UTC" } }, "selectors": [ { "criteria": [ { "kind_tag": "is_type", "asset_type": "s3" } ] } ], "mode": { "kind_tag": "scan_only", "s3": { "threat_hunt": false } }, "iscan": { "ransomware": true, "malware": true, "encryption_detection": false, "data_classification": false, "hunt": false, "pursuit": false }, "r_rpo": { "target_seconds": 86400, "severity": "high" }, "violations": [], "last_run_at": "2026-10-12T02:00:00Z", … } ], "total_count": 1}Preview a policy’s scope before you save it
Section titled “Preview a policy’s scope before you save it”/gateway/shared-services/v2/policies/scope-previewCompute the assets a draft policy definition would selectScope preview runs a draft definition against your current inventory and returns the asset IDs it would select. It saves nothing. AWS drafts send selectors and account_region_selectors in the same shape the policies API uses. Azure and IBM drafts send policy_yaml. The platform field is required. Results are paged with the limit (1–1000, default 100) and offset query parameters.
This draft selects every S3 bucket in one account and region, and skips anything tagged backup=skip. An exclude_tags criterion removes an asset if it matches any of the listed tags, and exclusions take precedence over the include criteria.
curl -X POST "https://acme.app.elastio.com/gateway/shared-services/v2/policies/scope-preview?limit=100" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "prod-s3-scan", "platform": "AWS", "account_region_selectors": [ { "account_id": "123456789012", "region": "us-east-1" } ], "selectors": [ { "criteria": [ { "kind_tag": "is_type", "asset_type": "s3" }, { "kind_tag": "exclude_tags", "tags": { "backup": "skip" } } ] } ] }'draft = { "name": "prod-s3-scan", "platform": "AWS", "account_region_selectors": [{"account_id": "123456789012", "region": "us-east-1"}], "selectors": [ {"criteria": [ {"kind_tag": "is_type", "asset_type": "s3"}, {"kind_tag": "exclude_tags", "tags": {"backup": "skip"}}, ]} ],}resp = requests.post( f"{BASE}/gateway/shared-services/v2/policies/scope-preview", headers=HEADERS, params={"limit": 100}, json=draft, timeout=60,)resp.raise_for_status()preview = resp.json()print(f"{preview['total_matched']} of {preview['candidate_assets']} candidate assets match")$draft = @{ name = "prod-s3-scan" platform = "AWS" account_region_selectors = @(@{ account_id = "123456789012"; region = "us-east-1" }) selectors = @(@{ criteria = @( @{ kind_tag = "is_type"; asset_type = "s3" }, @{ kind_tag = "exclude_tags"; tags = @{ backup = "skip" } } ) })} | ConvertTo-Json -Depth 10$preview = Invoke-RestMethod -Method Post -Uri "$Base/gateway/shared-services/v2/policies/scope-preview?limit=100" ` -Headers $Headers -ContentType "application/json" -Body $draft"$($preview.total_matched) of $($preview.candidate_assets) match"Example response:
{ "policy_name": "prod-s3-scan", "platform": "AWS", "candidate_assets": 212, "total_matched": 3, "asset_ids": [ "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d", "1b2c3d4e-5f6a-4b7c-9d8e-0f1a2b3c4d5e", "2c3d4e5f-6a7b-4c8d-8e9f-1a2b3c4d5e6f" ], "computed_at": "2026-10-12T10:30:00Z", "pagination": { "limit": 100, "offset": 0 }}Create a schedule and a policy that uses it
Section titled “Create a schedule and a policy that uses it”A policy’s cadence comes from one of two places: an inline frequency, or a schedule_id that points to a shared schedule. Sending both is rejected. A shared schedule is useful when several policies should run at the same time. Changing the schedule’s frequency changes the cadence of every policy that references it straight away.
1. Create the schedule
Section titled “1. Create the schedule”name (unique within the tenant, 1–255 characters) and frequency are required. frequency.kind_tag is one of every5_minutes, every15_minutes, every30_minutes, every_hour, every12_hours, daily, weekly or monthly. A daily frequency needs all seven weekday booleans. A weekly frequency needs day, and a monthly frequency needs day_of_month. Times use {"time": "HH:MM:SS", "timezone": "<IANA zone>"}.
curl -X POST "https://acme.app.elastio.com/gateway/shared-services/v1/schedules" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "nightly-0200-utc", "description": "Every night at 02:00 UTC", "frequency": { "kind_tag": "daily", "monday": true, "tuesday": true, "wednesday": true, "thursday": true, "friday": true, "saturday": true, "sunday": true, "time": { "time": "02:00:00", "timezone": "Etc/UTC" } } }'every_day = {d: True for d in ("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday")}resp = requests.post( f"{BASE}/gateway/shared-services/v1/schedules", headers=HEADERS, json={ "name": "nightly-0200-utc", "description": "Every night at 02:00 UTC", "frequency": {"kind_tag": "daily", **every_day, "time": {"time": "02:00:00", "timezone": "Etc/UTC"}}, }, timeout=30,)resp.raise_for_status()schedule_id = resp.json()["id"]$schedule = @{ name = "nightly-0200-utc" description = "Every night at 02:00 UTC" frequency = @{ kind_tag = "daily" monday = $true; tuesday = $true; wednesday = $true; thursday = $true friday = $true; saturday = $true; sunday = $true time = @{ time = "02:00:00"; timezone = "Etc/UTC" } }} | ConvertTo-Json -Depth 10$created = Invoke-RestMethod -Method Post -Uri "$Base/gateway/shared-services/v1/schedules" ` -Headers $Headers -ContentType "application/json" -Body $schedule$scheduleId = $created.idExample response (201 Created):
{ "id": "4c5d6e7f-8a9b-4c0d-9e1f-2a3b4c5d6e7f", "name": "nightly-0200-utc", "description": "Every night at 02:00 UTC", "frequency": { "kind_tag": "daily", "monday": true, "tuesday": true, "wednesday": true, "thursday": true, "friday": true, "saturday": true, "sunday": true, "time": { "time": "02:00:00", "timezone": "Etc/UTC" } }, "tenant_name": "acme", "created_at": "2026-10-12T10:35:00Z", "updated_at": "2026-10-12T10:35:00Z"}2. Create the policy
Section titled “2. Create the policy”For AWS, name and platform are required, and a usable policy also needs selectors and mode. This example creates a hunt-only policy (scan_only mode) for the S3 buckets previewed above, hunting for ransomware and malware on the shared schedule. It also sets a recovery RPO target: if the newest proven clean recovery point is older than 24 hours, Elastio raises a high severity finding.
mode.kind_tag is backup or scan_only. scan_only mode needs at least one family option bag: ec2_or_ebs, s3, efs or fsx_ontap. iscan needs all six booleans: ransomware, malware, encryption_detection, data_classification, hunt and pursuit.
curl -X POST "https://acme.app.elastio.com/gateway/shared-services/v3/policies" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "prod-s3-scan", "platform": "AWS", "description": "Nightly ransomware and malware hunt of production S3", "schedule_id": "4c5d6e7f-8a9b-4c0d-9e1f-2a3b4c5d6e7f", "account_region_selectors": [ { "account_id": "123456789012", "region": "us-east-1" } ], "selectors": [ { "criteria": [ { "kind_tag": "is_type", "asset_type": "s3" }, { "kind_tag": "exclude_tags", "tags": { "backup": "skip" } } ] } ], "mode": { "kind_tag": "scan_only", "s3": { "threat_hunt": false } }, "iscan": { "ransomware": true, "malware": true, "encryption_detection": false, "data_classification": false, "hunt": false, "pursuit": false }, "r_rpo": { "target_seconds": 86400, "severity": "high" } }'policy = { "name": "prod-s3-scan", "platform": "AWS", "description": "Nightly ransomware and malware hunt of production S3", "schedule_id": schedule_id, "account_region_selectors": draft["account_region_selectors"], "selectors": draft["selectors"], "mode": {"kind_tag": "scan_only", "s3": {"threat_hunt": False}}, "iscan": { "ransomware": True, "malware": True, "encryption_detection": False, "data_classification": False, "hunt": False, "pursuit": False, }, "r_rpo": {"target_seconds": 86400, "severity": "high"},}resp = requests.post(f"{BASE}/gateway/shared-services/v3/policies", headers=HEADERS, json=policy, timeout=60)resp.raise_for_status()created = resp.json()print(created["name"], created["status"])$policy = @{ name = "prod-s3-scan" platform = "AWS" description = "Nightly ransomware and malware hunt of production S3" schedule_id = $scheduleId account_region_selectors = @(@{ account_id = "123456789012"; region = "us-east-1" }) selectors = @(@{ criteria = @( @{ kind_tag = "is_type"; asset_type = "s3" }, @{ kind_tag = "exclude_tags"; tags = @{ backup = "skip" } } ) }) mode = @{ kind_tag = "scan_only"; s3 = @{ threat_hunt = $false } } iscan = @{ ransomware = $true; malware = $true; encryption_detection = $false; data_classification = $false; hunt = $false; pursuit = $false } r_rpo = @{ target_seconds = 86400; severity = "high" }} | ConvertTo-Json -Depth 10Invoke-RestMethod -Method Post -Uri "$Base/gateway/shared-services/v3/policies" ` -Headers $Headers -ContentType "application/json" -Body $policyThe response (201 Created) is the stored policy, in the same shape as a row from the list call. Because the policy references a schedule, frequency is filled in from that schedule. violations, alert_ids, hunt_rule_ids and ccl_severity_overrides are always present and come back as [] when empty.
Update a policy
Section titled “Update a policy”PUT /gateway/shared-services/v3/policies/{name} takes the same body as create, without name. platform is required and can’t be changed. A v3 update fully replaces violations and r_rpo: if you leave them out, they’re cleared. Read the policy first, change the fields you need, and send the whole definition back.
Check membership and run on demand
Section titled “Check membership and run on demand”See which assets a saved policy covers
Section titled “See which assets a saved policy covers”/gateway/shared-services/v2/policies/{name}/membershipCompute the assets currently selected by a stored policyBy default (source=computed), the policy’s selectors are evaluated live against the current inventory. source=stored reads the membership saved by the last engine pass instead, and returns 503 where that storage isn’t enabled. For the reverse lookup, which policies cover one asset, use GET /gateway/shared-services/v2/assets/{id}/policies.
curl "https://acme.app.elastio.com/gateway/shared-services/v2/policies/prod-s3-scan/membership?limit=1000" \ -H "Authorization: Bearer $ELASTIO_TOKEN"from urllib.parse import quote
name = "prod-s3-scan"resp = requests.get( f"{BASE}/gateway/shared-services/v2/policies/{quote(name, safe='')}/membership", headers=HEADERS, params={"limit": 1000}, timeout=60,)resp.raise_for_status()membership = resp.json()print(membership["total_matched"], "assets covered")$name = [uri]::EscapeDataString("prod-s3-scan")$m = Invoke-RestMethod -Uri "$Base/gateway/shared-services/v2/policies/$name/membership?limit=1000" -Headers $Headers"$($m.total_matched) assets covered"The response has the same shape as the scope preview: policy_name, platform, candidate_assets, total_matched, asset_ids, computed_at and pagination.
Run a policy now
Section titled “Run a policy now”This starts an immediate run of a saved policy. It takes no body and doesn’t change the policy. It returns 202 Accepted with the parent job_id. Per-connector child jobs carry this ID as their parent, so you can follow the whole run from it (see Track jobs). Run is AWS only. Azure and IBM policies are delivered as cluster YAML and have no per-connector job.
curl -X POST "https://acme.app.elastio.com/gateway/shared-services/v3/policies/prod-s3-scan/run" \ -H "Authorization: Bearer $ELASTIO_TOKEN"resp = requests.post(f"{BASE}/gateway/shared-services/v3/policies/{quote(name, safe='')}/run", headers=HEADERS, timeout=30)resp.raise_for_status()print("parent job", resp.json()["job_id"])$run = Invoke-RestMethod -Method Post -Uri "$Base/gateway/shared-services/v3/policies/$name/run" -Headers $Headers$run.job_idExample response (202 Accepted):
{ "job_id": "9f8e7d6c-5b4a-4392-8170-6f5e4d3c2b1a" }Pause and resume
Section titled “Pause and resume”POST /gateway/shared-services/v3/policies/{name}/pause requires a body. {"paused_until": "2026-10-20T00:00:00Z"} pauses the policy until that time (status becomes paused_until). An empty object {} disables it indefinitely (status becomes disabled). POST …/resume takes no body and turns the policy back on. Both return 204.
Retire a policy safely
Section titled “Retire a policy safely”/gateway/shared-services/v3/policies/{name}/soft-deleteSoft-delete a scheduled policy by name (Admin only)Prefer soft delete. It saves a snapshot of the policy, removes it from the live list and stops it from running, but you can still restore it. The body is optional, {"reason": "…"} (up to 1024 characters). The response is the deletion record.
curl -X POST "https://acme.app.elastio.com/gateway/shared-services/v3/policies/prod-s3-scan/soft-delete" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "reason": "Replaced by prod-s3-scan-v2" }'resp = requests.post( f"{BASE}/gateway/shared-services/v3/policies/{quote(name, safe='')}/soft-delete", headers=HEADERS, json={"reason": "Replaced by prod-s3-scan-v2"}, timeout=30,)resp.raise_for_status()deletion = resp.json()print("deletion record", deletion["id"])$deletion = Invoke-RestMethod -Method Post -Uri "$Base/gateway/shared-services/v3/policies/$name/soft-delete" ` -Headers $Headers -ContentType "application/json" -Body (@{ reason = "Replaced by prod-s3-scan-v2" } | ConvertTo-Json)$deletion.idExample response (trimmed):
{ "id": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e", "kind": "scheduled", "platform": "AWS", "last_known_name": "prod-s3-scan", "last_known_id": "c2d3e4f5-a6b7-4c8d-9e0f-1a2b3c4d5e6f", "prior_state": "enabled", "delete_reason": "Replaced by prod-s3-scan-v2", "deleted_at": "2026-10-12T11:00:00Z", "deleted_by": "admin@example.com", "restored_at": null, "hard_deleted_at": null, "alert_ids": [], "prior_snapshot": { … }, …}To find soft-deleted policies, call GET /gateway/shared-services/v3/policies/deleted. Restore one with POST /gateway/shared-services/v3/policies/deleted/{id}/restore, or delete it permanently with DELETE /gateway/shared-services/v3/policies/deleted/{id}.
Route system events with system policies
Section titled “Route system events with system policies”System policies control alerting that isn’t tied to one asset policy. A system_events policy covers operational events: the kinds listed in event_kinds, or every kind if all_event_kinds is true. The unprotected_assets policy covers findings on assets that no enabled protection policy covers. Seeded policies exist for every tenant and can’t be deleted. A tenant that hasn’t moved to System Policies yet gets an empty list.
- List the tenant’s system policies with
GET /gateway/shared-services/v3/system-policiesand note theidof the one you want. - List the available event kinds with
GET /gateway/shared-services/v3/system-events/catalog. Kinds withavailable: falsearen’t emitted yet. - Update the policy. Fields you leave out keep their stored values. If you send
alert_ids, it replaces the attached alerts and must contain at least one.
curl -X PUT "https://acme.app.elastio.com/gateway/shared-services/v3/system-policies/d3e4f5a6-b7c8-4d9e-8f0a-1b2c3d4e5f6a" \ -H "Authorization: Bearer $ELASTIO_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "status": "enabled", "all_event_kinds": true, "alert_ids": [ "e4f5a6b7-c8d9-4e0f-9a1b-2c3d4e5f6a7b" ] }'policy_id = "d3e4f5a6-b7c8-4d9e-8f0a-1b2c3d4e5f6a"resp = requests.put( f"{BASE}/gateway/shared-services/v3/system-policies/{policy_id}", headers=HEADERS, json={"status": "enabled", "all_event_kinds": True, "alert_ids": ["e4f5a6b7-c8d9-4e0f-9a1b-2c3d4e5f6a7b"]}, timeout=30,)resp.raise_for_status()print(resp.json()["name"], resp.json()["alert_ids"])$policyId = "d3e4f5a6-b7c8-4d9e-8f0a-1b2c3d4e5f6a"$body = @{ status = "enabled"; all_event_kinds = $true; alert_ids = @("e4f5a6b7-c8d9-4e0f-9a1b-2c3d4e5f6a7b") } | ConvertTo-JsonInvoke-RestMethod -Method Put -Uri "$Base/gateway/shared-services/v3/system-policies/$policyId" ` -Headers $Headers -ContentType "application/json" -Body $bodyExample response (trimmed):
{ "id": "d3e4f5a6-b7c8-4d9e-8f0a-1b2c3d4e5f6a", "name": "…", "description": "…", "type": "system_events", "status": "enabled", "is_seeded": true, "all_event_kinds": true, "event_kinds": [], "event_severities": [], "scope": null, "alert_ids": [ "e4f5a6b7-c8d9-4e0f-9a1b-2c3d4e5f6a7b" ], "created_at": "2026-01-15T09:00:00Z", "updated_at": "2026-10-12T11:10:00Z"}You can also limit a system policy to certain accounts or tags with scope. Set scope to null to apply it tenant-wide. To change the severity of individual event kinds, send event_severities as { "event_kind", "severity_override" } pairs. The API has no endpoint for creating new system policies.
All endpoints
Section titled “All endpoints”Policies
36 operations in the reference →- GET
/gateway/shared-services/v1/policiesList tenant policies - POST
/gateway/shared-services/v1/policiesCreate policy (Admin only) - GET
/gateway/shared-services/v1/policies/{name}Get policy by name - PUT
/gateway/shared-services/v1/policies/{name}Update policy by name (Admin only) - DELETE
/gateway/shared-services/v1/policies/{name}Delete policy by name (Admin only) - POST
/gateway/shared-services/v1/policies/{name}/pausePause policy (Admin only) - POST
/gateway/shared-services/v1/policies/{name}/resumeResume policy (Admin only) - GET
/gateway/shared-services/v2/policiesList tenant policies v2 - POST
/gateway/shared-services/v2/policiesCreate policy v2 (Admin only) - GET
/gateway/shared-services/v2/policies/{name}Get policy by name v2 - PUT
/gateway/shared-services/v2/policies/{name}Update policy v2 (Admin only) - DELETE
/gateway/shared-services/v2/policies/{name}Delete policy by name v2 (Admin only) - POST
/gateway/shared-services/v2/policies/{name}/pausePause policy v2 (Admin only) - POST
/gateway/shared-services/v2/policies/{name}/resumeResume policy v2 (Admin only) - POST
/gateway/shared-services/v2/policies:validateValidate a v2 Azure/IBM policy_yaml (Admin only) - GET
/gateway/shared-services/v3/event-policiesList event-based policies - POST
/gateway/shared-services/v3/event-policiesCreate an event-based policy - GET
/gateway/shared-services/v3/event-policies/{name}Get an event-based policy - PUT
/gateway/shared-services/v3/event-policies/{name}Update an event-based policy - DELETE
/gateway/shared-services/v3/event-policies/{name}Delete an event-based policy (Admin only) - POST
/gateway/shared-services/v3/event-policies/{name}/soft-deleteSoft-delete an event-based policy by name (Admin only) - GET
/gateway/shared-services/v3/policiesList tenant policies v3 - POST
/gateway/shared-services/v3/policiesCreate policy v3 (Admin only) - GET
/gateway/shared-services/v3/policies/{name}Get policy by name v3 - PUT
/gateway/shared-services/v3/policies/{name}Update policy v3 (Admin only) - DELETE
/gateway/shared-services/v3/policies/{name}Delete policy by name v3 (Admin only) - POST
/gateway/shared-services/v3/policies/{name}/pausePause policy v3 (Admin only) - POST
/gateway/shared-services/v3/policies/{name}/resumeResume policy v3 (Admin only) - POST
/gateway/shared-services/v3/policies/{name}/runRun policy on demand (Admin only) - POST
/gateway/shared-services/v3/policies/{name}/soft-deleteSoft-delete a scheduled policy by name (Admin only) - GET
/gateway/shared-services/v3/policies/deletedList active policy deletions - GET
/gateway/shared-services/v3/policies/deleted/{id}Read one policy deletion / tombstone - DELETE
/gateway/shared-services/v3/policies/deleted/{id}Permanently delete a soft-deleted policy (Admin only) - POST
/gateway/shared-services/v3/policies/deleted/{id}/restoreRestore a soft-deleted policy (Admin only) - GET
/gateway/shared-services/v3/policies/pursuit-playbooksList built-in pursuit playbooks - POST
/gateway/shared-services/v3/policies:validateValidate a v3 Azure/IBM policy_yaml (Admin only)
Policy Schedules
5 operations in the reference →- GET
/gateway/shared-services/v1/schedulesList tenant schedules - POST
/gateway/shared-services/v1/schedulesCreate schedule (Admin only) - GET
/gateway/shared-services/v1/schedules/{id}Get schedule by id - PATCH
/gateway/shared-services/v1/schedules/{id}Update schedule (Admin only) - DELETE
/gateway/shared-services/v1/schedules/{id}Delete schedule (Admin only)
Policy Membership
5 operations in the reference →- GET
/gateway/shared-services/v2/assets/{id}/policiesList the policies whose membership covers an asset - GET
/gateway/shared-services/v2/azure/subscription-regionsLive Azure (subscription, region) pairs - GET
/gateway/shared-services/v2/policies/{name}/membershipCompute the assets currently selected by a stored policy - GET
/gateway/shared-services/v2/policies/{name}/subscription-regionsAzure (subscription, region) pairs a stored policy covers - POST
/gateway/shared-services/v2/policies/scope-previewCompute the assets a draft policy definition would select