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

> Explore the OpenWork database schema, featuring a complete MySQL structure managed by Drizzle-ORM. Understand the organization of tables for plugins, connectors, and telemetry.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: api-reference
- Published: 2026-08-02

---

**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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/src/schema/sharables/plugin-arch.ts) and related migration [`0010_plugin_arch.sql`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/src/schema/desktop-policies.ts) (migration [`0001_desktop_handoff_grants.sql`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/org.ts) | `organization`, `organization_role`, `member`, `invitation`, `workspace_bootstrap`, `workspace_claim` |
| [`sharables/plugin-arch.ts`](https://github.com/different-ai/openwork/blob/main/sharables/plugin-arch.ts) | `plugin`, `plugin_config_object`, `plugin_access_grant`, `config_object`, `config_object_version` |
| [`connector.ts`](https://github.com/different-ai/openwork/blob/main/connector.ts) | `connector_account`, `connector_instance`, `connector_target`, `connector_mapping`, `connector_sync_event` |
| [`desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/desktop-policies.ts) | `DesktopHandoffGrantTable`, `DesktopConnectGrantTable` |
| [`telemetry.ts`](https://github.com/different-ai/openwork/blob/main/telemetry.ts) | `telemetry_event`, `telemetry_session_dimension`, `diagnostics` |

The central database client is exported from [`src/drizzle.ts`](https://github.com/different-ai/openwork/blob/main/src/drizzle.ts).

## Database Interaction Examples

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

```typescript
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`](https://github.com/different-ai/openwork/blob/main/desktop-policies.ts):

```typescript
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`](https://github.com/different-ai/openwork/blob/main/sharables/plugin-arch.ts):

```typescript
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:

- [`0001_desktop_handoff_grants.sql`](https://github.com/different-ai/openwork/blob/main/0001_desktop_handoff_grants.sql): Creates `desktop_handoff_grant` table
- [`0010_plugin_arch.sql`](https://github.com/different-ai/openwork/blob/main/0010_plugin_arch.sql): Defines `plugin`, `plugin_config_object`, and `plugin_access_grant` tables

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`](https://github.com/different-ai/openwork/blob/main/org.ts) for organization data, [`sharables/plugin-arch.ts`](https://github.com/different-ai/openwork/blob/main/sharables/plugin-arch.ts) for plugin configurations, [`connector.ts`](https://github.com/different-ai/openwork/blob/main/connector.ts) for GitHub integrations, and [`desktop-policies.ts`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/0001_desktop_handoff_grants.sql), [`0010_plugin_arch.sql`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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.