tutorial

Monitoring wasm-to-oci with Vigilmon: Keeping Your WebAssembly OCI Distribution Pipeline Healthy

How to monitor wasm-to-oci with Vigilmon — tracking OCI registry availability, Wasm artifact push/pull pipeline health, and distribution workflow heartbeats from outside your infrastructure.

wasm-to-oci is a tool for packaging and distributing WebAssembly modules as OCI artifacts in container registries. It enables Wasm modules to be pushed to and pulled from standard registries — Docker Hub, GHCR, ECR, and self-hosted registries — using the same infrastructure teams already operate for container images. CI/CD pipelines that build and distribute Wasm modules depend on wasm-to-oci to publish artifacts on every merge; when the OCI registry is unavailable or the push/pull pipeline breaks, Wasm deployments stall without clear error messages. Vigilmon gives you external monitoring that watches the registry availability and validates that the Wasm artifact distribution pipeline is completing on schedule.

What You'll Build

  • Vigilmon HTTP monitors for OCI registry availability
  • A heartbeat monitor validating that Wasm artifact push and pull operations complete end-to-end
  • A registry authentication health heartbeat to catch credential rotation failures
  • Alert channels routed to your release engineering team

Prerequisites

  • wasm-to-oci installed (go install github.com/engineerd/wasm-to-oci@latest or binary release)
  • An OCI-compatible registry (Docker Hub, GHCR, ECR, or self-hosted like Registry2 or Zot)
  • A free account at vigilmon.online

Why Monitoring wasm-to-oci Matters

The wasm-to-oci distribution pipeline sits between your Wasm build system and your runtime. Its failure modes are pipeline-level, not workload-level:

Registry downtime breaks Wasm deployments silently. If the OCI registry is unreachable when a CD pipeline runs, wasm-to-oci push fails and the Wasm module is not updated. The old version continues running — no crash, no alert — while the deployment appears to have succeeded from the pipeline runner's perspective if error handling is absent. External monitoring that probes registry availability independently from your CI system catches this before a rollout window closes.

Credential rotation failures block all pushes. OCI registries use token-based authentication with short-lived credentials. When a service account token expires or a registry PAT is rotated, every wasm-to-oci push in your pipeline returns a 401 — but the credential renewal system (GitHub Actions secret, AWS Secrets Manager rotation, Vault lease) may have silently failed days earlier. A heartbeat that attempts registry authentication on a schedule catches credential expiry before it blocks a release.

OCI manifest schema drift breaks pull compatibility. wasm-to-oci stores Wasm modules with a specific OCI media type (application/vnd.wasm.content.layer.v1+wasm). When a registry upgrade or proxy layer strips or rewrites unknown media types, Wasm pulls return a valid OCI response but with the wrong content type — and the runtime fails silently when attempting to execute the artifact. A probe that pulls and validates the media type catches this regression.

Storage quota exhaustion halts artifact publishing. Self-hosted registries and registry namespaces on hosted services have storage limits. When a namespace approaches its quota, push operations fail with 507 or 403 status codes. Without external monitoring of the push path, quota exhaustion is discovered only when a release pipeline fails.


Step 1: Monitor the OCI Registry Availability

For a self-hosted registry (Registry2, Zot, Harbor), probe the /v2/ API endpoint directly:

# Test registry V2 API availability
curl -fsS -o /dev/null -w "%{http_code}" \
  https://your-registry.example.com/v2/
# Expected: 200 (unauthenticated), 401 (authenticated registry — still reachable)

In the Vigilmon dashboard:

  1. Go to Add Monitor → HTTP
  2. Configure:

| Field | Value | |---|---| | Name | OCI registry V2 API | | URL | https://your-registry.example.com/v2/ | | Method | GET | | Expected status | 200 or 401 | | Check interval | 1 minute | | Timeout | 10 seconds | | Alert after | 2 consecutive failures |

For Docker Hub (public), monitor the catalog endpoint:

