Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
107 lines
7.9 KiB
Markdown
107 lines
7.9 KiB
Markdown
# Alga PSA Extension System (Enterprise Overview)
|
|
|
|
This document specifies the Enterprise Edition (EE) extension architecture. It is a v2-only system featuring out-of-process execution, content-addressed signed bundles, a component-model Runner that executes `componentize-js` artifacts, and iframe-only UI delivery served by the Runner.
|
|
|
|
## Goals
|
|
- No tenant code executes in the core app process
|
|
- Per-tenant isolation across compute, storage, and egress
|
|
- Signed, content-addressed bundles with verified provenance (sha256:…)
|
|
- Capability-based host APIs, quotas, and auditable execution
|
|
|
|
## Architecture
|
|
|
|
1) Runner Service (Rust + Wasmtime)
|
|
- Executes extension handlers as Wasmtime **components** generated via `componentize-js` + `@alga-psa/extension-runtime`
|
|
- Enforces memory/time/concurrency limits
|
|
- Exposes a minimal set of namespaced host APIs (alga.*) for storage, http, secrets, logging, and metrics
|
|
- Provides additional capability providers (e.g., ui proxy) based on install-scoped grants
|
|
- Hosts static UI assets for iframe delivery at ${RUNNER_PUBLIC_BASE}/ext-ui/{extensionId}/{content_hash}/[...]
|
|
|
|
2) Registry & Bundles
|
|
- Registry stores extensions, versions, and metadata (content_hash, signature, runtime) plus tenant install configuration (`tenant_extension_install_config`) and sealed secret envelopes (`tenant_extension_install_secrets`)
|
|
- Bundles are immutable, content-addressed artifacts in object storage
|
|
- Signatures are verified on publish/install and on load, against a configured trust bundle
|
|
|
|
3) API Gateway (Next.js)
|
|
- Route: `/api/ext/[extensionId]/[[...path]]`
|
|
- Resolves tenant install via [installConfig](../../../server/src/lib/extensions/installConfig.ts) → version/content hash → config + provider grants → secret envelope
|
|
- Proxies requests to Runner `POST /v1/execute` with strict header/size/time policies and quotas, attaching `config`, `providers`, and `secret_envelope` in the body
|
|
- Reference scaffold: [server/src/app/api/ext/[extensionId]/[[...path]]/route.ts](../../../server/src/app/api/ext/%5BextensionId%5D/%5B%5B...path%5D%5D/route.ts)
|
|
- Manifest endpoint matching is **not enforced** today; it is advisory. Enforcement decision is tracked in [2025-11-12 plan](../plans/2025-11-12-extension-system-alignment-plan.md#workstream-a-%E2%80%94-gateway--registry).
|
|
|
|
4) UI Delivery (Iframe-Only, served by Runner)
|
|
- Static UI assets are served by the Runner at ${RUNNER_PUBLIC_BASE}/ext-ui/{extensionId}/{content_hash}/[...]; the Next.js `ext-ui` route only gates/redirects when rust-host mode is enabled.
|
|
- The host constructs the iframe src via [buildExtUiSrc()](../../../server/src/lib/extensions/ui/iframeBridge.ts:38) and bootstraps via [bootstrapIframe()](../../../server/src/lib/extensions/ui/iframeBridge.ts:45)
|
|
- Client SDK (@alga/extension-iframe-sdk) provides auth, navigation bridge, and theme token integration
|
|
- UI kit (@alga/ui-kit) offers accessible, themed components
|
|
|
|
5) Observability & Policy
|
|
- Structured execution logs correlated to requests/events
|
|
- Prometheus metrics (duration, memory, fuel, egress bytes, errors)
|
|
- Per-tenant/per-extension quotas and egress allowlists
|
|
|
|
## Data Model (Initial)
|
|
- extension_registry, extension_version, extension_bundle
|
|
- tenant_extension_install, extension_event_subscription
|
|
- extension_execution_log, extension_quota_usage
|
|
|
|
## Request Flow (HTTP)
|
|
1. Client calls `/api/ext/{extensionId}/{...}` in the host app (iframe or API consumer).
|
|
2. Gateway resolves the tenant install config (content hash, version, providers, config map, sealed secret envelope).
|
|
3. Gateway filters headers/body, assembles `{context, http, limits, config, providers, secret_envelope}`, and calls Runner `POST /v1/execute`.
|
|
4. Runner fetches/verifies the component by `content_hash`, decrypts secrets when permitted, executes the handler, and returns `{status, headers, body_b64}`.
|
|
5. Gateway maps the response to the client with header allowlists and optional config/secrets version headers.
|
|
|
|
## Manifest v2 Summary
|
|
Manifest v2 is the canonical specification for extensions:
|
|
- runtime: e.g., `wasm-js@1` (the `componentize-js` pipeline output)
|
|
- capabilities: least-privilege host APIs requested (storage, http, secrets, etc.)
|
|
- api.endpoints: declare HTTP entrypoints (used for docs/UX today; enforcement work tracked in [Plan A4](../plans/2025-11-12-extension-system-alignment-plan.md))
|
|
- ui.iframe: iframe entry HTML and asset mapping; UI is served by Runner using content-addressed paths
|
|
- ui.hooks: host integration points such as adding menu entries that launch a full-page iframe; designed to expand for tabs and named placeholders
|
|
- precompiled and assets: bundle metadata including sha256 content hash and signatures
|
|
|
|
See full schema: [manifest_schema.md](manifest_schema.md)
|
|
|
|
## Security Highlights
|
|
- No dynamic importing of tenant JS into the host
|
|
- Capability-based host API; deny-by-default egress
|
|
- Signature verification and content hashing across the bundle lifecycle
|
|
- Iframe sandboxing and origin validation aligned with RUNNER_PUBLIC_BASE
|
|
|
|
## Runner: responsibilities and integration
|
|
The Runner is the execution and static asset host for the EE architecture:
|
|
- Executes WASM components out-of-process with isolation and quotas (Rust + Wasmtime Component APIs)
|
|
- Hosts static UI assets by immutable content hash; the host builds iframe src via [buildExtUiSrc()](../../server/src/lib/extensions/ui/iframeBridge.ts:38) and initializes via [bootstrapIframe()](../../server/src/lib/extensions/ui/iframeBridge.ts:45)
|
|
- Provides HTTP interface for handler execution (`POST /v1/execute`) called by the API Gateway. Gateway scaffold: [server/src/app/api/ext/[extensionId]/[[...path]]/route.ts](../../../server/src/app/api/ext/%5BextensionId%5D/%5B%5B...path%5D%5D/route.ts)
|
|
- Implements host capabilities including HTTP egress, storage KV, secrets, logging, metrics, and the UI proxy (`alga.ui_proxy`) with enforcement driven by install-level providers.
|
|
- Emits live debug events to Redis Streams when `RUNNER_DEBUG_REDIS_URL` is configured; EE consumes these via `/api/ext-debug/stream`.
|
|
- Signature and provenance enforcement integrate with Registry v2 services. Registry scaffold: [ExtensionRegistryServiceV2](../../server/src/lib/extensions/registry-v2.ts:48)
|
|
|
|
Runner-related configuration (host environment):
|
|
- `RUNNER_BASE_URL`: internal URL used by the Gateway to call POST /v1/execute
|
|
- `RUNNER_PUBLIC_BASE`: public base used to construct ext-ui iframe src
|
|
- `EXT_GATEWAY_TIMEOUT_MS`: gateway → runner request timeout
|
|
- `SIGNING_TRUST_BUNDLE`: path or inline bundle of trusted public keys/certificates for signature verification
|
|
- `RUNNER_DEBUG_REDIS_URL`, `RUNNER_DEBUG_REDIS_STREAM_PREFIX`, `RUNNER_DEBUG_REDIS_MAXLEN`: enable Redis-backed debug streaming
|
|
- `UI_PROXY_BASE_URL`, `UI_PROXY_AUTH_KEY`, `UI_PROXY_TIMEOUT_MS`: configure the runner-side UI proxy capability
|
|
|
|
See detailed Runner doc: [runner.md](runner.md)
|
|
|
|
## Endpoint and UI delivery correctness
|
|
- All extension API calls traverse `/api/ext/[extensionId]/[[...path]]` and are proxied to Runner `/v1/execute`. Enforcement of manifest endpoint lists is TBD (see [plan](../plans/2025-11-12-extension-system-alignment-plan.md)).
|
|
- UI assets are served by Runner only, at ${RUNNER_PUBLIC_BASE}/ext-ui/{extensionId}/{content_hash}/[...]; there is no Next.js route for ext-ui
|
|
|
|
## Live Debugging
|
|
- Runner emits structured `ExtDebugEvent` entries (stdout/stderr/log) into Redis Streams when debug streaming is enabled.
|
|
- EE exposes `/api/ext-debug/stream` (Server-Sent Events) and a UI at `/msp/extensions/[extensionId]/debug` to authorized tenant operators.
|
|
- Capability gating, session TTLs, and audit logging are tracked in [Workstream B](../plans/2025-11-12-extension-system-alignment-plan.md#workstream-b-%E2%80%94-runner--debug-stream).
|
|
|
|
## References
|
|
- [Implementation Plan](implementation_plan.md)
|
|
- [Manifest v2](manifest_schema.md)
|
|
- [API Routing Guide](api-routing-guide.md)
|
|
- [Security & Signing](security_signing.md)
|
|
- [Development Guide](development_guide.md)
|
|
- [Runner Service](runner.md)
|