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

Database Administration

CBOM Secure stores everything in MongoDB. This page is what is stored where, how it is secured, how it grows, and the operations a database administrator will be asked to perform.

Backup and restore procedures are on Backup and Recovery; replica set construction is in High Availability Runbooks. This page covers the database itself.

Two databases, not one

DatabaseHolds
CBOMDataThe product: inventory, hosts, tasks, templates, policies, configuration, dashboards, users
CBOMAuditThe evidence: the audit trail, material histories, deployment histories

Both must be backed up, and both must be restored together. CBOMAudit is the one that gets forgotten, because nothing in the console suggests there is a second database. Restoring only CBOMData gives a platform that works perfectly and has lost every history timeline, every audit record and every deployment history — and nothing reports the loss, because each of those reads simply returns nothing.

The separation is deliberate: the audit trail has a different retention policy, a different access model and a different growth rate from the operational data, and it must not be editable by anything that can edit the product's own state.

The collections that matter

In CBOMData:

CollectionHoldsGrowth
CryptoMaterialThe deduplicated inventory — the product's primary dataWith the estate
CMDepositRaw sensor results awaiting deduplicationTransient; should drain
CMCollectRunsOne row per collection call, with the ingestion countersWith scan frequency
DiscoveryLogsSensor log recordsWith scan frequency; TTL applies
HostsInfoTargets and their encrypted credentialsWith the estate
TaskDeployment, DeployManagementTasks and templatesSlowly
ConfigsThe configuration schema and the form that edits itTwo documents
AdminUsers, roles, groups and the permission mapSlowly
Widgets, Layouts, DashboardTemplatesDashboardsSlowly
AnalyticRulesAlgorithm rankings and scoring inputsFixed
CMTags, CMTagScopesTag definitions and named scopesSlowly
SensorSchemaRegistered sensor schemas, seeded at startupFixed
CountersThe atomic id allocatorA few documents

In CBOMAudit:

CollectionHolds
AuditLogWho did what — one flat document per audited action
CMHistoriesPer-material change timeline
TaskDeploymentHistoriesOne document per task, holding its runs

CMDeposit should be close to empty between scans. It is a staging collection that the deduplication pass consumes. Rows that persist mean the pass is not running, or is failing — and the materials they represent are not in the inventory yet. A growing CMDeposit is the earliest sign that ingestion has stalled, and it is worth a monitor.

Security

Authentication on, always. An exposed MongoDB with no authentication is the single worst configuration mistake available here — the inventory names every weak key in the estate, which makes it a map for an attacker rather than merely a data loss.

Bind to the platform interface, not to everything. The deployment's host port binding defaults to loopback deliberately. Changing it to 0.0.0.0 publishes the database to every network the host is on, with only the root password in front of it. If the application tier is on another host, bind to the specific interface it reaches and firewall the port to that host alone.

Give the application its own user, with readWrite on the two databases and nothing more. It does not need dbAdmin, clusterAdmin or root. Keep the root account for administration and do not use it from the application.

use admin
db.createUser({
  user: "cbomapp",
  pwd: "<strong password>",
  roles: [
    { role: "readWrite", db: "CBOMData" },
    { role: "readWrite", db: "CBOMAudit" }
  ]
})

Encrypt at rest. Use the storage engine's encryption, or full-disk encryption on the volume. Target credentials are separately encrypted by the platform before they are stored, but the inventory itself is not, and the inventory is sensitive on its own account.

Encrypt in transit between the application tier and the database wherever they are on different hosts.

Indexes

Indexes are created by the platform at startup — the application ensures what it needs and does not require an administrator to build them. There are unique constraints on task and template names, compound indexes behind the notification engine and the deployment histories, and two time-to-live indexes.

Do not drop an index you did not create. A missing unique index does not produce an error; it produces duplicate task names and a second document that quietly shadows the first.

Do add indexes for your own reporting. If you query the inventory directly for reports, index for those queries — but add them to a secondary first and watch the effect on write latency before promoting the practice.

Retention and growth

Three collections expire their own data through TTL indexes:

CollectionControlled by
AuditLogThe audit retention setting
NotificationTriggerEventsThe notification trigger retention setting
NotificationOutboxThe notification outbox retention setting

The audit TTL is on a date field, not on the timestamp string. The record carries both an ISO-8601 string for reading and a real date for expiry. This matters if you ever rebuild the index by hand: MongoDB accepts expireAfterSeconds on a string field and then expires nothing at all, silently, forever. Point it at the date field.

Everything else grows until something removes it. The ones that grow fastest are DiscoveryLogs and CMCollectRuns, both driven by scan frequency rather than estate size — a nightly scan of a small estate generates more of these than a monthly scan of a large one.

Capacity planning. Watch the working set rather than the total size: query latency degrades when the working set stops fitting in memory, long before storage fills. Size from the Sizing guide and monitor the pressure signal, not the disk.

Routine operations

Health check:

db.adminCommand({ ping: 1 })
db.stats()
db.CryptoMaterial.estimatedDocumentCount()

Find what is growing:

db.getCollectionNames().map(c => ({
  name: c,
  size: db[c].stats().size,
  count: db[c].estimatedDocumentCount()
})).sort((a, b) => b.size - a.size)

Reclaim space. MongoDB does not return disk to the filesystem when documents expire. On a replica set, resynchronise one secondary at a time from scratch and step the primary down last — that compacts without an outage. On a single node, compact takes a lock; schedule it.

Check for a stalled pipeline:

db.CMDeposit.estimatedDocumentCount()          // should be near zero at rest
db.CMCollectRuns.find().sort({collectedAt:-1}).limit(5)

Seeding and migration

A fresh install is seeded from the files in the deployment's initial-data directory by a one-shot container that runs the seeding tool. That covers the configuration schema, the dashboard widgets, the standard policies, the menu structure, the algorithm rankings and the initial administrative records.

The seed is a first-boot operation and a no-op afterwards. Once a document exists, the bootstrap leaves it alone — which is correct, since it must not overwrite a customer's configuration, and is also why upgrading an existing database needs explicit migration rather than a restart. See Upgrade and Migration.

Troubleshooting

The platform starts and reports no database. Authentication, binding or firewall. Test from the application host with the application's own credentials, not from the database host as root — that tests a different thing and usually succeeds.

Everything works but history pages are empty. CBOMAudit was not restored, or the application user has no rights on it. This is the most common consequence of a partial restore.

Writes slow down over time. Either the working set has outgrown memory, or an index was added that is not earning its write cost. Check working-set pressure first.

CMDeposit keeps growing. The deduplication pass is not completing. Check the collector worker and the broker before the database.

Duplicate task or template names appear. A unique index is missing. Deduplicate the documents by hand, then let the application recreate the index on restart.

A TTL index exists and nothing expires. It is on a string field. Drop it and recreate it on the date field.

Disk is full but document counts are falling. Expired documents have freed space inside the files that has not been returned to the filesystem. Compact, or resynchronise members in turn.

On this Page:
Support Privacy Policy Terms of Service

Copyright 2026 Encryption Consulting LLC. All rights reserved.