From securin-platform
Use this skill when the user asks to "find assets where...", "list my assets matching...", "how many assets...", "break down assets by...", "aggregate assets by type/criticality/workspace/cloud provider", "show asset distribution", "search my asset inventory", or any ad-hoc asset search / filter / aggregation against the Securin Platform. Requires the Securin Platform MCP server.
How this skill is triggered — by the user, by Claude, or both
Slash command
/securin-platform:securin-asset-triageThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Ad-hoc asset search, filtering, and aggregation. Translate natural-language questions about the user's asset inventory ("show me exposed-to-internet prod assets with critical exposures") into the correct Securin MCP `search*Data` / `aggregate*Data` call, with proper account scoping and deep links back to the platform.
references/_shared/account-preflight.mdreferences/_shared/brand.mdreferences/_shared/composite-fields.mdreferences/_shared/composite-vs-source.mdreferences/_shared/deep-links.mdreferences/_shared/fql-grammar.mdreferences/_shared/groupby-allowlist.mdreferences/_shared/securin_logos/README.mdreferences/_shared/securin_logos/Securin_logo_purple.pngreferences/_shared/securin_logos/Securin_logo_purple.svgreferences/_shared/securin_logos/Securin_logo_rounded.pngreferences/_shared/securin_logos/Securin_logo_rounded.svgreferences/_shared/securin_logos/Securin_logo_white.pngreferences/_shared/securin_logos/Securin_logo_white.svgreferences/_shared/sorting-rules.mdreferences/_shared/source-fields.mdreferences/asset-fields.mdAd-hoc asset search, filtering, and aggregation. Translate natural-language questions about the user's asset inventory ("show me exposed-to-internet prod assets with critical exposures") into the correct Securin MCP search*Data / aggregate*Data call, with proper account scoping and deep links back to the platform.
prod-cloud workspace"See _shared/account-preflight.md. Resolve the account-id(s), validate access, and hold them for the rest of the turn. If the question implies a workspace subset ("prod", "EU BU"), also resolve workspace-ids via getEffectiveAccessWorkspaces.
Before using this skill, read every file in the references folder, including the shared references/_shared/ docs. Prefer the cached field catalogs (source-fields.md for source mode, composite-fields.md for composite mode) over calling getApiFields — only fall back to the live tool when an entity or field is missing from the cache.
See _shared/composite-vs-source.md. Call getAccountSettings(account-id, settings: ["COMPOSITE_ASSET_LIST_VIEW"]) — "true" means composite, anything else means source. This determines:
assetQuery (composite) or searchAssetData (source).compositeAsset.* vs asset.*.Cache the flag for the turn. Picking the wrong model returns empty results with no error.
Composite accounts:
assetQuery — flat list and single-field bucketed countSource accounts:
searchAssetData — flat listaggregateAssetData — single-field bucketed countThere is no compound-filter + aggregation tool. For "filtered list and bucket counts", run the search and the aggregate as two sequential calls and combine client-side.
getApiFields with entityType: ["ASSET"] — field discovery when unsure of the field namegetGroupByFields — valid aggregation dimensionsgetTopValues — enum-like value discovery for a field (build in [...] sets)getAccountSettings / getAccountPreferences — composite FF detectiongetEffectiveAccessWorkspaces / getWorkspacesByAccountId — workspace scopingvalidateFilter — FQL syntax validationcreateDeepLink (preferred) — build a URL from entity type + filter (call once per list/aggregation, plus once per bucket if you need per-bucket links)getDeepLink — URL for a known assetIdClassify the question into one of:
| Shape | Example | Tool |
|---|---|---|
| Flat list | "Show me all assets where X" | search*Data / assetQuery |
| Bucketed count (one group-by) | "How many assets by type?" | aggregate*Data /assetQuery |
| Compound filter + aggregation | "Exposed-to-internet AND critical, grouped by workspace" | search*Data and aggregate*Data (two calls; combine client-side) or assetQuery in case of composite mode |
| Aggregation + deep links per bucket | "Bucketed counts I can click into" | createDeepLink |
If you're unsure of a field path or acceptable value:
getApiFields(entityType=["ASSET"])
getTopValues(field="asset.mappedAttributes.cloudProperties.provider") # or compositeAsset equivalent
getGroupByFields(entityType="ASSET")
Follow _shared/fql-grammar.md. Critical rules:
asset.* or compositeAsset.*) based on Step 0.5.AND/OR.asset.criticality is numeric — compare with >=, =, < using integers (e.g., asset.criticality >= 4).Optional sanity check: validateFilter before firing the actual query.
Apply the Step 1 classification. For compound filters + aggregation, fire search*Data and aggregate*Data with the same filters string — the search returns the row list, the aggregate returns the bucket counts.
Use *Query in case of composite mode.
createDeepLink for the filtered Assets view.createDeepLink per bucket, with the bucket's value narrowed into the filter (e.g. add AND <field> = '<bucket-value>').getDeepLink(assetId).**Query:** <plain-English restatement>
**Account:** <account name + id> (composite / source)
**Filter:** `<FQL>`
<table of results with a "View in Platform" column>
[View full list in Platform](<top-level deep link>)
| Filter shape | No aggs | With aggs |
|---|---|---|
asset.status = 'active' (single) | searchAssetData | aggregateAssetData |
asset.reachability = 'Exposed' AND asset.criticality >= 4 (compound, numeric criticality) | searchAssetData | searchAssetData + aggregateAssetData (two calls, same filter) |
For composite accounts there's no separate searchCompositeAssetData / aggregateCompositeAssetData — use the single assetQuery tool with compositeAsset.* prefixes; it returns the row list and bucket counts in one call.
# Source mode
aggregateAssetData
aggs: [{ name: "byWorkspace", function: { type: "TERMS", field: "asset.workspaces.name", size: 25 } }]
# Composite mode
assetQuery
aggs: [{ name: "byWorkspace", function: { type: "TERMS", field: "compositeAsset.workspaces.name", size: 25 } }]
Enrich workspace-ids → names via getWorkspacesByAccountId.
There are no asset.exposure.* rollup fields — the asset record does not carry exposure counts/severity. Run a two-step pattern: query EXPOSURE first, then ASSET (use composite variants if the account is composite):
# 1) Find exposures matching the criteria, collect assetIds
searchExposureData
filters: exposure.status = 'Open'
AND exposure.scores.scoreLevel = 'Critical'
fields: ["exposure.assetId"]
# 2) Pull the asset records for those ids, scoped to prod workspaces and exposed-to-internet
# NOTE: FQL list literals use parentheses, not square brackets.
searchAssetData
filters: asset.assetId in ('<id1>','<id2>',...)
AND asset.reachability = 'Exposed'
AND asset.workspaces.id in (<prod-ws-id-1>, <prod-ws-id-2>)
# 3) Bucket counts on the same asset filter (e.g., by asset type).
# aggs entries are {name, function: {type, field, size?}}.
# `function` is an object with a `type` discriminator (TERMS for
# bucketing, COUNT/SUM/MIN/MAX/AVG for metrics, DATE_HISTOGRAM for
# time series). String-form `function: "TERMS"` is rejected.
aggregateAssetData
filters: <same as step 2>
aggs: [{ name: "by_type", function: { type: "TERMS", field: "asset.assetType", size: 25 } }]
searchAssetData
filter: "asset.firstDiscoveredOn" >= "<ISO-8601 30 days ago>"
sort: "asset.firstDiscoveredOn:desc"
aggregateAssetData
aggs: [{
name: "byCredentialed",
function: { type: "TERMS", field: "asset.mappedAttributes.isCredentialed", size: 2 }
}]
# or asset.isCredentialedAsset — confirm the active field via getApiFields
securin-cve-enrichment or securin-threat-correlation.securin-exposure-triage.Securin__search_tools meta-tool to find the right MCP tool by description.getApiFields. Don't guess field paths across accounts; custom attributes differ.getEffectiveAccessWorkspaces will omit it; surface the gap.When this skill produces aggregated or multi-row data (counts, trends, distributions, comparisons, single-CVE reports), emit a chart/graph/infographic in the Securin brand palette (#712880 / #453983 / #542ade / #987bf7 / #d7cbfb), Lato font, light theme, with the Securin logo. Default colormap uses the monotone gradient defined in _shared/brand.md. Offer customization after delivery; never default to a different brand.
npx claudepluginhub securin-public/securin-skills --plugin securin-platformGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.