CBOM Documentation

CBOM Secure

  • Administrative Guide
  • Login and Authentication
    • Overview
    • Dashboard Interface
    • Dashboard Operations
    • Data Visualization
    • Overview
    • Host
    • Template
      • Networked Deployments
      • Cloud Deployments
      • Off-Grid Deployments
      • Tags
      • Integrations
      • Cloud Servers
      • CycloneDX Export
    • Sensors Reference
    • Overview
    • Summary Report
    • PQC Report
    • AI Services
    • Source Code Visualizer
    • Key
    • Certificate
    • CipherSuites
    • Analysis
    • Policy Management
    • User Policy
    • Standard Policy
    • User Management
    • Roles & Permissions
    • System Configuration
    • Introduction
      • Components
      • Data Flows
      • Execution Models
      • Incremental Scanning
      • Security Model
      • Quick Start
      • Topologies
      • Sizing Guide
      • HA and Scaling
      • HA Runbooks
      • Ports and Firewall
      • Reverse Proxy
      • Prerequisites
      • Docker Compose
      • Native on Linux
      • Deployment Server
      • Install Troubleshooting
      • Validation Checklist
      • Managing Services
      • Logging
      • Certificates
      • Configuration
      • Database Administration
      • Backup and Recovery
      • Upgrade and Migration
      • Ops Troubleshooting
      • Methods
      • SAML 2.0 SSO
      • OIDC and Entra ID
      • Token Authentication
      • Password Policy
      • Sensor vs Connector
      • Sensor Guide Structure
      • Capability Matrix
        • AWS
        • Azure
        • Google Cloud
        • Active Directory
        • LDAP Directories
        • AD CS
        • EJBCA
        • CertSecure Manager
        • Thales Luna HSM
        • Entrust nShield HSM
        • SoftHSM2
        • HashiCorp Vault KMIP
        • MSSQL TDE
        • Oracle TDE
        • MySQL TDE
        • MariaDB TDE
        • HTTPS and TLS
        • SSH Servers
        • Windows Certificate Store
        • Linux Trust Store
        • Java Keystores
        • PKCS#12 Keystores
        • GnuPG Keyrings
        • Binaries and Libraries
        • Source Code Scanning
        • GitHub
        • GitLab
        • Bitbucket
        • Local Git
      • Roadmap
      • Integration Model
      • CrowdStrike
      • ServiceNow
      • ServiceNow and Jira Setup
      • Notification Engine
    • Glossary
    • Configuration Reference
    • Data Model Reference
    • API Reference
    • API Authentication
    • Running a Scan via API
    • Searching via API
    • CycloneDX Export Specification
    • Risk and PQC Scoring
    • Built-in Standards
    • Widget Catalogue
    • AI Services Data Handling

Searching the Inventory Through the API

How to get material out of the crypto inventory programmatically: what the query surfaces are, what each one is good for, and how to filter and page through results.

There is no free-form query endpoint

Start here, because it is the question most integrations ask first. CBOM Secure exposes no generic "send a query, get documents" endpoint. There is no path that takes a database expression, and /query, /objects and /discovery — URL shapes reserved during design — were never implemented and have been withdrawn from the product. Do not build against them.

This is deliberate rather than missing. An endpoint that forwards an arbitrary expression to the database makes every field a public interface, and a query that performs acceptably on a test estate can take a production one down. What exists instead are four purpose-built surfaces, each with its own filters, its own paging and its own bounded cost.

SurfaceUse it to
ExportPull material in bulk, as a standard document another tool can read
Widget dataAsk the same question a dashboard tile asks, with your own parameters
AnalysisGet a risk or policy rollup without computing it yourself
HistoryFind what changed, and when

Export — bulk material

The CycloneDX export endpoints are the right surface for an integration that wants the inventory itself: feeding a SIEM, a GRC platform, an asset database, or an offline report.

EndpointReturns
GET /cyclonedx/export/certificatesCertificates
GET /cyclonedx/export/keysKeys
GET /cyclonedx/export/protocolsProtocol endpoints
GET /cyclonedx/export/binaryBinaries
GET /cyclonedx/export/sourcecodeSource-code findings
GET /cyclonedx/exportEvery type, time-bounded

Filters are query-string parameters, and a parameter that accepts a list takes comma-separated values matching any of them. Every endpoint accepts discoverTimeFrom, discoverTimeTo and scanHost; each type adds its own. The full filter tables and the field mapping are on the CycloneDX Export Specification page.

Certificates expiring in a window, as a worked request:

GET /cbomsrv/api/v1/cyclonedx/export/certificates
      ?discoverTimeFrom=2026-01-01T00:00:00Z
      &algorithm=RSA,ECDSA
Authorization: Bearer <session_id>

The combined /cyclonedx/export requires a time bound. At least one of discoverTimeFrom or discoverTimeTo must be present, or the request is rejected with a 400. The bound applies to discovery time or scan time, so material first discovered before the window is still included when a scan inside the window saw it — which is what makes an incremental sync correct rather than merely cheap.

Syncing incrementally. Keep the timestamp of your last successful pull and pass it as discoverTimeFrom on the next. Use the per-type endpoints rather than the combined one: a sync that only cares about certificates should not pay for binaries.

Widget data — any dashboard figure

