OpenWork Database Schema: Complete MySQL Structure for the different-ai/openwork Platform

The OpenWork database schema uses MySQL managed by Drizzle-ORM, organizing data into logical table groups for organizations, plugins, connectors, and telemetry, with TypeScript definitions in ee/packages/den-db/src/schema/ and SQL migrations in ee/packages/den-db/drizzle/.

The different-ai/openwork repository implements a multi-tenant platform architecture through a structured relational database. Built with Drizzle-ORM type-safe SQL helpers such as mysqlTable, index, and uniqueIndex, the schema separates concerns into distinct domains that handle organization membership, plugin configurations, external integrations, and diagnostic telemetry.

Schema Architecture Overview

The OpenWork database schema divides its MySQL tables into seven logical groups that mirror the platform's core concepts. These groups manage the full lifecycle of organizations, their plugins, connections to external services like GitHub, and system diagnostics.

  • Organization & Membership: Multi-tenant isolation, roles, and invitations
  • Plugins & Config Objects: Reusable skills, agents, tools, and version history
  • Connectors: External account integrations and synchronization events
  • Desktop Handoff: Secure session bootstrap for desktop clients
  • Telemetry & Diagnostics: Analytics events and debugging data
  • SCIM & Teams: Enterprise provisioning and team management
  • Shared Resources: LLM providers and capability credentials

Organization and Membership Tables

The foundation of the OpenWork database schema resides in src/schema/org.ts, which defines multi-tenant isolation and access control.

These tables include:

  • organization: Tenant root entities with unique slugs
  • organization_role: Custom role definitions with permissions
  • member: User memberships linked to organizations, with removedAt tracking for soft deletes
  • invitation: Pending membership invitations
  • workspace_bootstrap and workspace_claim: New workspace provisioning flows

Plugin and Config Object Architecture

Plugin data lives in src/schema/sharables/plugin-arch.ts and related migration 0010_plugin_arch.sql. This group implements the platform's extensible architecture for reusable components.

Key tables include:

  • plugin: Registered plugins with organization_id, name, description, and status fields
  • plugin_config_object: Links plugins to their exposed capabilities
  • plugin_access_grant: Permission assignments for plugin usage
  • config_object and config_object_version: Version-controlled configuration storage
  • config_object_access_grant: Fine-grained access to specific config objects
  • plugin_arch, llm_providers, and capability_credentials: Supporting resources for AI capabilities

Connector Integration Tables

External integrations (notably GitHub) are modeled in src/schema/connector.ts. This schema group handles oauth accounts, instance configurations, and synchronization state.

The connector tables include:

  • connector_account: External service credentials and metadata
  • connector_instance: Configured connector instances per organization
  • connector_target: Destination mappings for synced data
  • connector_mapping: Relationships between external and OpenWork entities
  • connector_sync_event: Audit log of synchronization operations
  • connector_source_binding and connector_source_tombstone: Source tracking and deletion handling

Desktop Session Management

Short-lived security tokens for desktop client authentication are defined in src/schema/desktop-policies.ts (migration 0001_desktop_handoff_grants.sql).

  • desktop_handoff_grant: Temporary grants allowing desktop clients to handshake with the server, containing user_id, session_token, and expires_at fields
  • desktop_connect_grant: Connection establishment permissions

These tables implement time-bound security policies with automatic expiration.

Telemetry and SCIM Tables

System observability and enterprise provisioning tables include:

  • telemetry_event and telemetry_session_dimension: Usage analytics captured for diagnostics
  • diagnostics: System health and error reporting
  • scim_group, team, and scim_sync_events: Enterprise identity provisioning support

Definitions reside in src/schema/telemetry.ts.

Key Schema Implementation Files

The Drizzle-ORM schema is organized across these source files in ee/packages/den-db/src/schema/:

