Plugin System Architecture

May 18, 2026 · View on GitHub

NornicDB ships a unified plugin loader that auto-detects and routes plugins to the right subsystem at startup. Two plugin types are supported:

TypeInterfaceSubsystemExample
Functionapoc.Plugin (in apoc/)Cypher executor — registers functions callable from queriesAPOC (apoc.coll.sum, apoc.text.join, apoc.algo.pageRank, ~960 functions)
Heimdallheimdall.HeimdallPlugin (in pkg/heimdall/)SLM subsystem — registers actions invokable by the AI assistantWatcher plugin (heimdall_watcher_query, heimdall_watcher_status, …)

Plugins are dynamic Go shared objects (.so files on Linux/macOS) loaded at startup from configured directories. Each plugin's Type() method tells the loader which subsystem to route it to, so neither type requires manual registration in the host binary.

Loader

The loader lives in pkg/nornicdb/plugins.go for function plugins and pkg/heimdall/plugin.go for Heimdall plugins. Both follow the same pattern:

  1. Scan the plugin directory for *.so files.
  2. plugin.Open() each file and look up the exported Plugin symbol.
  3. Call Type() on the symbol.
  4. Route to the function-plugin path or the Heimdall-plugin path.

Function plugins register their functions with the Cypher executor through the APOC adapter; Heimdall plugins register their actions with the SubsystemManager and start their lifecycle hooks.

Configuration

VariablePurpose
NORNICDB_PLUGINS_DIRDirectory scanned for function plugins. Default: apoc/built-plugins.
NORNICDB_PLUGINS_ENABLEDMaster switch for the loader.
NORNICDB_HEIMDALL_PLUGINS_DIRDirectory scanned for Heimdall plugins.
NORNICDB_HEIMDALL_ENABLEDHeimdall plugins only start when this is true (the loader skips them otherwise to avoid background goroutines).

There is no separate Cypher procedure for plugin lifecycle (dbms.plugins.list/load/unload is not implemented). Plugins are loaded once at startup; restart the server to add or remove plugins.

Where the consumer-facing docs live

This architecture file is intentionally small. For day-to-day usage:

Platform support

Go plugins are supported on Linux (amd64, arm64), macOS (arm64, amd64), and not supported on Windows (Go's plugin package is Linux/macOS only). For Windows deployments, plugins must be compiled into the main binary as built-ins.

Security posture

  • Plugins run in the same process and with the same OS permissions as nornicdb serve. They are not sandboxed.
  • Only load plugins from trusted sources.
  • Plugin code has full system access (storage engine, network, filesystem).
  • Use Docker volume mounts and explicit NORNICDB_PLUGINS_DIR paths for isolation.
  • Heimdall plugins additionally see the active session's PrincipalRoles, DatabaseAccessMode, and ResolvedAccess so they can enforce per-database RBAC inside their own action handlers — see Heimdall Plugins for the contract.