| Field | Value | |---|---| | Name | Docker Hub registry API | | URL | https://registry-1.docker.io/v2/ | | Expected status | 401 | | Response body contains | Unauthorized | | Check interval | 2 minutes |

A 401 from Docker Hub means the registry is reachable and responding correctly; a timeout or 5xx means an outage.


Step 2: Heartbeat Monitor for Wasm Artifact Push and Pull

The most reliable validation of the wasm-to-oci pipeline is a round-trip: push a known Wasm module, pull it back, and verify the content hash matches. Create a probe script:

# /usr/local/bin/wasm-oci-probe.sh
#!/bin/bash
set -euo pipefail

HEARTBEAT_URL="${WASM_OCI_HEARTBEAT_URL}"
REGISTRY="${WASM_OCI_REGISTRY}"     # e.g. your-registry.example.com
NAMESPACE="${WASM_OCI_NAMESPACE}"   # e.g. myorg/wasm-probes
TAG="probe-$(date +%s)"

PROBE_WASM="/tmp/wasm-oci-probe.wasm"
PULL_WASM="/tmp/wasm-oci-probe-pulled.wasm"

# Create a minimal valid Wasm module (magic number + version)
printf '\x00asm\x01\x00\x00\x00' > "$PROBE_WASM"

# Push the Wasm module to the registry
if ! wasm-to-oci push "$PROBE_WASM" \
  "${REGISTRY}/${NAMESPACE}:${TAG}" 2>/dev/null; then
  echo "$(date): ERROR — wasm-to-oci push failed" >&2
  rm -f "$PROBE_WASM"
  exit 1
fi

# Pull it back
if ! wasm-to-oci pull "${REGISTRY}/${NAMESPACE}:${TAG}" \
  --output "$PULL_WASM" 2>/dev/null; then
  echo "$(date): ERROR — wasm-to-oci pull failed" >&2
  rm -f "$PROBE_WASM" "$PULL_WASM"
  exit 1
fi

# Verify content integrity
PUSH_HASH=$(sha256sum "$PROBE_WASM" | awk '{print $1}')
PULL_HASH=$(sha256sum "$PULL_WASM" | awk '{print $1}')

rm -f "$PROBE_WASM" "$PULL_WASM"

if [ "$PUSH_HASH" != "$PULL_HASH" ]; then
  echo "$(date): ERROR — content hash mismatch after round-trip" >&2
  exit 1
fi

curl -fsS --max-time 10 "$HEARTBEAT_URL" -o /dev/null
echo "$(date): wasm-to-oci push/pull probe OK, heartbeat sent"
# /etc/systemd/system/wasm-oci-probe.service
[Unit]
Description=wasm-to-oci push/pull pipeline probe

[Service]
Type=oneshot
EnvironmentFile=/etc/wasm-oci-probe.env
ExecStart=/usr/local/bin/wasm-oci-probe.sh

# /etc/systemd/system/wasm-oci-probe.timer
[Unit]
Description=Run wasm-to-oci pipeline probe every 15 minutes

[Timer]
OnBootSec=3min
OnUnitActiveSec=15min
Unit=wasm-oci-probe.service

[Install]
WantedBy=timers.target
# /etc/wasm-oci-probe.env
WASM_OCI_HEARTBEAT_URL=https://vigilmon.online/heartbeat/YOUR_WASM_OCI_TOKEN
WASM_OCI_REGISTRY=your-registry.example.com
WASM_OCI_NAMESPACE=your-org/wasm-probes
chmod +x /usr/local/bin/wasm-oci-probe.sh
systemctl daemon-reload
systemctl enable --now wasm-oci-probe.timer

Create the heartbeat monitor in Vigilmon:

  1. Add Monitor → Heartbeat
  2. Name: wasm-to-oci push/pull pipeline
  3. Expected interval: 15 minutes
  4. Grace period: 8 minutes

