What Is OpenWork Den? Understanding the Organization Control Plane for Teams, Skills, and Plugins

OpenWork Den is the control-plane backend that governs every organization-wide operation in OpenWork, running as a Hono-based HTTP service with a companion web UI to centrally manage authentication, teams, policies, and plugin marketplace access.

OpenWork Den serves as the single source of truth for enterprise deployment of the OpenWork platform. Built as a modular stack comprising the Den API and Den Web console, it coordinates how organizations provision users, distribute AI skills, and enforce security policies across desktop clients and agent runtimes. This article examines how Den implements organization control plane functionality—from team hierarchy management to plugin access grants—based on the source code in the different-ai/openwork repository.

How OpenWork Den Architecture Implements the Control Plane

The Den stack separates concerns across two main deliverables: a lightweight API layer and an administrative web interface.

Component Implementation Responsibility
Den API Hono HTTP framework (ee/apps/den-api/) REST endpoints for auth, org management, policies, and marketplace
Den Web Companion admin UI (ee/apps/den-web/) Browser-based console for bulk operations and visualization
den-db Drizzle ORM + MySQL (ee/packages/den-db/) Persistence layer for org, team, and plugin schemas

This architecture lets operators run Den as a centralized service while agents and desktop clients consume it via standard HTTP calls.

Authentication and Session Management in Den

Den delegates authentication to Better Auth, wrapping its routes under /api/auth/* as documented in the Den API README.


┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Desktop App │────▶│  Den API    │────▶│ Better Auth │
│   or Agent  │     │ /api/auth/* │     │   (OAuth,   │
│             │◀────│  (wraps)    │◀────│  SAML, etc) │
└─────────────┘     └─────────────┘     └─────────────┘
         │
         ▼
    Signed session cookie
    (used for subsequent calls)

The middleware layer validates this session on every protected endpoint, extracting the caller's organization context before allowing operations to proceed.

Organization and Team Management

Den stores organizational hierarchy in MySQL tables defined in [ee/packages/den-db/src/schema/teams.ts](https://github.com/different-ai/openwork/blob/main/ee/packages/den-db/src/schema/teams.ts).

The schema enforces three key constraints:

  • team table: Unique names scoped to each organization (org_id + name composite unique key)
  • team_member table: Many-to-many linking users to teams with role annotations
  • Organization isolation: Every query filters by org_id to prevent cross-tenant data leakage

# Seed a demo organization with teams and members

pnpm --filter @openwork-ee/den-api seed:demo-org

This command creates "Acme Robotics" with sample users, teams, and membership links, demonstrating how Den structures multi-team enterprises.

Policy Enforcement and Access Control

The organization control plane applies governance through dedicated policy tables:

Policy Type Storage Location Enforcement Point
Desktop policies desktop_policy table Client configuration fetch
SSO providers sso_provider table Authentication routing
SCIM provisioning SCIM-related tables User lifecycle management

Middleware documented in the Den API README validates the caller's scope—org, team, or individual user—before permitting mutations.

Policy definitions themselves live in [packages/types/src/den/desktop-policies.ts](https://github.com/different-ai/openwork/blob/main/packages/types/src/den/desktop-policies.ts), where TypeScript interfaces specify which model providers, update channels, and feature flags an organization permits.


# Query desktop policy for an organization

curl "http://localhost:8790/v1/policies/desktop?orgId=org_abcdef1234567890" | jq .

The Marketplace Model: Managing Skills and Plugins

Den implements plugin distribution through a Marketplace abstraction with granular access grants. The core schema in [ee/packages/den-db/src/schema/sharables/plugin-arch.ts](https://github.com/different-ai/openwork/blob/main/ee/packages/den-db/src/schema/sharables/plugin-arch.ts) defines:

  • plugin table: Registered skills and extensions with metadata
  • plugin_access_grant table: Permission links scoped to org, team, or individual member

Grant scoping follows a hierarchy: organization-wide grants apply to all teams and members, while team-specific or user-specific grants override with finer precision.

Publishing and Assigning Plugins

Administrators interact with plugins through REST endpoints:


# List all plugins available to the authenticated organization

curl -H "Cookie: <session-cookie>" \
  http://localhost:8790/v1/marketplace/plugins | jq .

Granting access requires a POST to the plugin access grants endpoint:

curl -X POST http://localhost:8790/v1/marketplace/plugin-access-grants \
  -H "Content-Type: application/json" \
  -d '{
        "pluginId": "plg_abcdef1234567890",
        "teamId": "team_1234567890abcdef",
        "role": "editor"
      }' | jq .

The role field supports permission levels (viewer, editor, admin) that downstream clients enforce when executing plugin functionality.

The Client Control Plane Flow

Every OpenWork desktop session or agent initialization follows a five-step enrollment against Den:

  1. Authenticate — Exchange credentials for signed session via Better Auth
  2. Resolve organization — GET /v1/me/org returns active org context
  3. Load policy bundle — Desktop policies, allowed models, and constraints
  4. Fetch marketplace catalog — Filtered to granted plugins for this user/team/org
  5. Enforce access — Middleware validates grants on every subsequent API call

This flow ensures continuous central governance: clients cache policies and catalogs locally but must revalidate with Den for mutations or periodic refresh.

Observability and Security Hardening

Den includes production-hardened observability:

  • OTEL/Sentry integration — Request tracing and error aggregation (configurable backends)
  • Credential redaction — Sensitive fields filtered from logs before persistence
  • SSRF protection — Network-level guards against server-side request forgery

Configuration details appear in the Den API README observability section.

Running OpenWork Den Locally

The standard development workflow brings up all components:


# Terminal 1: Start the Den API on :8790

pnpm --filter @openwork-ee/den-api dev:local

# Terminal 2: Start the admin web UI on :3005

pnpm --filter @openwork-ee/den-web dev:local

These commands launch the full control plane stack for local testing and plugin development.

Summary

  • OpenWork Den is the Hono-based control plane that centralizes organization management for the OpenWork platform
  • Team hierarchy enforces org-scoped isolation via MySQL schemas in teams.ts
  • Plugin marketplace uses granular access grants (plugin_access_grant) to distribute skills across org, team, or user scopes
  • Policy enforcement combines middleware validation with typed policy definitions for desktop clients
  • Better Auth integration provides pluggable authentication while Den manages authorization and session state

Frequently Asked Questions

How does Den prevent unauthorized cross-organization access?

Den middleware validates the session's org_id claim against the requested resource on every operation. Database queries include mandatory org_id filters, and unique constraints prevent name collisions between organizations rather than allowing data leakage.

What authentication methods does OpenWork Den support?

Den wraps Better Auth, which supports OAuth 2.0, OpenID Connect, SAML, and password-based flows. Additional SSO providers integrate through the sso_provider table and associated configuration, as noted in the Den API middleware documentation.

Can plugins be restricted to specific teams within an organization?

Yes. The plugin_access_grant table accepts org_id, team_id, or member_id scope fields, allowing administrators to publish organization-wide defaults while restricting sensitive plugins to specific teams or individual power users.

How do desktop clients receive policy updates from Den?

Clients fetch the active policy bundle during initialization via GET /v1/policies/desktop and cache it locally. Den can signal policy changes through session refresh or version-stamped configurations, with the client re-querying on context switches or periodic refresh intervals.

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 →