# How to Build a Custom NeMo Relay Plugin Bundle for Switchyard Using relay-plugin.toml and a Digest

> Learn to build a custom NeMo Relay plugin bundle for Switchyard. Compile the crate, calculate a digest, and package it with relay-plugin.toml using package_bundle.py.

- Repository: [NVIDIA-NeMo/Switchyard](https://github.com/NVIDIA-NeMo/Switchyard)
- Tags: how-to-guide
- Published: 2026-09-12

---

**To build a custom NeMo Relay plugin bundle for Switchyard, compile the `switchyard-nemo-relay-plugin` crate as a dynamic library, calculate a SHA-256 digest of the artifact, and package it with a populated [`relay-plugin.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/relay-plugin.toml) manifest using the provided [`package_bundle.py`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/package_bundle.py) script.**

The Switchyard framework in the **NVIDIA-NeMo/Switchyard** repository provides a native NeMo Relay plugin that enables integration with the NeMo ecosystem. Creating a custom bundle allows you to distribute validated plugin artifacts that NeMo Relay can load securely using cryptographic integrity checks. This workflow requires the Rust toolchain, Python for packaging automation, and the NeMo Relay CLI for installation.

## Prerequisites

Before building the plugin, ensure you have the Rust toolchain installed and the repository cloned locally.

```bash
git clone https://github.com/NVIDIA-NeMo/Switchyard.git
cd Switchyard
rustup toolchain install stable
rustup default stable

```

The `switchyard-nemo-relay-plugin` crate is located in `crates/switchyard-nemo-relay-plugin/` and contains the source code, build configuration, and packaging scripts necessary to generate the bundle.

## Building the Plugin Dynamic Library

The plugin compiles into a platform-specific shared library that NeMo Relay loads at runtime. In [`crates/switchyard-nemo-relay-plugin/Cargo.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/crates/switchyard-nemo-relay-plugin/Cargo.toml), the crate is configured to produce a `cdylib` target suitable for dynamic linking.

Build the release artifact using Cargo:

```bash
cargo build --release -p switchyard-nemo-relay-plugin

```

Upon completion, the compiled library appears in `target/release/` with platform-specific extensions:

- Linux: `libswitchyard_nemo_relay_plugin.so`
- macOS: `libswitchyard_nemo_relay_plugin.dylib`
- Windows: `switchyard_nemo_relay_plugin.dll`

The entry point `nemo_relay_register_plugin` defined in [`crates/switchyard-nemo-relay-plugin/src/lib.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/crates/switchyard-nemo-relay-plugin/src/lib.rs) handles plugin registration when the library is loaded.

## Generating the SHA-256 Digest

NeMo Relay requires a cryptographic digest to verify bundle integrity. Calculate the SHA-256 hash of the compiled shared library to populate the `integrity.sha256` field in the manifest.

On Linux or macOS:

```bash
sha256sum target/release/libswitchyard_nemo_relay_plugin.so | awk '{print $1}'

```

On Windows using PowerShell or Command Prompt:

```cmd
CertUtil -hashfile target\release\switchyard_nemo_relay_plugin.dll SHA256

```

Record the resulting hexadecimal string (e.g., `abcd1234...`), as you will inject this value into [`relay-plugin.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/relay-plugin.toml) during the packaging step.

## Packaging the Bundle with relay-plugin.toml

The repository ships a template manifest at [`crates/switchyard-nemo-relay-plugin/relay-plugin.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/crates/switchyard-nemo-relay-plugin/relay-plugin.toml) containing placeholders for the library filename and digest. The [`package_bundle.py`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/package_bundle.py) script automates substitution and directory structure creation.

Run the packaging script from the repository root:

```bash
python crates/switchyard-nemo-relay-plugin/scripts/package_bundle.py \
    --library target/release/libswitchyard_nemo_relay_plugin.so \
    --sha256 <artifact-sha256>

```

This script performs the following operations derived from its implementation in [`package_bundle.py`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/package_bundle.py):

- Reads the template [`relay-plugin.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/relay-plugin.toml) and substitutes `<platform-library-file>` with the actual library filename
- Inserts `sha256:<artifact-sha256>` into the `integrity.sha256` field
- Copies the compiled library and LICENSE files into `./plugins/switchyard/` by default

The resulting bundle directory contains:
- [`relay-plugin.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/relay-plugin.toml) — Fully populated manifest with integrity metadata
- The compiled shared library file
- Required LICENSE files

## Installing and Validating the Plugin

Once packaged, validate the bundle structure before registering it with NeMo Relay:

```bash
nemo-relay plugins validate ./plugins/switchyard/relay-plugin.toml

```

Install the plugin for the current user:

```bash
nemo-relay plugins add --user ./plugins/switchyard/relay-plugin.toml

```

NeMo Relay now recognizes the plugin ID `nvidia.switchyard` and can load the custom bundle when requested by Switchyard applications.

## Configuration and Usage

To activate the plugin within a Switchyard deployment, reference the plugin ID in your Switchyard configuration TOML:

```toml
[plugins]
nvidia.switchyard = { enabled = true }

```

Alternatively, set the `SWITCHYARD_RELAY_PLUGIN` environment variable to point to the bundle directory path. When Switchyard initializes, it queries NeMo Relay for the `nvidia.switchyard` plugin and loads the validated shared library according to the manifest specifications in [`relay-plugin.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/relay-plugin.toml).

## Summary

- **Clone and build** the `switchyard-nemo-relay-plugin` crate using `cargo build --release -p switchyard-nemo-relay-plugin` to generate the platform-specific shared library.
- **Calculate integrity** by generating a SHA-256 digest of the compiled artifact using standard system utilities.
- **Automate packaging** with [`package_bundle.py`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/package_bundle.py) to populate [`relay-plugin.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/relay-plugin.toml) placeholders and assemble the bundle directory structure.
- **Register securely** using `nemo-relay plugins add` to install the validated bundle into your NeMo Relay environment.
- **Configure Switchyard** to load the plugin via the `nvidia.switchyard` ID in TOML configuration or environment variables.

## Frequently Asked Questions

### What is the purpose of the SHA-256 digest in the plugin bundle?

The SHA-256 digest provides cryptographic integrity verification for the compiled shared library. When NeMo Relay loads the plugin specified in [`relay-plugin.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/relay-plugin.toml), it validates the library against the `integrity.sha256` hash to ensure the artifact has not been modified or corrupted since packaging. This security measure prevents the execution of tampered code in production environments.

### Can I modify the plugin source code before building the custom bundle?

Yes. The [`crates/switchyard-nemo-relay-plugin/src/lib.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/crates/switchyard-nemo-relay-plugin/src/lib.rs) file contains the plugin implementation including the `nemo_relay_register_plugin` entry point. After modifying the source code to customize behavior or add capabilities, rebuild the crate with `cargo build --release` and regenerate the SHA-256 digest. The [`package_bundle.py`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/package_bundle.py) script will package your modified version just like the standard build.

### How do I resolve validation errors when running nemo-relay plugins validate?

Validation errors typically indicate missing files, incorrect paths in [`relay-plugin.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/relay-plugin.toml), or digest mismatches. Ensure the `<platform-library-file>` placeholder was properly substituted with the actual filename, verify that the `integrity.sha256` field contains the full hash string prefixed with `sha256:`, and confirm the library file exists in the same directory as the manifest. Check that you calculated the digest against the release binary, not a debug build.

### Where should I deploy the custom plugin bundle in production environments?

Deploy the bundle directory (containing [`relay-plugin.toml`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/relay-plugin.toml), the shared library, and licenses) to a persistent path accessible by NeMo Relay, then register it using `nemo-relay plugins add --user` for user-specific installation or system-wide depending on your deployment requirements. The bundle remains portable as long as the relative paths between the manifest and library files are maintained as structured by [`package_bundle.py`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/package_bundle.py).