dwctl 0.4.2

The Doubleword Control Layer - A self-hostable observability and analytics platform for LLM applications
# Control Layer API Server (dwctl)

Rust-based API server for user, group, and model management with PostgreSQL database.

## Local Development Setup

### Prerequisites

- Rust (latest stable)
- PostgreSQL running locally
- sqlx-cli: `cargo install sqlx-cli`

### 1. Database Setup

```bash
# Start PostgreSQL (macOS with Homebrew)
brew services start postgresql

# Create database
createdb control_layer

# Or connect to existing PostgreSQL instance
psql -c "CREATE DATABASE control_layer;"
```

### 2. Environment Configuration

Create `.env` file in the `dwctl` directory:

```bash
# dwctl/.env
DATABASE_URL=postgres://your-username@localhost:5432/control_layer
```

Replace `your-username` with your PostgreSQL username.

### 3. Run Database Migrations

```bash
cd dwctl
sqlx migrate run
```

### 4. Generate Query Cache (for builds without database)

```bash
# Generate offline query cache
cargo sqlx prepare

# This creates .sqlx/ directory with cached query metadata
```

## Running the Service

```bash
cd dwctl

# Run with live database connection
cargo run

# Run tests (requires database)
cargo test
```

## Configuration

The service uses `config.yaml` (or `DWCTL_*` environment variables):

- `DWCTL_HOST`: Server host (default: 0.0.0.0)
- `DWCTL_PORT`: Server port (default: 3001)
- `DATABASE_URL`: PostgreSQL connection string

## User Roles and Permissions

Control Layer uses an additive role-based access control system where users can have multiple roles that combine to provide different levels of access.

### Role Types

#### StandardUser (Base Role)
- **Required for all users** - Cannot be removed
- Enables basic authentication and login functionality
- Provides access to user's own profile and data
- Allows model access, API key creation, and playground usage
- Foundation role that all other roles build upon

#### PlatformManager
- **Administrative access** to most platform functionality
- Can create, update, and delete users
- Can manage groups and group memberships
- Can control access to models and manage inference endpoints
- Can configure system settings
- **Cannot** view private request data (requires RequestViewer)

#### RequestViewer
- **Read-only access** to request logs and analytics
- Can view all requests that have transited the gateway
- Useful for auditing, monitoring, and analytics purposes
- Often combined with other roles for full administrative access

### Role Combinations

Roles are additive, meaning users gain the combined permissions of all their assigned roles:

- **StandardUser only**: Basic user with profile access and model usage
- **StandardUser + PlatformManager**: Full administrative access except request viewing
- **StandardUser + RequestViewer**: Basic user who can also view request logs
- **StandardUser + PlatformManager + RequestViewer**: Full system administrator with all permissions

### Role Management

- All users automatically receive and retain the `StandardUser` role
- Additional roles can be assigned/removed via the admin interface
- The system automatically ensures `StandardUser` is preserved during role updates
- Role changes take effect immediately without requiring user re-authentication, unless using native auth with jwts, whereby a user needs to logout and back for API access effects to take place

## Troubleshooting

**Database connection errors**

- Ensure PostgreSQL is running: `brew services start postgresql`
- Check DATABASE_URL in `.env` file
- Verify database exists: `psql -l | grep control_layer`

**Migration errors**

```bash
# Reset database
sqlx database reset # add `-y` to skip confirmation and `-f` if you get a
                    # 'other user are connected' error (usually your IDE is also connected)
```

## Database Schema

Migrations are stored in the `migrations/` directory, and run automatically on startup.

- `001_initial.sql` - Users, groups, models tables
- `002_listen_notify.sql` - PostgreSQL notify triggers
- `003_make_hosted_on_not_null.sql` - Schema updates

## API Endpoints

- See OpenAPI docs at `/admin/docs` when running