Every number on every dashboard is available over the API, under parameters you choose. This is the surface for "give me the same breakdown the console shows, but for my own scope".

The pattern is always two calls.

GET /cbomsrv/api/v1/ui/dashboard/widgets
GET /cbomsrv/api/v1/ui/dashboard/widgets/{wid}
POST /cbomsrv/api/v1/ui/dashboard/widgets/{wid}/data

The first lists the catalogue. The second returns one widget's definition including its query schema — the fields that widget's data call accepts. The third posts parameters matching that schema and returns the data.

Read the schema rather than guessing at it. Parameter validation rejects an unknown field outright, so a request carrying a field the widget does not declare fails before the handler runs. The schema is also the authoritative list for that deployment: widget definitions live in the database, so a deployment can carry widgets another does not.

POST /cbomsrv/api/v1/ui/dashboard/widgets/Cert-TBL/data
Content-Type: application/json

{
  "pageNo": 1,
  "pageSize": 50,
  "tagScope": "(\"Production\" $or \"Sales\") $not \"Test\""
}

Table widgets page. Chart widgets return groups, and each group carries the request body that would open the matching table — so a chart result tells you how to drill into it rather than requiring you to construct the follow-up yourself. Replay the emitted body against the named endpoint and the row count matches the number in the chart.

Scoping by tag

tagScope is the filter that most integrations actually want, because it is the one that maps to how an organisation thinks about its estate. It takes a boolean expression over tag names and is accepted by the widget data endpoints and the analysis endpoints.

Tag names are always quoted, and operators carry a $:

"Production"
("Production" $or "Sales") $not "Test"
("Production" $or "Sales") $and $not "Test"
("Production" $or "Sales") $except "Test"

Quoting is mandatory because real tag names contain spaces, and once it is mandatory a tag name can never collide with an operator — so the bare forms and, or and not are accepted too. $not is unary in prefix position and means "and not" after a complete operand; position alone decides. Precedence is $not, then $and, then $or, and parentheses override.

A named scope defined once in the console can be referenced by name with @"Scope Name" instead of being spelled out, and GET /cmtags/scopes/ lists them. POST /cmtags/scopes/validate checks an expression without running it, which is worth calling once when your integration starts rather than discovering a typo as an empty result.

An empty result and a wrong expression look the same from the outside. Validate the expression, and treat zero rows as a result to investigate rather than as "no material matches". A tag name that does not exist is a perfectly valid expression that matches nothing.

Analysis — risk and policy rollups

EndpointReturns
GET /analytic/host-analysis/Per-host risk rollup
POST /analytic/host-analysis-filtered/The same, under a filter
GET /analytic/enterprise-analysis/Estate-wide rollup

These return computed positions rather than documents. Use them when the question is "how bad is it" rather than "what is there" — they are far cheaper than exporting the inventory and computing the answer yourself, and they apply the same scoring the dashboards use, so the numbers agree. The scoring rules are on the Risk and PQC Scoring page.

Policy results come from the policy widgets rather than a separate endpoint; GET /policy/ lists the policies and GET /policy/standard-policy the built-in baselines.

History — what changed

EndpointReturns
GET /cmhistory/The change feed across the whole inventory
GET /cmhistory/{canonicalId}One material's timeline
GET /cmhistory/{canonicalId}/atThat material's state at a point in time
GET /cmhistory/{canonicalId}/diffField-level change between two versions

This is the surface for an integration that reacts to change rather than re-reading state: poll the feed, act on what is new. A bare date on the ts parameter covers the whole of that day.

History is readable and never writable. No path in the API can modify or delete a history entry, which is what makes it usable as evidence.

Paging, ordering and limits

Table widget data takes pageNo and pageSize and returns a total count alongside the rows, so a client can size its loop before starting it. The export endpoints stream a whole filtered set rather than paging — narrow with filters, not with offsets.

Request size and rate limits are on the API Authentication page. The practical guidance: filter server-side, pull incrementally by time, and prefer a per-type export over the combined one.

Choosing a surface

If you wantUse
The whole inventory in a standard formatPer-type CycloneDX export, time-bounded, pulled incrementally
One figure, scoped your wayThe widget's definition, then its /data path
A risk positionThe analysis endpoints
Only what changed since last timeThe history feed, or an export with discoverTimeFrom
To be told rather than to pollA notification rule — see Running a Scan Through the API

Common problems

422 on a widget data call. The request carries a field the widget's schema does not declare. Unknown fields are rejected rather than ignored. Fetch the definition and send only what it declares.

A tagScope returns nothing. Either the expression does not parse, or it parses and matches nothing. POST /cmtags/scopes/validate separates the two. A tag created after your integration last cached the tag list is resolved on a retry, so a transient empty result on a brand-new tag is expected.

400 on /cyclonedx/export. No time bound. Supply discoverTimeFrom, discoverTimeTo, or both — or use a per-type endpoint.

An export times out. The filter is too broad for the estate. Narrow by type first, then by time window, then by scanning host.

Chart and table disagree. They should not — each chart group carries the exact request body that opens its table. Rebuilding that body by hand is the usual cause of a mismatch; replay the emitted one.

404 on /query or /objects. Those paths were never implemented and have been withdrawn. Use the surfaces on this page.

On this Page:
Support Privacy Policy Terms of Service

Copyright 2026 Encryption Consulting LLC. All rights reserved.