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

4.9 KiB

Secrets Demo Component

A minimal Alga PSA extension component demonstrating how to retrieve secrets from the Runner and stream debug logs using the cap:secrets.get and cap:log.emit capabilities.

What it does

This sample component:

  1. Receives an HTTP request via the Gateway
  2. Retrieves a secret named greeting from the Runner's secrets store
  3. Falls back to the string 'hello' if the secret is missing
  4. Returns a JSON response containing the message, request path, and install config
  5. Emits structured log events (log-info / log-warn) so the EE Debug Console can capture them via the Redis stream

How it works

import { get as getSecret } from 'alga:extension/secrets';
import { logInfo, logWarn } from 'alga:extension/logging';

export async function handler(request: ExecuteRequest): Promise<ExecuteResponse> {
  const method = request.http.method || 'GET';
  const url = request.http.url || '/';
  const requestId = request.context.requestId ?? 'n/a';

  logInfo(`[secrets-demo] request start requestId=${requestId} method=${method} url=${url}`);

  let message: string;
  try {
    message = await getSecret('greeting');
    logInfo('[secrets-demo] greeting secret resolved');
  } catch (error) {
    const reason = error instanceof Error ? error.message : String(error);
    logWarn(`[secrets-demo] greeting secret missing; falling back. reason=${reason}`);
    message = 'hello';
  }

  return jsonResponse({ message, path: url, config: request.context.config ?? {} });
}

The handler imports the secrets interface directly from the WIT bindings while also calling the logging interface so every request generates debug events that the Runner forwards to Redis/the EE Debug Console.

Building

Using the Alga CLI (recommended):

npm install
npm run build    # runs: alga build

Or directly with the CLI:

alga build

Build output

  • dist/main.wasm — The compiled WASM component
  • dist/js/ — Intermediate JavaScript artifacts

Packaging

npm run pack     # runs: alga pack

This creates dist/bundle.tar.zst with the manifest, WASM component, and assets.

Packaging and Publishing

Manifest

The manifest.json declares the extension metadata and handler endpoint:

{
  "name": "com.alga.sample.secrets-demo",
  "publisher": "Alga",
  "version": "0.1.0",
  "runtime": "wasm-js@1",
  "capabilities": ["cap:secrets.get", "cap:log.emit"],
  "api": {
    "endpoints": [
      { "method": "GET", "path": "/", "handler": "dist/main" }
    ]
  },
  "assets": []
}

Pack

The bundle has already been packed with:

npx alga pack . dist/bundle.tar.zst

To re-pack after changes:

export PATH="/opt/homebrew/bin:$PATH"  # Ensure zstd is in PATH (macOS)
npx alga pack . dist/bundle.tar.zst

Publish

To publish to your Alga PSA server:

export PATH="/opt/homebrew/bin:$PATH"
ALGA_ADMIN_HEADER=true npx alga publish \
  --bundle dist/bundle.tar.zst \
  --manifest manifest.json \
  --declared-hash c4a9d892a80e31c34ba6630b56044cc44d46b5171b8f9c04095e527dc0228b2b \
  --server http://localhost:3000

The published bundle will be stored at:

  • sha256/<hash>/bundle.tar.zst
  • sha256/<hash>/manifest.json

See Enterprise Build Workflow for more details.

Testing

npm test

Runs the handler tests using Vitest.

Key Concepts

Capabilities

This sample declares cap:secrets.get (to read install-scoped secrets) and cap:log.emit (to stream structured logs into the EE Debug Console).

WIT Interfaces

The component imports the secrets interface from alga:extension/secrets, which is defined in wit/extension-runner.wit. The runner provides this capability at instantiation.

Error Handling

The handler gracefully falls back to 'hello' if the secret is missing or retrieval fails. In production, you'd typically return an error response instead.

Live Debug Logging

When this component runs inside the EE environment, each log-info / log-warn call is forwarded to the Runner's Redis-backed debug stream. Use the Debug Console link on /msp/settings?tab=extensions (or go directly to /msp/extensions/<registryId>/debug) to confirm that the [secrets-demo] … messages appear in real time. Avoid logging raw secret values—this sample only logs request metadata and fallback reasons.

Next Steps

  • Add more capabilities (http.fetch, storage.kv, etc.)
  • Implement additional API endpoints
  • Add a UI with ui.iframe and the client SDK
  • See Development Guide for the full extension architecture

References