#238 Implement default app bootstrap system for multi-tenant deployment
Description
Edit## Overview
Highway needs a bootstrap system that pre-installs a curated set of apps for all tenants. These apps should be available in **disabled** mode by default, allowing tenant admins to enable them as needed.
## Current State
- Apps are registered in `highway.apps` and `highway.app_versions` tables
- Per-tenant installations tracked in `highway.tenant_app_installations`
- Apps resolved dynamically at workflow execution time via `AppToolBridge`
- No mechanism to auto-install apps for new tenants
- No concept of "system" vs "marketplace" apps
## Requirements
### 1. App Classification System
Add classification to distinguish app types:
| Type | Description | Can Uninstall | Auto-Install |
|------|-------------|---------------|--------------|
| `system` | Core Highway apps (logging, http, etc.) | No | Yes (disabled) |
| `default` | Recommended integrations | Yes | Yes (disabled) |
| `marketplace` | On-demand installations | Yes | No |
**Schema change:**
```sql
ALTER TABLE highway.apps ADD COLUMN app_type VARCHAR(20) DEFAULT 'marketplace';
-- Values: 'system', 'default', 'marketplace'
```
### 2. Default Apps Registry
Create bootstrap configuration defining default apps:
```python
# engine/apps/defaults.py
DEFAULT_APPS = {
'system': [
'http', # HTTP/webhook calls
'logging', # Structured logging
'notifications', # Internal notifications
],
'default': [
'slack', # Slack integration
'email', # Email sending
'github', # GitHub integration
'jira', # Jira integration
's3', # S3 storage
'ai', # LLM/AI tools
],
}
```
### 3. Bootstrap Command
New CLI command to initialize apps:
```bash
# Initial bootstrap (run once during deployment)
hwe apps bootstrap
# Sync new default apps to existing tenants
hwe apps sync-defaults --tenant all
hwe apps sync-defaults --tenant <tenant_id>
# List default apps
hwe apps list-defaults
```
### 4. Tenant Creation Hook
When a new tenant is created via API:
1. Query all apps where `app_type IN ('system', 'default')`
2. Create `tenant_app_installations` records with `status = 'disabled'`
3. Log audit event for compliance
**Modify:** `api/blueprints/v1/tenants.py` - tenant creation endpoint
### 5. App Installation States
Extend installation status:
| Status | Description |
|--------|-------------|
| `disabled` | Installed but not active (default for bootstrap) |
| `enabled` | Active and usable in workflows |
| `pending_config` | Needs OAuth/credentials before enabling |
| `suspended` | Admin-disabled (for system apps) |
### 6. Database Migration
```sql
-- Migration: Add app_type and update installation states
ALTER TABLE highway.apps
ADD COLUMN app_type VARCHAR(20) DEFAULT 'marketplace',
ADD COLUMN is_configurable BOOLEAN DEFAULT true,
ADD COLUMN required_scopes JSONB DEFAULT '[]';
-- Add constraint
ALTER TABLE highway.apps
ADD CONSTRAINT apps_type_check
CHECK (app_type IN ('system', 'default', 'marketplace'));
-- Update installation status enum
-- (if using enum, otherwise just document valid values)
```
### 7. Bootstrap Process Flow
```
┌─────────────────────────────────────────────────────────────┐
│ hwe apps bootstrap │
├─────────────────────────────────────────────────────────────┤
│ 1. Load DEFAULT_APPS configuration │
│ 2. For each app in system + default: │
│ a. Check if app exists in highway.apps │
│ b. If not, register app + version from bundled manifest │
│ c. Set app_type appropriately │
│ 3. For each existing tenant: │
│ a. Check tenant_app_installations │
│ b. Install missing default apps (status=disabled) │
│ 4. Log summary │
└─────────────────────────────────────────────────────────────┘
```
### 8. API Endpoints
**New/Modified endpoints:**
```
GET /api/v1/apps/defaults # List default apps (public)
POST /api/v1/apps/sync-defaults # Admin: sync defaults to tenants
GET /api/v1/tenant/apps # List tenant's apps (include disabled)
POST /api/v1/tenant/apps/{app}/enable # Enable an app
POST /api/v1/tenant/apps/{app}/disable # Disable an app
```
### 9. App Manifest Structure
Each bundled app needs a manifest:
```yaml
# engine/apps/manifests/slack.yaml
name: slack
display_name: Slack
description: Send messages and notifications to Slack channels
category: communication
app_type: default
version: 1.0.0
requires_oauth: true
oauth_provider: slack
actions:
send_message:
description: Send a message to a channel
parameters:
channel: {type: string, required: true}
message: {type: string, required: true}
returns:
ts: {type: string, description: Message timestamp}
send_blocks:
description: Send rich Block Kit message
parameters:
channel: {type: string, required: true}
blocks: {type: array, required: true}
```
### 10. Upgrade Path for Existing Deployments
When Highway is upgraded and new default apps are added:
1. Migration detects new apps in DEFAULT_APPS
2. Registers new apps in `highway.apps`
3. Does NOT auto-install for existing tenants (breaking change risk)
4. Admin runs `hwe apps sync-defaults` to propagate
5. Or: add `--auto-sync` flag to migration for CI/CD pipelines
### 11. RBAC Considerations
| Action | Required Permission |
|--------|---------------------|
| View available apps | `view_apps` |
| Enable/disable app | `manage_apps` |
| Configure app (OAuth) | `manage_apps` + `manage_integrations` |
| Uninstall default app | `manage_apps` (not allowed for system) |
| Run bootstrap command | System admin (CLI only) |
### 12. Audit Logging
All app state changes must be logged:
```json
{
"event_type": "app_state_change",
"tenant_id": "acme",
"app_name": "slack",
"previous_state": "disabled",
"new_state": "enabled",
"changed_by": "user@acme.com",
"timestamp": "2025-12-02T18:30:00Z"
}
```
## Implementation Phases
### Phase 1: Schema & Core (Priority: High)
- [ ] Add `app_type` column to `highway.apps`
- [ ] Create `engine/apps/defaults.py` with DEFAULT_APPS
- [ ] Create app manifest YAML structure
- [ ] Bundle 2-3 system apps (http, logging)
### Phase 2: Bootstrap Command (Priority: High)
- [ ] Implement `hwe apps bootstrap` CLI command
- [ ] Implement `hwe apps sync-defaults` CLI command
- [ ] Add bootstrap to deployment checklist
### Phase 3: Tenant Hook (Priority: Medium)
- [ ] Modify tenant creation to auto-install defaults
- [ ] Add `pending_config` status for OAuth apps
- [ ] Update tenant apps API to show disabled apps
### Phase 4: Default Apps Bundle (Priority: Medium)
- [ ] Create manifests for: slack, email, github, jira, s3, ai
- [ ] Implement OAuth flow stubs for each
- [ ] Write integration tests
### Phase 5: Admin UI (Priority: Low)
- [ ] App marketplace view
- [ ] Enable/disable toggles
- [ ] OAuth configuration wizard
## Testing Strategy
1. **Unit tests:** Bootstrap logic, manifest parsing
2. **Integration tests:**
- New tenant gets default apps (disabled)
- Enable/disable flow works
- System apps cannot be uninstalled
3. **Migration tests:** Upgrade path works for existing data
## Files to Modify/Create
- `engine/apps/defaults.py` (new)
- `engine/apps/manifests/*.yaml` (new)
- `engine/apps/bootstrap.py` (new)
- `engine/cli/apps.py` (new CLI commands)
- `engine/migrations/XXXX_add_app_types.sql` (new)
- `api/blueprints/v1/tenant_apps.py` (modify)
- `api/blueprints/v1/tenants.py` (modify - creation hook)
## Dependencies
- Issue #195: App system foundation
- Issue #204: Tool bridge integration
## Acceptance Criteria
1. Running `hwe apps bootstrap` registers all default apps
2. New tenants automatically have default apps installed (disabled)
3. Tenant admins can enable apps via API
4. System apps cannot be uninstalled
5. `hwe apps sync-defaults` propagates new apps to existing tenants
6. All state changes are audit logged
Comments
Loading comments...
Context
Loading context...
Audit History
View AllLoading audit history...