PSA/ee/docs/extension-system/manifest_schema.md
Hermes 284313f908
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
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

5.8 KiB
Raw Permalink Blame History

Alga PSA Extension Manifest v2

Manifest v2 is the canonical specification for the Enterprise Extension System. It defines out-of-process execution, signed content-addressed bundles, component-model runtime metadata, and iframe-only UI served by the Runner.

Manifest v2 defines signed, content-addressed bundles executed out-of-process and rendered via iframe UI.

Overview

  • File name: manifest.json inside the bundle root
  • Declares runtime, capabilities, API endpoints, and UI entry
  • Used by Registry to validate, install, and route requests

Type (abridged)

interface ManifestV2 {
  name: string;                 // reversedomain ID, e.g., "com.acme.reports"
  publisher: string;            // organization name
  version: string;              // semver
  runtime: 'wasm-js@1';         // componentize-js output (see @alga-psa/extension-runtime)
  capabilities?: string[];      // e.g., ["http.fetch","storage.kv","secrets.get"]
  ui?: {                        // iframe UI (served by Runner)
    type: 'iframe';
    entry: string;              // e.g., "ui/index.html"
    hooks?: {                   // host integration points
      appMenu?: { label: string };
      [key: string]: unknown;   // future: tabs, placeholders
    };
  };
  api?: {
    endpoints: Array<{
      method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
      path: string;             // e.g., "/agreements" or "/agreements/:id"
      handler: string;          // e.g., "dist/handlers/http/list_agreements"
    }>;
  };
  events?: Array<{             // optional event subscriptions
    topic: string;
    handler: string;
  }>;
  entry?: string;              // main wasm entry, e.g., "dist/main.wasm"
  precompiled?: Record<string, string>; // target triple → cwasm path
  assets?: string[];           // glob patterns, e.g., ["ui/**/*"]
  sbom?: string;               // optional SBOM reference
}

Example

{
  "name": "com.alga.softwareone",
  "publisher": "SoftwareOne",
  "version": "1.2.3",
  "runtime": "wasm-js@1",
  "capabilities": ["http.fetch", "storage.kv", "secrets.get"],
  "ui": {
    "type": "iframe",
    "entry": "ui/index.html",
    "hooks": { "appMenu": { "label": "Agreements" } }
  },
  "api": {
    "endpoints": [
      { "method": "GET", "path": "/agreements", "handler": "dist/handlers/http/list_agreements" },
      { "method": "POST", "path": "/agreements/sync", "handler": "dist/handlers/http/sync" }
    ]
  },
  "precompiled": {
    "x86_64-linux-gnu": "artifacts/cwasm/x86_64-linux-gnu/main.cwasm",
    "aarch64-linux-gnu": "artifacts/cwasm/aarch64-linux-gnu/main.cwasm"
  },
  "assets": ["ui/**/*"],
  "sbom": "sbom.spdx.json"
}

Validation Rules

  • name: reversedomain, lowercase alphanumeric, dots, hyphens; unique per registry
  • version: semver
  • runtime: currently wasm-js@1 (componentized handlers)
  • api.endpoints: optional; when present use unique method+path pairs; paths must start with /; currently advisory (not enforced by gateway)
  • ui.entry must exist in the bundle; manifest-level entry field is not used by the current runtime
  • ui.hooks.appMenu.label must be a non-empty string when present
  • capabilities: optional array (defaults to empty); must be recognized by the platform; leastprivilege encouraged
  • assets: glob patterns limited to static files; no hidden files by default

Signing & Provenance

  • Bundles are contentaddressed using SHA256 and signed (e.g., sha256:<hex>).
  • Registry records content_hash, signature, and publisher certificate/keys.
  • Signature verification occurs on publish/install and on load.

See Security & Signing.

Routing & Execution

  • Gateway maps /api/ext/[extensionId]/[[...path]] requests to tenant installs. Endpoint metadata from the manifest is surfaced to operators today; strict enforcement is not enabled (see 2025-11-12 plan).
  • Gateway normalizes the request and calls Runner POST /v1/execute with {context, http, limits, config, providers, secret_envelope}.
  • Runner executes the handler under isolation and returns {status, headers, body_b64} to the Gateway.

See API Routing Guide.

Install Metadata (Config, Providers, Secrets)

Manifest v2 describes the bundle. Tenant-specific configuration is stored separately:

  • tenant_extension_install_config persists per-tenant config maps and provider grants (capability enablement).
  • tenant_extension_install_secrets stores sealed envelopes (Vault transit or inline) that the Runner decrypts on demand.
  • The gateway attaches config, providers, and secret_envelope to each Runner call so host capabilities (storage/http/secrets/ui_proxy) can enforce policy.

Plan dependencies and outstanding gaps are documented in 2025-11-12-extension-system-alignment-plan.

UI Delivery

  • UI is served by the Runner at ${RUNNER_PUBLIC_BASE}/ext-ui/{extensionId}/{content_hash}/[...] (immutable). The Next.js ext-ui route is a gate/redirect when rust-host mode is enabled.
  • The host constructs iframe URLs via buildExtUiSrc() and performs secure bootstrap via bootstrapIframe().
  • No in-process UI rendering and no dynamic import of tenant code in the host.