Upgrading from v2.3.0 or earlier: existing single admin key will be automatically migrated to the new multi-key format with admin role. No manual migration required.
Breaking changes
WebSocket endpoint /api/ws/activity now requires authentication via ?key= query parameter — previously listed in PublicPaths and accessible without credentials. Unauthenticated WebSocket clients will be rejected.
Scope checks now validate the requesting key specifically rather than any key in the store. Agent keys that previously bypassed scope restrictions due to the HasScope() bug will now be correctly denied.
Security fixes
[P0] Compose Path Traversal — /api/marketplace/start accepted an arbitrary compose_path and passed it directly to docker compose -f, allowing host filesystem access. Fixed: path now validated with filepath.Abs + strings.HasPrefix to enforce /app/data/containers/ prefix.
[P0] Scope Check Bypass — All 9 scope checks in server.go called keyStore.HasScope(), which checked if any key in the store had the scope, not the requesting key. Agent keys with no permissions could act with admin privileges. Fixed: changed to auth.KeyStoreHasScope(meta, scope) to validate the specific requesting key.
[P1] Unauthenticated WebSocket — /api/ws/activity was in PublicPaths, allowing unauthenticated network access to container activity events. Fixed: removed from public paths, added ?key= query parameter authentication.
Notable features
Admin and Agent roles — admin keys can manage other keys; agent keys are restricted to their assigned scopes with no escalation path
Key Management API — GET/POST/DELETE /api/keys for programmatic key lifecycle management
Key Management UI in Settings — create agent keys with custom scopes, revoke keys, view role badges
Final release capturing the legacy WAGMIOS API state with single-key authentication and original endpoint structure. Deprecated in favor of v2.3.0 which introduces granular scoped permissions and agent-safe API design.