> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/relay/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/relay/_mcp/server.

# Design Plugin Configuration

> Design stable configuration, validation, rollout, and lifecycle behavior for NeMo Relay plugins.

Use this guide to safely configure a plugin that needs more than a single flag
or string.

## What You Design

Define the plugin's configuration contract, validation rules, advanced
configuration patterns, and runtime registration plan. Keep activation
predictable for operators while keeping runtime objects and business logic in
the plugin implementation.

## Plugin Shape and Requirements

A NeMo Relay plugin has four practical parts:

| Part              | Requirement                                                             |
| ----------------- | ----------------------------------------------------------------------- |
| Plugin kind       | A stable `kind` string registered once per process.                     |
| Component config  | A JSON-compatible object under `components[].config`.                   |
| Validation hook   | A function that returns structured diagnostics before initialization.   |
| Registration hook | A function that receives `PluginContext` and installs runtime behavior. |

The top-level plugin document keeps activation consistent across bindings:

```json
{
  "version": 1,
  "components": [
    {
      "kind": "header-plugin",
      "enabled": true,
      "config": {
        "header_name": "x-tenant",
        "value": "tenant-a"
      }
    }
  ],
  "policy": {
    "unknown_component": "warn",
    "unknown_field": "warn",
    "unsupported_value": "error"
  }
}
```

Keep the component config portable:

* Use JSON-compatible values only.
* Put clients, callbacks, file handles, and provider SDK objects in plugin code, not config.
* Include a component-local config version when the plugin's own schema needs to evolve independently.
* Prefer references to secrets or endpoints over embedding sensitive values directly.
* Treat a component whose `enabled` field has the value `false` as disabled for
  activation, not as a reason to skip validation.

The top-level `policy` controls validation that Relay handles. For a custom
plugin's component-local `config`, define unknown-field and unsupported-value
behavior in the plugin's `validate()` method.

## Configuration Validation

Keep validation deterministic and side-effect free. Inspect configuration and
return diagnostics. Do not register middleware, open network connections,
create clients, or change process state.

Check these areas:

* Required fields are present.
* Field types match the supported shape.
* The plugin reports unknown component-local fields with stable diagnostics.
* The plugin reports unsupported component-local values with stable diagnostics.
* Cross-field combinations make sense.
* Environment-specific limitations are warnings unless they would make activation fail.

Diagnostics should be actionable and stable enough for tests or deployment automation:

```json
[
  {
    "level": "error",
    "code": "header-plugin.missing_header_name",
    "component": "header-plugin",
    "field": "header_name",
    "message": "config.header_name is required"
  }
]
```

Use `warning` when the config can still activate but deserves operator attention. Use `error` when initialization should not proceed.

## Advanced Configuration Patterns

These patterns help plugin authors keep configuration stable as components evolve.

### Component-Local Versioning

Use a field such as `config.version` when the plugin's config schema needs independent compatibility handling. Keep the top-level `version` for the NeMo Relay plugin document itself.

### Multiple Component Instances

If your plugin supports multiple instances, require an explicit instance
identity in configuration:

```json
{
  "kind": "routing-policy",
  "config": {
    "instance": "east-region",
    "priority": 100,
    "region": "us-east-1"
  }
}
```

Use the instance identity in logs, diagnostics, and downstream resource names.
Let the NeMo Relay plugin system qualify runtime registration names. Do not
hand-build global names to avoid collisions.

### Presets and Overrides

Presets are useful when most deployments use a known shape:

```json
{
  "kind": "redaction-policy",
  "config": {
    "preset": "strict",
    "overrides": {
      "allow_fields": ["request_id", "tenant"]
    }
  }
}
```

Validate the resolved result, not only the literal input. Unknown preset names should be `error` diagnostics because the plugin cannot know what behavior to install.

### Rollout Controls

For behavior that can affect execution, include explicit rollout fields:

* `mode`: for example `observe_only`, `enforce`, or `disabled`.
* `priority`: where middleware should run relative to other registrations.
* `break_chain`: whether a request intercept should stop later intercepts.
* `sample_rate` or `tenants`: when behavior should apply only to part of traffic.

Prefer observe-only defaults for new policies and execution-affecting intercepts.

## Plugin Context

`PluginContext` is the component-scoped surface used during registration. It connects validated config to real runtime behavior.

Use `PluginContext` to register:

* Subscribers
* Tool guardrails
* Tool request and execution intercepts
* LLM guardrails
* LLM request, execution, and stream execution intercepts

The context gives the plugin system enough information to qualify runtime names
and roll back partial setup if registration fails. Put all runtime registration
work in the registration hook so rollback can clean up correctly.

Avoid these patterns:

* Registering middleware before plugin initialization.
* Creating process-global state that is not owned by the plugin instance.
* Reusing one mutable object across component instances without tenant or request isolation.
* Encoding runtime callbacks inside JSON config.

## Validation Checklist

Before publishing a plugin config contract:

1. Validate the smallest correct config.
2. Validate a config with each required field missing.
3. Validate each unsupported enum or mode.
4. Validate unknown component-local fields and their diagnostic levels.
5. Initialize a valid config and confirm expected middleware or subscribers are active.
6. Force a registration failure and confirm partial setup is rolled back.

## Next Steps

Use these links to continue from this workflow into the next related task.

* Build the first plugin with [Language Binding Plugins](/build-plugins/language-binding/about).
* Validate plugin config with [Validate Plugin Configuration](/build-plugins/language-binding/validate-configuration).
* Register runtime behavior with [Register Plugin Behavior](/build-plugins/language-binding/register-behavior).
* Review reusable patterns in [Code Examples](/build-plugins/language-binding/code-examples).