VaakLoom
Extensibility & Custom Code

External Modules & Custom Applications

Maintain non-trivial business logic, domain algorithms, or entire legacy applications in separate repositories. Load and execute them seamlessly inside VaakLoom workflows with Hub-managed runtime or your own CI/CD pipelines.

Why External Code Modules?

While low-code visual workflows excel at API routing, branching, rate-limiting, and transformations, real enterprise systems often need heavy custom logic:

  • Domain Algorithms: Proprietary scoring models, pricing engines, or risk assessment matrices.
  • Separate Lifecycles: Teams need dedicated git repositories with independent pull requests, CI/CD, and semantic versioning.
  • Multi-Function Modules: Export multiple named functions or entire service contracts from a single repository.
  • Polyglot Microservices: Existing Python, Go, Java, or Rust applications that you want to integrate via high-speed HTTP sidecars.

Three Loading Mechanisms

VaakLoom supports three distinct source protocols for loading external code into workflow steps:

1. NPM Package

npm:<package>@<version>

Loads published npm packages in-process via dynamic import(). Supports version pinning or latest resolution. Zero infrastructure overhead.

source: "npm:@acme/pricing-rules@2.1.0"
2. Git Repository

git:<url>#<ref>

References a private or public git repo by branch, tag, or commit. Private repos authenticate securely using SSH deploy keys or access tokens.

source: "git:https://github.com/acme/rules.git#v1.4"
3. HTTP Sidecar

http:<endpoint>

Invokes a customer-managed container or microservice via HTTP sidecar contract. Completely isolated process space in any programming language.

source: "http://pricing-sidecar:9090"

Runtime Management Modes

You choose how your extension runtime is managed:

  1. Hub-Managed (In-Process): The VaakLoom Hub installs, caches, and runs the module within its high-performance JavaScript runtime. Ideal for fast development with zero cloud infrastructure management.
  2. Self-Managed (Sidecar Container): You deploy the extension container on Kubernetes or your container platform. Workflows route step payloads to the sidecar over localhost or internal DNS.
  3. Custom CI/CD Webhook Integration: Configure your own external CI/CD pipeline (GitHub Actions, GitLab CI, ArgoCD, Jenkins). When your pipeline builds or tags a release, it sends a webhook to VaakLoom:
    POST /hub/extensions/:id/deploy-webhook
    Headers:
      x-webhook-secret: <YOUR_SECRET>
    Body:
      { "ref": "refs/tags/v2.0.0", "commit": "abc1234", "sender": "ci" }
    VaakLoom automatically pulls the artifact, refreshes the module in memory, and reloads active workflows with zero downtime.

Writing an Extension Module

An external extension repository exports one or more functions matching the standard step handler contract:

// src/index.ts in your custom repository
export async function calculateRisk({ input, ctx }: { input: any; ctx: any }) {
  const score = input.creditScore * 0.7 + input.annualIncome * 0.0001;
  return {
    approved: score > 650,
    riskTier: score > 750 ? "LOW" : "MEDIUM",
    computedAt: new Date().toISOString(),
  };
}

export async function validateKyc({ input, ctx }: { input: any; ctx: any }) {
  return {
    verified: Boolean(input.passportNumber && input.country),
  };
}

// Default export if called without specific operation
export default calculateRisk;

Using Extensions in Workflows

Declare the extension in your WorkflowSpec and invoke its functions using the ext:<moduleId>:<function> syntax:

{
  "version": 1,
  "id": "loan-application-workflow",
  "route": { "method": "POST", "path": "/loans/apply" },
  "extensions": [
    {
      "moduleId": "risk-engine",
      "source": "npm:@acme/risk-engine@1.2.0",
      "runtime": "hub-managed"
    }
  ],
  "nodes": [
    {
      "type": "step",
      "step": {
        "id": "step1_kyc",
        "kind": "ext:risk-engine:validateKyc",
        "inputFrom": "input"
      }
    },
    {
      "type": "step",
      "step": {
        "id": "step2_score",
        "kind": "ext:risk-engine:calculateRisk",
        "inputFrom": "input"
      }
    }
  ]
}

Per-Workflow Authentication & Custom JWT

Each workflow can define its own authentication requirements independently:

  • platform (default): Requires a Platform API key with api:invoke permission.
  • custom_jwt: Validates customer JWT tokens with signature check and arbitrary required key-value claims (e.g. role: "underwriter", iss: "https://auth.acme.com"). Claims are automatically decoded and injected into context attributes ({{attrs.jwt.sub}}, {{attrs.claims.role}}).
  • public: Completely unauthenticated public endpoint.
{
  "version": 1,
  "id": "secured-finance-api",
  "route": { "method": "POST", "path": "/finance/payout" },
  "auth": {
    "mode": "custom_jwt",
    "jwtSecret": "acme-hmac-secret-256",
    "requiredClaims": {
      "role": "financial-officer",
      "department": "treasury"
    }
  },
  "nodes": [ ... ]
}

Next: Explore the Architecture

Learn how the reactive async DAG executor, Anvesh distributed audit store, and 75% resource governor deliver resilient low-latency workflows.

Read Architecture Docs →