# pvnarp/kong-plugin-vard architecture

> Architecture diagram of the GitHub repository pvnarp/kong-plugin-vard, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/pvnarp/kong-plugin-vard
- Repository: https://github.com/pvnarp/kong-plugin-vard

## Overview

Vard is a Kong Gateway plugin that evaluates MCP tool calls using their arguments and Kong principal, then allows, denies, or holds them. The main flow is agent → Kong/Vard → tool server; held calls wait for human review at the approvals UI. Vard also observes tool listings to detect manifest drift and refuses the next call to a changed tool. The map preserves the documented model-gateway observer capability. Plugin internals are only partially sampled, so uncertain storage and call wiring are omitted.

Main entry points: [`kong/plugins/vard/handler.lua`](https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/handler.lua) (Vard plugin), [`kong/plugins/vard/ui.lua`](https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/ui.lua) (Approvals UI), [`rules.example.yaml`](https://github.com/pvnarp/kong-plugin-vard/blob/main/rules.example.yaml) (Policy rules)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_gateway_policy["Gateway policy"]
  node_vard["Vard plugin<br/>[handler.lua]"]
  node_rules["Policy rules<br/>[rules.example.yaml]"]
  node_verdict["Call verdict<br/>[handler.lua]"]
end

subgraph group_manifest_integrity["Manifest integrity"]
  node_manifest_check["Manifest pinning<br/>[handler.lua]"]
  node_drift["Drift refusal<br/>[handler.lua]"]
end

subgraph group_human_approval["Human approval"]
  node_approval_ui["Approvals UI<br/>[ui.lua]"]
end

subgraph group_integrations["Runtime integrations"]
  node_kong["Kong Gateway"]
  node_mcp_server["MCP tool server"]
  node_ai_gateway["AI Gateway"]
end

node_agent(("MCP agent"))
node_approver(("Human approver"))

node_agent -->|"sends MCP calls"| node_kong
node_kong -->|"invokes plugin"| node_vard
node_vard -->|"evaluates rules"| node_rules
node_vard -->|"scores call"| node_verdict
node_verdict -->|"returns decision"| node_kong
node_kong -->|"proxies allowed calls"| node_mcp_server
node_kong -->|"passes tool listings"| node_vard
node_vard -->|"hashes manifests"| node_manifest_check
node_manifest_check -->|"detects changes"| node_drift
node_drift -->|"refuses next call"| node_vard
node_verdict -->|"parks held calls"| node_approval_ui
node_approver -->|"reviews requests"| node_approval_ui
node_approval_ui -->|"releases decision"| node_verdict
node_kong -.->|"model-lane observer"| node_ai_gateway

click node_vard "https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/handler.lua"
click node_rules "https://github.com/pvnarp/kong-plugin-vard/blob/main/rules.example.yaml"
click node_verdict "https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/handler.lua"
click node_manifest_check "https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/handler.lua"
click node_drift "https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/handler.lua"
click node_approval_ui "https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/ui.lua"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_vard,node_rules,node_verdict toneBlue
class node_manifest_check,node_drift toneAmber
class node_approval_ui toneMint
class node_kong,node_mcp_server,node_ai_gateway toneRose
class node_agent,node_approver toneIndigo
```

## Components

### Gateway policy

- [Vard plugin](https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/handler.lua): `kong/plugins/vard/handler.lua`
- [Policy rules](https://github.com/pvnarp/kong-plugin-vard/blob/main/rules.example.yaml): `rules.example.yaml`
- [Call verdict](https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/handler.lua): `kong/plugins/vard/handler.lua`

### Manifest integrity

- [Manifest pinning](https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/handler.lua): `kong/plugins/vard/handler.lua`
- [Drift refusal](https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/handler.lua): `kong/plugins/vard/handler.lua`

### Human approval

- [Approvals UI](https://github.com/pvnarp/kong-plugin-vard/blob/main/kong/plugins/vard/ui.lua): `kong/plugins/vard/ui.lua`

### Runtime integrations

- **Kong Gateway**
- **MCP tool server**
- **AI Gateway**

### Other components

- **MCP agent**
- **Human approver**

## Connections

- MCP agent → Kong Gateway: sends MCP calls
- Kong Gateway → Vard plugin: invokes plugin
- Vard plugin → Policy rules: evaluates rules
- Vard plugin → Call verdict: scores call
- Call verdict → Kong Gateway: returns decision
- Kong Gateway → MCP tool server: proxies allowed calls
- Kong Gateway → Vard plugin: passes tool listings
- Vard plugin → Manifest pinning: hashes manifests
- Manifest pinning → Drift refusal: detects changes
- Drift refusal → Vard plugin: refuses next call
- Call verdict → Approvals UI: parks held calls
- Human approver → Approvals UI: reviews requests
- Approvals UI → Call verdict: releases decision
- Kong Gateway → AI Gateway: model-lane observer
