# VulnClaw Plugin Context Model: Understanding PluginContext in the Unclecheng-li/VulnClaw Framework

> Explore the VulnClaw plugin context model, a Pydantic BaseModel that manages execution parameters for vulnerability scanning plugins. Understand target URLs, lifecycle stages, and more.

- Repository: [Unclecheng/VulnClaw](https://github.com/Unclecheng-li/VulnClaw)
- Tags: internals
- Published: 2026-06-30

---

**The VulnClaw plugin context model is a Pydantic `BaseModel` class named `PluginContext` that encapsulates all execution parameters—including target URLs, lifecycle stages, timeouts, and safety policies—passed to plugins during vulnerability scanning.**

The plugin context model in VulnClaw serves as the central contract between the scanning engine and its extensible plugins. Defined in [`vulnclaw/plugins/base.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/base.py), this `PluginContext` class provides a type-safe container that standardizes how configuration, state, and constraints flow through the system. Understanding this model is essential for developing custom plugins or configuring the runtime behavior of the Unclecheng-li/VulnClaw security scanning framework.

## Core Architecture of the Plugin Context Model

The `PluginContext` class inherits from Pydantic's `BaseModel` and is located in [`vulnclaw/plugins/base.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/base.py) (lines 11-21). This design choice ensures automatic validation, serialization, and type coercion while maintaining strict contract guarantees between the runtime and plugin implementations.

The runtime system uses this model as the single source of truth for plugin execution parameters. When the `PluginRuntime` class in [`vulnclaw/plugins/runtime.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/runtime.py) initiates a scan, it normalizes incoming dictionaries into validated `PluginContext` instances before invoking any plugin logic.

## PluginContext Fields and Data Types

The plugin context model contains nine distinct fields that control every aspect of plugin execution:

- **`target`** (`str`): The network target—such as a URL, IP address, or hostname—that the plugin will analyze. This field remains empty for plugins that do not require network targets.
  
- **`stage`** (`PluginStage`): The lifecycle phase of execution, defaulting to `PluginStage.DISCOVERY`. Valid values include `recon`, `discovery`, and `verification`, defined in [`vulnclaw/plugins/result.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/result.py).
  
- **`options`** (`dict[str, Any]`): A flexible dictionary for plugin-specific configuration supplied via CLI or API calls.
  
- **`state`** (`dict[str, Any]`): Mutable state that persists across multiple plugin runs within the same execution context, enabling multi-step plugin workflows.
  
- **`metadata`** (`dict[str, Any]`): Arbitrary key-value pairs for tracing IDs, timestamps, or audit information attached by callers.
  
- **`timeout_seconds`** (`float | None`): Optional per-plugin timeout that must be greater than zero when specified, preventing hung processes.
  
- **`allow_destructive`** (`bool`): A safety flag that must be `True` for plugins marked as `destructive` to execute; otherwise, the runtime skips them automatically.
  
- **`scope_targets`** (`set[str]`): A whitelist of allowed targets (supporting CIDR notation) that restricts plugin execution to approved network ranges.
  
- **`task_constraints`** (`Any`): Optional constraint objects used by the constraint policy layer in [`vulnclaw/plugins/runtime.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/runtime.py) to validate host and port restrictions before execution.

## Runtime Integration and Pre-flight Validation

The `PluginRuntime` class leverages the plugin context model to enforce safety policies before plugin invocation. According to the source code in [`vulnclaw/plugins/runtime.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/runtime.py), the runtime performs three critical validation steps using context data:

1. **Context Normalization**: Incoming dictionaries coerce into typed `PluginContext` instances, ensuring all fields meet Pydantic validation rules.

2. **Scope Validation**: The `_preflight` and `_target_error` methods compare `context.target` against `context.scope_targets`, rejecting execution if the target falls outside whitelisted ranges.

3. **Policy Enforcement**: The `_policy_error` method inspects `context.allow_destructive` and `context.task_constraints` to determine whether the requested operation violates organizational security policies.

## Practical Usage Examples

### Creating a PluginContext Instance Manually

When writing unit tests or orchestrating complex scans, instantiate `PluginContext` directly with validated parameters:

```python
from vulnclaw.plugins.base import PluginContext
from vulnclaw.plugins.result import PluginStage

ctx = PluginContext(
    target="https://example.com",
    stage=PluginStage.DISCOVERY,
    options={"header_check": True},
    allow_destructive=False,
    timeout_seconds=30,
)

```

### Passing Plain Dictionaries to the Runtime

The `PluginRuntime` automatically coerces dictionary inputs into `PluginContext` objects, simplifying CLI integrations:

```python
await PluginRuntime().execute(
    plugin_id="builtin.web.headers",
    context={
        "target": "https://example.com",
        "stage": "discovery",
        "options": {"header_check": True},
    },
)

```

### Accessing Context Fields Inside Plugins

Plugins receive the context through their `run` method signature. The `SecurityHeadersPlugin` in [`vulnclaw/plugins/web/headers.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/web/headers.py) demonstrates this pattern:

```python

# vulnclaw/plugins/web/headers.py

class SecurityHeadersPlugin(VulnPlugin):
    plugin_id = "builtin.web.headers"
    # ...

    def run(self, context: PluginContext) -> PluginResult:
        # Use the target URL supplied by the caller

        target_url = context.target
        # Respect the per-plugin timeout if provided

        timeout = context.timeout_seconds or 10
        # … perform the header analysis …

        return PluginResult(...)

```

### Restricting Execution with Scope Targets

Use the `scope_targets` field to implement network segmentation policies:

```python
ctx = PluginContext(
    target="192.168.1.10",
    scope_targets={"192.168.1.0/24"},
)

# The runtime will reject the plugin if the target lies outside the CIDR range

```

## Key Implementation Files

Understanding the plugin context model requires familiarity with these specific files in the Unclecheng-li/VulnClaw repository:

- **[`vulnclaw/plugins/base.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/base.py)**: Defines `PluginContext` and the abstract `VulnPlugin` base class that all plugins must inherit.
  
- **[`vulnclaw/plugins/result.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/result.py)**: Contains the `PluginStage` enumeration used by the `stage` field to track execution lifecycle phases.
  
- **[`vulnclaw/plugins/runtime.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/runtime.py)**: Implements the core execution engine that normalizes inputs, validates `PluginContext` instances, and runs pre-flight checks.
  
- **[`vulnclaw/plugins/web/headers.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/web/headers.py)**: Reference implementation showing how production plugins consume `PluginContext` attributes.
  
- **[`vulnclaw/plugins/registry.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/registry.py)**: Manages plugin discovery and registration using `plugin_id` values defined in each `VulnPlugin` subclass.

## Summary

The VulnClaw plugin context model provides a robust, type-safe contract for plugin execution through the `PluginContext` Pydantic model. Key takeaways include:

- **`PluginContext`** in [`vulnclaw/plugins/base.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/base.py) encapsulates all runtime parameters including targets, timeouts, and safety flags.
- The **runtime system** automatically validates and coerces incoming data into `PluginContext` instances before execution.
- **Scope targets** and **destructive flags** enforce security boundaries at the framework level, not just the plugin level.
- **Mutable state** persistence enables complex multi-step scanning workflows across plugin invocations.
- All fields are strongly typed, supporting IDE autocomplete and runtime validation via Pydantic.

## Frequently Asked Questions

### What is the plugin context model in VulnClaw?

The plugin context model is a Pydantic `BaseModel` class named `PluginContext` defined in [`vulnclaw/plugins/base.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/base.py). It serves as the standardized container for all execution parameters passed to plugins, including target URLs, lifecycle stages, configuration options, and security constraints like `allow_destructive` and `scope_targets`.

### How does PluginContext handle plugin timeouts?

The `timeout_seconds` field accepts an optional `float` value that specifies the maximum execution time for a single plugin run. When provided, this value must be greater than zero, and the runtime system uses it to limit plugin execution duration. If not specified, plugins typically fall back to default timeouts defined in their implementation or the global configuration.

### Can I pass a plain dictionary instead of a PluginContext object?

Yes. The `PluginRuntime` class in [`vulnclaw/plugins/runtime.py`](https://github.com/Unclecheng-li/VulnClaw/blob/main/vulnclaw/plugins/runtime.py) automatically coerces dictionary inputs into validated `PluginContext` instances. This allows simpler CLI and API integrations while maintaining type safety through Pydantic validation. However, within plugin implementations, the `run` method receives a fully instantiated `PluginContext` object.

### How does the scope_targets field improve security?

The `scope_targets` field accepts a `set[str]` containing whitelisted targets such as IP addresses or CIDR ranges (e.g., `{"192.168.1.0/24"}`). During pre-flight validation, the runtime compares the `target` field against this whitelist, automatically rejecting plugin execution if the target falls outside approved network boundaries. This prevents accidental scanning of out-of-scope assets in production environments.