---
name: fastgrc-policy-router
description: Use when building agent applications that need policy enforcement, compliance guardrails, or audit logging. Instructs how to call FastGRC Agent Policy Router to protect any agent task via ingress/egress evaluation, pass correlationId for audit threading, interpret skillGuidance in responses, trigger the FastGRC Copilot, and view audit logs in the FastGRC dashboard.
---

# FastGRC Agent Policy Router

FastGRC Agent Policy Router is a **standalone HTTP service** — fully decoupled from your agents. Any agent framework (Claude, LangChain, OpenAI, AutoGen, CrewAI, custom) consumes it with a single HTTP call. No SDK required.

## Getting started

1. Sign up at **https://fastgrc.ai** → Create account → Dashboard
2. Get an API key: Settings → API Keys → Create key (starts with `fgrc_k1_`)
3. Create a policy: Dashboard → Agent Policies → Create Policy → choose a template
4. Call the API from your agent code (examples below)

---

## Protecting agent tasks — ingress (before the agent acts)

Call **before** the agent processes any user task, prompt, plan, or tool argument.

```typescript
import crypto from "crypto";

const correlationId = crypto.randomUUID(); // generate once per user session

const response = await fetch("https://fastgrc.ai/api/v1/policy-router/evaluate", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.FASTGRC_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    action: "agent_task",
    subject_content: userMessage,
    subject_type: "task",       // task | prompt | plan | tool_argument
    agent_id: "my-agent-v1",
    correlation_id: correlationId, // ALWAYS include — this is the full audit thread
    direction: "ingress",          // default, can be omitted
  }),
});

const { decision, sessionId, skillGuidance } = await response.json();

if (decision === "block") {
  throw new Error("Policy blocked this action");
}
if (decision === "require_approval") {
  // pause and wait for human approval before continuing
}

// store sessionId to pass on the egress call
```

---

## Protecting agent outputs — egress (before returning to user)

Call **before** the agent response is returned to the user. Pass the same `correlationId` and the `sessionId` returned from the ingress call to link both decisions in the audit log.

```typescript
const egressResponse = await fetch("https://fastgrc.ai/api/v1/policy-router/evaluate", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.FASTGRC_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    action: "agent_response",
    subject_content: agentOutput,
    subject_type: "tool_result",  // use tool_result for all agent outputs
    agent_id: "my-agent-v1",
    correlation_id: correlationId,  // same ID as ingress
    session_id: sessionId,          // returned from ingress — links the pair
    direction: "egress",
  }),
});

const { decision, skillGuidance } = await egressResponse.json();

if (skillGuidance?.blockResponse) {
  return "[Response blocked by compliance policy]";
}
if (skillGuidance?.displayAlert) {
  console.warn("Policy alert:", skillGuidance.alertMessage);
}
if (skillGuidance?.escalate) {
  // route to FastGRC compliance agent: skillGuidance.escalateTo
}
```

---

## Interpreting `skillGuidance`

The `skillGuidance` object tells your application **how** to act on the decision, beyond just allow/block:

```typescript
skillGuidance?: {
  skill: string;           // "auto" | "monitor" | "alert" | "guard" | "strict"
  blockResponse: boolean;  // true → suppress agent response entirely
  displayAlert: boolean;   // true → show alert banner to user
  alertMessage?: string;   // suggested alert text for the banner
  escalate: boolean;       // true → route to FastGRC compliance agent
  escalateTo?: string;     // "compliance" | "risk" | "evidence" | "remediation"
  logEvent: boolean;       // always true — decision is always logged
}
```

Always check `skillGuidance` even on `allow` decisions — the policy may still want an alert displayed.

---

## CLI integration

```bash
# Install
npm install -g @fastgrc/router-cli

# Evaluate an agent action
fastgrc policy evaluate \
  --action "deploy to production" \
  --subject-type task \
  --agent-id "deploy-agent" \
  --correlation-id "$CORRELATION_ID" \
  --api-key "$FASTGRC_API_KEY"
```

---

## MCP integration (FastGRC Copilot)

Add the FastGRC MCP server to your Claude config so your coding assistant can call the policy router directly:

```json
{
  "mcpServers": {
    "fastgrc": {
      "command": "fastgrc",
      "args": ["mcp"],
      "env": {
        "FASTGRC_API_KEY": "<YOUR_API_KEY>",
        "FASTGRC_BASE_URL": "https://fastgrc.ai"
      }
    }
  }
}
```

Once configured, use the `fastgrc_evaluate_action` tool in any Claude conversation:

```
Use fastgrc_evaluate_action to check if I should run: deploy database migration to production
```

The FastGRC Copilot will evaluate the action against your policy and return a decision with reasoning.

---

## Viewing audit logs

Every evaluate call with a `correlationId` is logged. View all decisions for a session two ways:

**Dashboard:**
`https://fastgrc.ai/dashboard/agent-policies` → Decisions tab → filter by `correlation_id`

**REST API:**
```bash
curl -H "Authorization: Bearer $FASTGRC_API_KEY" \
  "https://fastgrc.ai/api/v1/policy-router/decisions?correlation_id=<your-correlation-id>"
```

The audit log shows: decision, confidence, matched rules, latency, direction (ingress/egress), and the full reasoning chain.

---

## Guardian Agent — zero-setup monitoring

FastGRC's **Guardian Agent** watches all policy router decisions automatically. It:

- Detects anomalies: high block rates, policy bypass attempts, unusual patterns
- Opens compliance incidents automatically — no configuration needed
- Sends alerts based on your notification settings

View incidents at: `https://fastgrc.ai/dashboard/incidents`

You don't need to set anything up. The Guardian Agent is always running.

---

## Subject types reference

| `subject_type` | Direction | When to use |
|---|---|---|
| `task` | ingress | User task or instruction to the agent |
| `prompt` | ingress | System prompt or injected instructions |
| `plan` | ingress | Agent's proposed plan before execution |
| `tool_argument` | ingress | Arguments being passed to a tool |
| `tool_result` | egress | Agent output / response to be returned to user |

---

## Targeting specific agent tasks

The policy router is fully decoupled — use it to protect any specific operation by specifying `action` and `subject_type` appropriately:

```typescript
// Protect a database write
await evaluatePolicy({ action: "write_to_database", subject_content: sqlQuery, subject_type: "tool_argument" });

// Protect a file system operation
await evaluatePolicy({ action: "delete_file", subject_content: filePath, subject_type: "tool_argument" });

// Protect an external API call
await evaluatePolicy({ action: "call_external_api", subject_content: requestPayload, subject_type: "task" });

// Screen an agent plan before execution
await evaluatePolicy({ action: "execute_plan", subject_content: agentPlan, subject_type: "plan" });
```

Use descriptive `action` strings — the policy engine matches them against your policy's `blocked_actions` and `require_approval_patterns`.

---

## Key rules

- **Always pass `correlationId`** — it's the thread that links every decision for a session in the audit log
- **correlationId is yours to generate** — use `crypto.randomUUID()`, a user session ID, or a request ID
- **sessionId is FastGRC's** — it's returned from ingress and passed back on egress to link the pair
- **ingress is the default** — omit `direction` or set `"ingress"` to evaluate before acting
- **egress is opt-in** — set `direction: "egress"` to evaluate before returning a response
- **Any decision can have `skillGuidance`** — always check it, even on `allow`
