PanOS Docs

Multi-Context Integration Recipes

Practical implementation recipes for integrating PanOS with web apps, services, edge jobs, CI pipelines, and embedded systems

Multi-Context Integration Recipes

This guide provides concrete recipes you can adapt directly.

Each recipe includes:

  • Context and target
  • Minimal architecture
  • Code sample
  • Validation strategy

Recipe A — API Runtime for Internal Tooling

Context

You need a lightweight internal API where reproducible startup matters more than horizontal complexity.

Minimal Architecture

Admin UI -> HTTP API (PanOS guest) -> Local JSON state

Implementation

// /app/internal-api.js
import http from "node:http";
import { readFile, writeFile } from "node:fs/promises";

const dbPath = "/tmp/state.json";

async function loadState() {
  try {
    return JSON.parse(await readFile(dbPath, "utf8"));
  } catch {
    return { tickets: [] };
  }
}

async function saveState(state) {
  await writeFile(dbPath, JSON.stringify(state, null, 2));
}

http
  .createServer(async (req, res) => {
    if (req.method === "GET" && req.url === "/tickets") {
      const state = await loadState();
      res.writeHead(200, { "content-type": "application/json" });
      res.end(JSON.stringify(state.tickets));
      return;
    }

    if (req.method === "POST" && req.url === "/tickets") {
      let body = "";
      req.on("data", (chunk) => (body += chunk));
      req.on("end", async () => {
        const payload = JSON.parse(body || "{}");
        const state = await loadState();
        const ticket = { id: crypto.randomUUID(), ...payload };
        state.tickets.push(ticket);
        await saveState(state);
        res.writeHead(201, { "content-type": "application/json" });
        res.end(JSON.stringify(ticket));
      });
      return;
    }

    res.writeHead(404);
    res.end("not found");
  })
  .listen(8080, () => {
    console.log("internal-api-ready");
  });

Validation

curl -s http://127.0.0.1:8080/tickets
curl -s -X POST http://127.0.0.1:8080/tickets -d '{"title":"Boot issue"}'

Recipe B — Frontend + Runtime Bridge

Context

Your web app needs host diagnostics from PanOS runtime without exposing full system internals.

Backend Bridge

// /app/bridge.js
import http from "node:http";
import os from "node:os";

http
  .createServer((req, res) => {
    if (req.url === "/v1/diagnostics") {
      res.writeHead(200, { "content-type": "application/json" });
      res.end(
        JSON.stringify({
          node: process.version,
          cpus: os.cpus().length,
          loadavg: os.loadavg(),
          uptime: process.uptime(),
        })
      );
      return;
    }

    res.writeHead(404);
    res.end();
  })
  .listen(8090);

Frontend Client

// web/src/features/runtime/getDiagnostics.ts
export type RuntimeDiagnostics = {
  node: string;
  cpus: number;
  loadavg: [number, number, number];
  uptime: number;
};

export async function getDiagnostics(apiBase: string): Promise<RuntimeDiagnostics> {
  const response = await fetch(`${apiBase}/v1/diagnostics`, {
    headers: { accept: "application/json" },
  });

  if (!response.ok) {
    throw new Error(`Diagnostics request failed: ${response.status}`);
  }

  return response.json();
}

Recipe C — Batch Worker with Artifact Output

Context

You need deterministic batch processing and file artifact output from runtime jobs.

Worker

// /app/batch.js
import { readFile, writeFile } from "node:fs/promises";

const inPath = process.env.INPUT_FILE ?? "/tmp/input.ndjson";
const outPath = process.env.OUTPUT_FILE ?? "/tmp/report.json";

const lines = (await readFile(inPath, "utf8")).trim().split("\n");
const events = lines.map((line) => JSON.parse(line));

const byType = events.reduce((acc, event) => {
  acc[event.type] = (acc[event.type] ?? 0) + 1;
  return acc;
}, {});

const report = {
  generatedAt: new Date().toISOString(),
  total: events.length,
  byType,
};

await writeFile(outPath, JSON.stringify(report, null, 2));
console.log("report-ready", outPath);

Recipe D — CI Smoke Boot + API Assertion

Context

You want to fail CI early if runtime boot or API behavior changes unexpectedly.

Pipeline Script

#!/usr/bin/env bash
set -euo pipefail

./1-build.sh

timeout 80s ./2-run.sh > /tmp/boot.log 2>&1 || true

if ! grep -q "Shell Ready" /tmp/boot.log; then
  echo "PanOS failed to boot"
  cat /tmp/boot.log
  exit 1
fi

echo "PanOS boot smoke passed"

Optional Runtime API Contract Test

// tools/assert-runtime-contract.mjs
import assert from "node:assert/strict";

const response = await fetch("http://127.0.0.1:8080/runtime");
assert.equal(response.status, 200);

const body = await response.json();
assert.equal(typeof body.node, "string");
assert.equal(typeof body.uptimeSec, "number");

console.log("runtime-contract-ok");

Recipe E — Embedded Gateway Loop

Context

You need a protocol bridge from local hardware reads to upstream cloud publishing.

Pattern

sensor read -> normalize -> buffer -> publish -> ack -> rotate logs

Gateway Core

// /app/gateway-core.js
import { appendFile } from "node:fs/promises";

function normalize(raw) {
  return {
    id: raw.id,
    ts: Date.now(),
    temperatureC: Number(raw.temp),
    pressureKpa: Number(raw.pressure),
  };
}

async function publish(event) {
  await appendFile("/tmp/gateway.log", JSON.stringify(event) + "\n");
  return true;
}

export async function processReading(raw) {
  const event = normalize(raw);
  const ok = await publish(event);
  if (!ok) throw new Error("publish-failed");
  return event;
}

Recipe F — Plugin-Friendly Runtime App

Context

You want feature extensions without hardcoding every integration into core logic.

Plugin Host

// /app/plugin-host.js
import { readdir } from "node:fs/promises";

export async function loadPlugins(pluginDir = "/app/plugins") {
  const entries = await readdir(pluginDir);
  const plugins = [];

  for (const entry of entries) {
    if (!entry.endsWith(".mjs")) continue;
    const module = await import(`${pluginDir}/${entry}`);
    if (typeof module.setup === "function") {
      plugins.push(await module.setup());
    }
  }

  return plugins;
}

Operational Notes

Resource Budgets

ModeMemoryCPUTypical Use
API runtime512 MB–2 GB1–2 vCPUInternal services
Batch worker256 MB–1 GB1 vCPUShort-lived compute jobs
Gateway256 MB–512 MB1 vCPUDevice bridge

Reliability Practices

  • Keep startup idempotent.
  • Use explicit retry budgets.
  • Isolate external dependencies behind adapters.
  • Emit machine-readable logs (json lines).

Next Read

Proceed to 13-system-design-playbook.mdx for architectural trade-offs and design examples.

On this page