Step 3: Heartbeat Monitor for Registry Authentication

Credential rotation failures are silent until a pipeline runs. Probe registry authentication on a schedule separate from the push/pull test — authentication failure returns a different exit path:

# /usr/local/bin/wasm-oci-auth-probe.sh
#!/bin/bash
set -euo pipefail

HEARTBEAT_URL="${WASM_OCI_AUTH_HEARTBEAT_URL}"
REGISTRY="${WASM_OCI_REGISTRY}"
REGISTRY_USER="${WASM_OCI_USER}"
REGISTRY_TOKEN="${WASM_OCI_TOKEN}"

# Attempt token exchange against the V2 API
AUTH_RESPONSE=$(curl -fsS -o /dev/null -w "%{http_code}" \
  -u "${REGISTRY_USER}:${REGISTRY_TOKEN}" \
  "https://${REGISTRY}/v2/" 2>/dev/null || echo "000")

if [ "$AUTH_RESPONSE" = "200" ] || [ "$AUTH_RESPONSE" = "401" ]; then
  # 401 here means the endpoint is reachable; auth validation happens at token exchange
  # Run a lightweight manifest list to confirm auth works
  TOKEN=$(curl -fsS \
    -u "${REGISTRY_USER}:${REGISTRY_TOKEN}" \
    "https://${REGISTRY}/v2/token?service=${REGISTRY}&scope=repository:${WASM_OCI_NAMESPACE}:pull" \
    2>/dev/null | jq -r '.token // empty')
  if [ -n "$TOKEN" ]; then
    curl -fsS --max-time 10 "$HEARTBEAT_URL" -o /dev/null
    echo "$(date): registry auth probe OK"
    exit 0
  fi
fi

echo "$(date): ERROR — registry authentication failed (status: $AUTH_RESPONSE)" >&2
exit 1
# /etc/wasm-oci-auth-probe.env
WASM_OCI_AUTH_HEARTBEAT_URL=https://vigilmon.online/heartbeat/YOUR_AUTH_TOKEN
WASM_OCI_REGISTRY=your-registry.example.com
WASM_OCI_USER=your-service-account
WASM_OCI_TOKEN=your-registry-token
WASM_OCI_NAMESPACE=your-org/wasm-probes

Create the heartbeat monitor in Vigilmon:

  1. Add Monitor → Heartbeat
  2. Name: wasm-to-oci registry auth
  3. Expected interval: 30 minutes
  4. Grace period: 10 minutes

Step 4: Configure Alert Channels

Route wasm-to-oci alerts to your release engineering team:

  1. In Vigilmon: Alert Channels → Add Channel → Slack Webhook
  2. Add your #releases or #registry-ops webhook URL
  3. Assign to all wasm-to-oci monitors

For authentication failures (block all push pipelines):

  1. Alert Channels → Add Channel → PagerDuty
  2. Route the wasm-to-oci registry auth heartbeat to on-call
  3. An auth failure means all Wasm releases are blocked until credentials are rotated

What You're Now Monitoring

| Component | Monitor Type | What It Detects | |---|---|---| | OCI registry V2 API | HTTP GET | Registry unreachable or returning errors | | wasm-to-oci push/pull | Heartbeat (15 min) | End-to-end pipeline failure, media type corruption, storage exhaustion | | Registry authentication | Heartbeat (30 min) | Credential rotation failures, expired tokens |


Conclusion

The wasm-to-oci distribution pipeline is a critical but unmonitored link in most Wasm deployment stacks. Registry downtime, credential expiry, and media type corruption all result in failed deployments without clear signals. External monitoring with Vigilmon catches each failure mode independently: the V2 API probe detects registry outages, the push/pull heartbeat validates the complete distribution path including content integrity, and the authentication heartbeat catches credential rotation failures before they block a release. Together, they give you confidence that your Wasm artifacts will be publishable when a release is triggered.

Get started free at vigilmon.online.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →