Artefact Metadata Search
The endpoint POST /artefacts/metadata/query/by-search-expression provides a structured query
interface for searching artefact metadata stored in the delivery-db. It supports filtering,
excluding, full-text search, OCM scope resolution, severity comparisons, and cursor-based
pagination.
A companion endpoint GET /artefacts/metadata/query-attributes returns the list of queryable
fields, their types, and supported operators — useful for building UIs or validating queries
client-side.
Request format
{
"criteria": [ <criterion>, ... ],
"limit": 50,
"sort": [ { "field": "meta.creation_date", "order": "desc" } ],
"cursor": null
}
Field |
Type |
Default |
Description |
|---|---|---|---|
|
array |
|
List of filter criteria (see below) |
|
integer |
|
Page size, capped server-side at |
|
array |
|
Sort specification (see Sorting) |
|
object |
|
Seek cursor for next page (see Pagination) |
Criteria
Every criterion is a JSON object with a required type field. All criteria are ANDed
together. Within criteria of the same type and attribute, OR semantics apply (see details
per type below).
An optional "mode": "exclude" field negates any criterion.
1. ocm — component/artefact scope
Filters by OCM component identity (name or name:version).
{ "type": "ocm", "value": "acme.org/my-comp" }
{ "type": "ocm", "value": "acme.org/my-comp:1.2.3" }
{ "type": "ocm", "value": "acme.org/my-comp:1.2.3", "recursive": true }
{ "type": "ocm", "value": "acme.org/my-comp:1.2.3", "mode": "exclude" }
Field |
Required |
Description |
|---|---|---|
|
yes |
|
|
no |
If |
|
no |
|
Multiple ocm includes are OR-ed — useful for scoping across several components at once.
Version-less queries (acme.org/my-comp without a version) match all rows with that
component name regardless of version, including rows where component_version is NULL.
Versioned queries without a component descriptor lookup perform a strict
component_name = X AND component_version = Y match. With a component descriptor lookup
configured, the server resolves the component’s artefact list from the OCM registry and
additionally matches rows where component_version is NULL but the artefact key matches
a known artefact of that component version (handles findings stored without a component
version).
Rescoring-aware version matching: when type:rescorings is present in the criteria,
versioned ocm: filters also match rows where component_version IS NULL (in addition to
the exact version). This is because rescorings are typically stored without a component
version since they apply across all versions of a component.
1. artefact-metadata — field filter
Filters on a specific attribute of the artefact metadata row.
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "finding/vulnerability" }
{ "type": "artefact-metadata", "attr": "data.cve", "op": "in", "values": ["CVE-2024-1234", "CVE-2024-5678"] }
{ "type": "artefact-metadata", "attr": "data.severity", "op": "cmp", "cmp": ">=", "value": "HIGH" }
{ "type": "artefact-metadata", "attr": "meta.creation_date", "op": "range", "gte": "2025-01-01T00:00:00Z" }
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "finding/vulnerability", "mode": "exclude" }
Supported attr values
Attribute |
Column / source |
Notes |
|---|---|---|
|
|
See Data types |
|
|
Only populated for |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JSONB |
e.g. |
|
JSONB |
e.g. |
Supported op values
|
Required fields |
Semantics |
|---|---|---|
|
|
Exact match. If |
|
|
Any-of match (OR semantics). All values compared as strings. |
|
|
Datetime range, both bounds inclusive. Values must be ISO 8601. Either bound may be omitted for an open range. Only applicable to datetime attributes. |
|
|
Comparison operator: |
AND/OR semantics
Criteria on different attributes are ANDed.
Multiple criteria on the same attribute (same
attr) are ORed (include) orNOT(OR(...))(exclude).
3. fulltext — free-text search
Searches for a token across a set of default fields using a case-insensitive contains match.
{ "type": "fulltext", "value": "kerberos" }
{ "type": "fulltext", "value": "kerberos", "fields": ["data.summary", "data.cve"] }
{ "type": "fulltext", "value": "kerberos", "mode": "exclude" }
Field |
Required |
Description |
|---|---|---|
|
yes |
Token to search for |
|
no |
List of attributes to search in. Defaults to |
|
no |
|
Multiple fulltext criteria are ANDed — all tokens must match (somewhere across the configured fields).
Severity comparisons
Severity values in the DB are stored as string IDs (e.g. NONE, LOW, MEDIUM, HIGH,
CRITICAL). Numeric comparison (op: cmp) works directly against the raw string. However,
for symbolic comparisons (data.severity>=HIGH) to work correctly, the server resolves the
symbolic ID to a numeric value via the configured finding categorisations.
This resolution requires exactly one included finding type in the criteria. If multiple
finding types are selected (or none), symbolic severity comparisons will be rejected with a
400 Bad Request.
Example:
[
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "finding/vulnerability" },
{ "type": "artefact-metadata", "attr": "data.severity", "op": "cmp", "cmp": ">=", "value": "HIGH" }
]
Data types
The type field on each row identifies what kind of data it holds. Common values:
Value |
Description |
|---|---|
|
CVE vulnerability finding |
|
License compliance finding |
|
Cryptography finding |
|
Malware scan finding |
|
Diki policy finding |
|
SAST finding |
|
Falco runtime finding |
|
OS identification finding |
|
IP finding |
|
Custom rescoring applied to a finding |
|
Scan metadata |
|
Compliance snapshot |
For rescorings rows, referenced_type holds the finding type the rescoring applies to
(e.g. finding/vulnerability).
Querying rescorings
Rescorings might be stored without a component version because it can be intended to apply across all versions of a component. To query rescorings effectively:
[
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "rescorings" }
]
Scope to a specific finding type:
[
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "rescorings" },
{ "type": "artefact-metadata", "attr": "referenced_type", "op": "eq", "value": "finding/vulnerability" }
]
Scope to a component (versioned). Because rescorings typically have no component_version,
the server automatically widens the match to also include rows where component_version IS NULL
whenever type: rescorings is the only included type filter:
[
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "rescorings" },
{ "type": "ocm", "value": "acme.org/my-comp:1.2.3" }
]
This returns rescorings for acme.org/my-comp regardless of whether they were stored with
version 1.2.3 or without any version.
Sorting
Default sort is meta.creation_date DESC, id DESC. A secondary id sort is always appended
automatically to guarantee a stable cursor position.
Supported sort fields:
Field |
Description |
|---|---|
|
Creation timestamp (datetime-aware) |
|
Last update timestamp (datetime-aware) |
|
Data type string |
|
Component name |
|
Component version |
|
Row ID (always appended as tiebreaker) |
All sort fields in a single request must use the same direction (asc or desc). Mixed
sort orders are rejected with 400 Bad Request.
Pagination
The endpoint uses cursor-based client-facing pagination. After receiving a page,
pass the returned nextCursor object as cursor in the next request to continue from where
the previous page ended. A null nextCursor means there are no more results.
The cursor encodes the sort-field values of the last returned row. It is opaque and must not
be modified. Changing criteria or sort between pages yields undefined results.
To avoid pagination becoming arbitrarily expensive on very large result sets that are
heavily filtered post-fetch (by finding configs), the server over-fetches from the database
(up to 10x the page size per round, capped at 2000 rows) and iterates up to 10 rounds
before returning a partial page.
Examples
All vulnerability findings for a component version
{
"criteria": [
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "finding/vulnerability" },
{ "type": "ocm", "value": "acme.org/my-comp:1.2.3" }
]
}
High or critical vulnerabilities across a component tree
{
"criteria": [
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "finding/vulnerability" },
{ "type": "artefact-metadata", "attr": "data.severity", "op": "cmp", "cmp": ">=", "value": "HIGH" },
{ "type": "ocm", "value": "acme.org/my-comp:1.2.3", "recursive": true }
]
}
Specific CVE across all component versions
{
"criteria": [
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "finding/vulnerability" },
{ "type": "artefact-metadata", "attr": "data.cve", "op": "eq", "value": "CVE-2024-1234" }
]
}
All rescorings for a component, any finding type
{
"criteria": [
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "rescorings" },
{ "type": "ocm", "value": "acme.org/my-comp:1.2.3" }
]
}
Findings created after a specific date, excluding a known noisy component
{
"criteria": [
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "finding/vulnerability" },
{ "type": "artefact-metadata", "attr": "meta.creation_date", "op": "range", "gte": "2025-06-01T00:00:00Z" },
{ "type": "ocm", "value": "acme.org/noisy-comp", "mode": "exclude" }
]
}
Free-text search for a package name
{
"criteria": [
{ "type": "artefact-metadata", "attr": "type", "op": "eq", "value": "finding/vulnerability" },
{ "type": "fulltext", "value": "openssl" }
]
}