
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
@sourceregistry/node-ovsdb
Advanced tools
Low-level OVSDB client for Node.js with:
npm install @sourceregistry/node-ovsdb
Generate types from a schema with:
npx ovsdb-generate --help
The client is intentionally low-level and maps closely to the wire protocol.
list_dbsget_schematransactcancelmonitormonitor_condmonitor_cond_sincemonitor_cancellockstealunlockechoset_db_change_awareupdate, update2, update3, locked, stolenUnix socket:
import {OVSDBClient} from "@sourceregistry/node-ovsdb";
const client = new OVSDBClient({
socketPath: "/var/run/openvswitch/db.sock",
timeout: 5000
});
try {
await client.connect();
const databases = await client.listDbs();
const schema = await client.getSchema("Open_vSwitch");
console.log(databases, schema.version);
} finally {
await client.close();
}
Plain TCP:
import {OVSDBClient} from "@sourceregistry/node-ovsdb";
const client = new OVSDBClient({
host: "127.0.0.1",
port: 6640
});
TLS:
import {OVSDBClient} from "@sourceregistry/node-ovsdb";
const client = new OVSDBClient({
host: "ovsdb.example.internal",
port: 6640,
tls: true,
tlsOptions: {
servername: "ovsdb.example.internal",
rejectUnauthorized: true
}
});
The package includes an ovsdb-generate CLI that emits TypeScript row and database model types you can use with OVSDBClient<...>.
Generate from a checked-in schema file:
npx ovsdb-generate --schema ./Open_vSwitch.schema.json --out ./src/generated/ovsdb.ts
Generate directly from a live OVSDB server:
npx ovsdb-generate --socket /var/run/openvswitch/db.sock --db Open_vSwitch --out ./src/generated/ovsdb.ts
Generate from a live TCP endpoint:
npx ovsdb-generate --host 127.0.0.1 --port 6640 --db Open_vSwitch --out ./src/generated/ovsdb.ts
Generate from a live TLS endpoint:
npx ovsdb-generate \
--host ovsdb.example.internal \
--port 6640 \
--tls \
--tls-ca-file ./pki/ca.pem \
--tls-cert-file ./pki/client.pem \
--tls-key-file ./pki/client.key \
--db Open_vSwitch \
--out ./src/generated/ovsdb.ts
You can override the generated top-level type name with --name OpenVSwitchDb.
You can provide your own table model to get typed table names, rows, selected columns, conditions, mutations, and tuple-shaped transaction results.
import {OVSDBClient, type DatabaseOperation, type OvsSet} from "@sourceregistry/node-ovsdb";
type OpenVSwitchDb = {
Bridge: {
name: string;
ports: OvsSet<string>;
};
Port: {
name: string;
interfaces: OvsSet<string>;
};
};
const client = new OVSDBClient<OpenVSwitchDb>();
await client.connect();
const operations = [
{
op: "select",
table: "Bridge",
where: [["name", "==", "br-int"]],
columns: ["name", "ports"]
},
{
op: "insert",
table: "Port",
row: {
name: "uplink0",
interfaces: ["set", []]
}
}
] satisfies [DatabaseOperation<OpenVSwitchDb>, DatabaseOperation<OpenVSwitchDb>];
const [bridges, insertedPort] = await client.transact("Open_vSwitch", operations);
For a higher-level staged flow, use client.transaction(...). The callback can build operations against a transaction-scoped helper, and the library will send one transact request only if the callback completes successfully. By default it appends a trailing commit operation automatically.
const outcome = await client.transaction("Open_vSwitch", (tx) => {
tx.comment("prepare bridge lookup");
tx.select({
op: "select",
table: "Bridge",
where: [["name", "==", "br-int"]],
columns: ["name"]
});
return "ok";
});
import {OVSDBClient} from "@sourceregistry/node-ovsdb";
const client = new OVSDBClient();
await client.connect();
client.on("update", (notification) => {
const [monitorId, updates] = notification.params;
console.log("monitor", monitorId, updates);
});
await client.monitor("Open_vSwitch", "bridges", {
Bridge: {
columns: ["name"],
select: {
initial: true,
insert: true,
modify: true,
delete: true
}
}
});
For conditional monitoring, use monitorCond() or monitorCondSince().
OVSDB does not usually emit a single semantic event like "interface attached to bridge". Instead, you observe the row changes that together mean an attachment happened:
Interface row may appearPort row may appearBridge row may be modified so its ports set now includes that portIn practice, the bridge update is usually the strongest signal that something was attached to the virtual switch.
Why this works:
Bridge.ports column is the relationship that tells you which ports are attached to the bridgePort and Interface tables to resolve names or metadata for the newly attached objectsIf you want richer correlation, monitor Bridge, Port, and Interface together and keep a small in-memory cache keyed by UUID so you can map a changed bridge port set back to the concrete port and interface names.
Example: examples/detect-interface-added.ts
These examples focus on patterns that show up often in virtualized environments, where OVS is used to connect VM or container networking to a virtual switch.
What this does:
Interface row of type internalPort that owns that interfaceBridge that owns that portWhy it is done this way:
Example: examples/bridge-port-interface.ts
What this does:
InterfacePort that references that interfaceports setWhy this is a common pattern:
ports set avoids rewriting the whole bridge rowExample: examples/attach-interface-to-bridge.ts
In practice, type: "internal" is useful when you want OVS itself to create the interface device. Leaving type unset is common when attaching an already existing device such as a tap interface created by a hypervisor.
The client implements AsyncDisposable, so it also works with await using in runtimes that support explicit resource management.
await using client = new OVSDBClient();
await client.connect();
const dbs = await client.listDbs();
ErrorOvsdbRpcErrorprotocolErrortransportErrorGenerate API docs with Typedoc:
npm run docs:build
The public API is documented with TSDoc so the generated output is usable as a reference, not just a symbol dump.
Planned work for the next iterations of the library:
PortRef or InterfaceRef instead of plain UuidrefTable and refTypeThe intended direction is to make the generator more relation-aware first, before attempting a larger ORM-style layer.
npm test
npm run build
npm run docs:build
Apache-2.0. See LICENSE.
FAQs
TypeScript OVSDB client for Node.js
We found that @sourceregistry/node-ovsdb demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.