File Path Tables Defined
org.ts organization, organization_role, member, invitation, workspace_bootstrap, workspace_claim
sharables/plugin-arch.ts plugin, plugin_config_object, plugin_access_grant, config_object, config_object_version
connector.ts connector_account, connector_instance, connector_target, connector_mapping, connector_sync_event
desktop-policies.ts DesktopHandoffGrantTable, DesktopConnectGrantTable
telemetry.ts telemetry_event, telemetry_session_dimension, diagnostics

The central database client is exported from src/drizzle.ts.

Database Interaction Examples

The following TypeScript examples demonstrate typical CRUD patterns using the OpenWork database schema with Drizzle-ORM:

import { db } from "@openwork/den-db";
import { organization, member, plugin } from "@openwork/den-db/src/schema";

// Fetch an organization by slug
export async function getOrgBySlug(slug: string) {
  const org = await db
    .select()
    .from(organization)
    .where(eq(organization.slug, slug))
    .limit(1);
  return org[0] ?? null;
}

// List active members with null check on removedAt
export async function listActiveMembers(orgId: string) {
  return db
    .select()
    .from(member)
    .where(and(eq(member.organizationId, orgId), isNull(member.removedAt)));
}

Creating temporary desktop grants uses the table from desktop-policies.ts:

import { DesktopHandoffGrantTable } from "@openwork/den-db/src/schema/desktop-policies";

export async function createHandoffGrant(params: {
  id: string;
  userId: string;
  sessionToken: string;
  expiresAt: Date;
}) {
  await db.insert(DesktopHandoffGrantTable).values({
    id: params.id,
    user_id: params.userId,
    session_token: params.sessionToken,
    expires_at: params.expiresAt,
    created_at: new Date(),
  });
}

Registering plugins utilizes the plugin table defined in sharables/plugin-arch.ts:

export async function registerPlugin(pluginData: {
  id: string;
  organizationId: string;
  name: string;
  description?: string;
}) {
  await db.insert(plugin).values({
    id: pluginData.id,
    organization_id: pluginData.organizationId,
    name: pluginData.name,
    description: pluginData.description ?? null,
    status: "active",
    created_at: new Date(),
    updated_at: new Date(),
  });
}

Migration Strategy

Database migrations are stored as SQL files in ee/packages/den-db/drizzle/ and applied sequentially. Key migration files include:

These files match the TypeScript schema definitions and are generated from the Drizzle-ORM configuration.

Summary

  • The OpenWork database schema uses MySQL with type-safe Drizzle-ORM definitions in ee/packages/den-db/src/schema/
  • Tables are grouped by domain: organizations, plugins, connectors, desktop sessions, and telemetry
  • Multi-tenancy is enforced through organization_id foreign keys across all relevant tables
  • Desktop authentication relies on time-bound grants in desktop_handoff_grant
  • Plugin architecture supports versioned configuration objects and access control
  • Schema migrations live in ee/packages/den-db/drizzle/ with sequential numbering

Frequently Asked Questions

What database engine does OpenWork use?

OpenWork uses MySQL as its primary relational database. The schema is managed through Drizzle-ORM, a type-safe SQL-like ORM that provides compile-time safety for database operations while maintaining raw SQL performance characteristics.

Where are the Drizzle-ORM schema definitions located?

The TypeScript schema definitions are located in ee/packages/den-db/src/schema/. Key files include org.ts for organization data, sharables/plugin-arch.ts for plugin configurations, connector.ts for GitHub integrations, and desktop-policies.ts for session management tables.

How are database migrations managed in OpenWork?

Migrations are stored as SQL files in ee/packages/den-db/drizzle/ with sequential prefixes (e.g., 0001_desktop_handoff_grants.sql, 0010_plugin_arch.sql). These files contain the DDL statements that create tables, indexes, and constraints, and are applied in numerical order to maintain schema consistency across environments.

What is the purpose of the desktop_handoff_grant table?

The desktop_handoff_grant table stores short-lived authentication grants that allow desktop clients to establish sessions with the OpenWork server. As defined in src/schema/desktop-policies.ts, each grant contains a session_token, user_id, and expires_at timestamp, implementing a secure handshake mechanism that automatically invalidates after expiration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →