# How OpenAI Validates Path Format for Plugin Configurations: Schema and Runtime Security

> Discover how OpenAI validates plugin configuration paths using schema regex and runtime security checks to keep plugins within their sandbox.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: deep-dive
- Published: 2026-07-05

---

**OpenAI validates plugin configuration paths through a two-layer defense combining JSON-Schema regex patterns in `validate.mjs` with runtime directory traversal checks in [`plugin.js`](https://github.com/openai/plugins/blob/main/plugin.js) to ensure paths stay within the plugin sandbox.**

The `openai/plugins` repository implements strict path validation to prevent security vulnerabilities in plugin configurations. When a plugin manifest specifies a file path, the system must verify that the reference points only to files within the plugin's designated directory. This article examines the exact validation mechanisms, from regex patterns to filesystem resolution checks, that enforce these boundaries according to the source code.

## Two-Layer Validation Architecture

OpenAI’s validation strategy employs **schema validation** followed by **runtime safety checks**.

| Layer | Purpose | Location |
|-------|---------|----------|
| **Schema Validation** | Enforces string format rules (no traversal sequences or double slashes) | `plugins/plugin-eval/scripts/validate.mjs` |
| **Runtime Enforcement** | Resolves paths and verifies they remain inside the plugin root | [`plugins/plugin-eval/src/evaluators/plugin.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/evaluators/plugin.js) |

This combination guarantees that **only relative paths** such as `"src/handler.ts"` are accepted, while **absolute paths** or **traversal attempts** like `"../secret.txt"` are rejected before file system access occurs.

## JSON-Schema Pattern Validation

The first line of defense is a JSON-Schema that validates the `path` field using a regular expression.

### Schema Definition in validate.mjs

In `plugins/plugin-eval/scripts/validate.mjs`, the schema is constructed programmatically and passed to the `ajv` validator. The pattern uses negative lookahead assertions to block dangerous sequences:

```javascript
// plugins/plugin-eval/scripts/validate.mjs
const pathPattern = /^(?!.*\.\.)(?!.*\/\/)[^\n\r]*$/; // no ".." or "//"
const configSchema = {
  type: "object",
  properties: {
    path: { type: "string", pattern: pathPattern.source },
    // … other fields …
  },
  required: ["path"],
  additionalProperties: false,
};

```

The regex `^(?!.*\.\.)(?!.*\/\/)[^\n\r]*$` enforces three critical constraints:

- **`(?!.*\.\.)`** prevents path traversal by disallowing the double-dot sequence anywhere in the string.
- **`(?!.*\/\/)`** blocks double slashes that could indicate protocol specifiers or path normalization tricks.
- **`^` and `$`** anchors ensure the entire string conforms to the pattern, preventing substring bypasses.

## Runtime Root Directory Enforcement

After schema validation passes, the system performs a **filesystem-aware check** to guarantee the resolved path does not escape the plugin’s sandbox.

### The ensureWithinRoot Safety Check

Located in [`plugins/plugin-eval/src/evaluators/plugin.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/evaluators/plugin.js), the `ensureWithinRoot` function uses Node.js path utilities to validate the resolved location:

```javascript
// plugins/plugin-eval/src/evaluators/plugin.js
import path from "path";

/**
 * Throws if candidatePath, once resolved, is outside rootDir.
 */
function ensureWithinRoot(candidatePath, rootDir) {
  const absolute = path.resolve(rootDir, candidatePath);
  const relative = path.relative(rootDir, absolute);
  if (relative.startsWith("..") || path.isAbsolute(relative)) {
    throw new Error(
      `Invalid plugin path – ${candidatePath} points outside the plugin root`
    );
  }
  return absolute;
}

```

This function implements a **canonical path comparison**:

1. **`path.resolve(rootDir, candidatePath)`** generates an absolute path from the plugin root.
2. **`path.relative(rootDir, absolute)`** calculates the relative path from root to the target.
3. **Security check**: If the relative path starts with `..` or is itself absolute, the target lies outside the sandbox and the function throws an error.

## Integration and Validation Flow

When a plugin configuration is loaded, the evaluator orchestrates both validation layers. The following pattern demonstrates how the system combines `ajv` schema validation with the runtime root check:

```javascript
import Ajv from "ajv";
import { configSchema } from "./validate.mjs";

export async function validatePluginConfig(rawConfig, pluginRoot) {
  const ajv = new Ajv();
  const valid = ajv.validate(configSchema, rawConfig);
  if (!valid) {
    throw new Error(`Schema validation error: ${ajv.errorsText()}`);
  }

  // Runtime safety check
  const safePath = ensureWithinRoot(rawConfig.path, pluginRoot);
  return { ...rawConfig, resolvedPath: safePath };
}

```

### Error Examples

The system produces distinct error messages depending on which validation layer catches the violation.

**Schema validation failure** (blocked by regex):

```javascript
const cfg = { path: "src//handler.ts" };
await validatePluginConfig(cfg, "/plugins/my-awesome-plugin");
// → throws: Schema validation error: path must match pattern "^(?!.*\.\.)(?!.*\/\/)[^\n\r]*$"

```

**Runtime traversal detection**:

```javascript
const cfg = { path: "../secret.txt" };
await validatePluginConfig(cfg, "/plugins/my-awesome-plugin");
// → throws: Invalid plugin path – ../secret.txt points outside the plugin root

```

## Summary

- **JSON-Schema validation** in `plugins/plugin-eval/scripts/validate.mjs` uses a regex pattern `/^(?!.*\.\.)(?!.*\/\/)[^\n\r]*$/` to block traversal sequences and double slashes at the configuration level.
- **Runtime enforcement** via `ensureWithinRoot` in [`plugins/plugin-eval/src/evaluators/plugin.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/evaluators/plugin.js) resolves paths using `path.resolve` and `path.relative` to verify they remain within the plugin root directory.
- **Combined defense** ensures that malicious paths like `"/etc/passwd"`, `"../secret.txt"`, or `"src//../handler.ts"` are rejected before any file system operations occur.
- **Test coverage** exists in [`plugins/plugin-eval/tests/plugin-eval.test.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/tests/plugin-eval.test.js) to verify both validation layers function correctly under edge cases.

## Frequently Asked Questions

### What regex pattern does OpenAI use to validate plugin paths?

OpenAI uses the pattern `/^(?!.*\.\.)(?!.*\/\/)[^\n\r]*$/` defined in `plugins/plugin-eval/scripts/validate.mjs`. This regex employs negative lookaheads to disallow the substring `..` (path traversal) and `//` (double slashes) anywhere in the path string, while the anchors `^` and `$` ensure the entire value conforms to the rule.

### How does the runtime check prevent directory traversal attacks?

The `ensureWithinRoot` function in [`plugins/plugin-eval/src/evaluators/plugin.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/evaluators/plugin.js) resolves the candidate path against the plugin root using `path.resolve`, then computes the relative path using `path.relative`. If the resulting relative path starts with `..` or is absolute, the function throws an error, guaranteeing the resolved file location cannot escape the plugin’s sandbox.

### Where is the path validation logic located in the openai/plugins repository?

The validation logic is split between two locations: the **JSON-Schema definition** resides in `plugins/plugin-eval/scripts/validate.mjs`, and the **runtime security check** is implemented in [`plugins/plugin-eval/src/evaluators/plugin.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/evaluators/plugin.js). Test cases for both layers are located in [`plugins/plugin-eval/tests/plugin-eval.test.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/tests/plugin-eval.test.js).

### What happens if a plugin configuration fails path validation?

If validation fails at the schema level, the `ajv` validator returns an error indicating the path does not match the required pattern. If it fails at the runtime level, the `ensureWithinRoot` function throws an `Error` with the message `"Invalid plugin path – {path} points outside the plugin root"`. In both cases, the plugin configuration is rejected before any file system access is attempted.