#238 Implement default app bootstrap system for multi-tenant deployment

open high apps bootstrap multi-tenant Created 2025-12-02 19:02 · Updated 2025-12-02 19:02

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 All
Loading audit history...