# How Local Managed MCP Connections Interact with the URL Guard Mechanism in OpenWork

> Discover how OpenWork's local managed MCP connections use a dual-layer system to interact with URL guard, blocking SSRF attacks with configurable private network exemptions.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: internals
- Published: 2026-08-22

---

**Local managed MCP connections interact with OpenWork's URL guard through a dual-layer validation system that checks URLs during initial connection registration and re-validates every runtime request to block SSRF attacks, with configurable exemptions for private networks via environment variables.**

OpenWork's Den server utilizes the Multi-Connector Platform (MCP) to register external service connections by storing URLs in its database. Because the server fetches these URLs on behalf of users during both capability discovery and tool invocation, **local managed MCP connections** are protected by a comprehensive URL guard mechanism. This security layer prevents Server-Side Request Forgery (SSRF) attacks while allowing controlled access to internal resources through explicit environment configuration.

## URL Guard Architecture and Core Implementation

The URL guard mechanism lives in [`ee/apps/den-api/src/capability-sources/url-guard.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/capability-sources/url-guard.ts) and provides two primary fetch wrappers that enforce security boundaries for all outbound MCP requests.

### Core Protection Components

The guard implements `createGuardedFetch()`, which combines **public URL validation** with **redirect safety checks**. The `assertPublicUrl` function enforces HTTPS protocol requirements, rejects URLs containing embedded credentials, and ensures hostnames resolve exclusively to public IP addresses (lines 73-78). Additionally, `createRedirectSafeFetch` wraps outbound requests to re-validate URLs on every redirect, blocking protocol downgrades, private-to-public redirects, and cross-origin redirects that carry request bodies (lines 33-74).

## Two-Stage Protection for MCP Connections

The interaction between local managed MCP connections and the URL guard occurs at two distinct stages: initial connection discovery and ongoing runtime execution.

### Connection Discovery and Validation

When administrators register new external MCP connections in [`ee/apps/den-api/src/routes/org/mcp-connections.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/routes/org/mcp-connections.ts), the system first validates the URL structure using the Zod schema `externalMcpUrlSchema` (lines 40-75). After schema validation, the discovery request executes through `externalMcpDiscoveryFetch`, defined conditionally as:

```typescript
env.allowPrivateMcpUrls ? createRealmSafeFetch() : createGuardedFetch()

```

This logic appears at lines 28-29 and determines whether the connection discovery uses full SSRF protection or the relaxed "realm-safe" variant. For standard deployments, `createGuardedFetch()` applies `assertPublicUrl` to confirm the target is publicly accessible before allowing the connection record creation.

### Runtime DNS Rebinding Protection

Every subsequent MCP tool invocation re-applies the same guard mechanism. The MCP client receives the `externalMcpDiscoveryFetch` wrapper during initialization, ensuring that lines 34-38 of the connection routes inject the protected fetch instance into the SDK. This design protects against **DNS rebinding attacks** where a malicious actor later changes DNS records to point a previously validated domain toward a private IP address. The runtime wrapper calls `assertPublicUrl` before each request and on every redirect, maintaining consistent SSRF protection throughout the connection lifecycle.

## Private Network Configuration and Opt-Out

Self-hosted OpenWork deployments that legitimately communicate with internal services can bypass public IP restrictions while maintaining other safety checks.

### Environment Variable Controls

Setting `DEN_ALLOW_PRIVATE_MCP_URLS=1` in the environment configuration modifies the fetch behavior in [`url-guard.ts`](https://github.com/different-ai/openwork/blob/main/url-guard.ts) (lines 15-27). This flag swaps `createGuardedFetch()` for `createRealmSafeFetch()`, which enforces HTTPS protocol validation and header sanitization but **skips the DNS/IP address checks** that block private network access. Additionally, running in development mode with `OPENWORK_DEV_MODE=1` automatically bypasses the guard entirely.

### Realm-Safe vs. Guarded Fetch

- **`createGuardedFetch()`**: Full SSRF protection with public IP validation, credential rejection, and redirect analysis.
- **`createRealmSafeFetch()`**: Protocol and header safety only, permitting connections to private IP ranges suitable for internal enterprise networks.

## Implementation Examples

The following patterns demonstrate how the URL guard integrates with MCP connection workflows:

### 1. Adding a New External MCP Connection

When administrators create connections through the admin UI, the system validates input through Zod before executing the discovery fetch:

```typescript
import { externalMcpDiscoveryFetch } from '../../capability-sources/url-guard.js';

await externalMcpDiscoveryFetch(async (url) => {
  // Throws PrivateUrlError for private or malformed URLs
  const resp = await fetch(url);
  return resp.json();
});

```

### 2. Runtime Tool Invocation

The MCP client uses the same guarded fetch wrapper for all tool calls, ensuring continuous protection:

```typescript
import { createGuardedFetch } from '../../capability-sources/url-guard.js';

const guardedFetch = createGuardedFetch(); // default = guarded
const response = await guardedFetch('https://api.example.com/tool', { 
  method: 'POST' 
});
// Re-checks redirects and DNS changes; private addresses trigger PrivateUrlError

```

### 3. Bypassing for Self-Hosted Setups

Configure the environment variable to enable internal API access:

```typescript
// In .env or Docker: DEN_ALLOW_PRIVATE_MCP_URLS=1
// Code automatically selects realm-safe version
const safeFetch = env.allowPrivateMcpUrls 
  ? createRealmSafeFetch() 
  : createGuardedFetch();

```

## Summary

- **Dual validation**: Local managed MCP connections undergo URL validation during initial registration and runtime execution to prevent SSRF and DNS rebinding attacks.
- **Core files**: The guard logic resides in [`ee/apps/den-api/src/capability-sources/url-guard.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/capability-sources/url-guard.ts) and is applied in [`ee/apps/den-api/src/routes/org/mcp-connections.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/routes/org/mcp-connections.ts).
- **Strict defaults**: `createGuardedFetch()` enforces public IP resolution, HTTPS-only protocols, and safe redirect handling for all connections.
- **Controlled exemptions**: Self-hosted deployments use `DEN_ALLOW_PRIVATE_MCP_URLS=1` to switch to `createRealmSafeFetch()`, maintaining protocol safety while allowing private network access.
- **Development flexibility**: `OPENWORK_DEV_MODE=1` completely bypasses the guard for local testing scenarios.

## Frequently Asked Questions

### What is the URL guard mechanism in OpenWork?

The URL guard is an SSRF protection system implemented in the Den server that validates all outbound URLs requested by local managed MCP connections. It ensures that the server only communicates with publicly accessible endpoints by verifying IP addresses, protocols, and redirect chains through the `createGuardedFetch()` wrapper.

### How does the URL guard prevent SSRF during MCP tool calls?

The guard prevents SSRF by applying `assertPublicUrl` checks before every HTTP request and during every redirect, blocking attempts to access private IP ranges (10.0.0.0/8, 192.168.0.0/16, etc.). This protects against DNS rebinding where an attacker changes DNS records after initial validation to point toward internal resources.

### Can I disable the URL guard for internal API connections?

Yes, self-hosted deployments can disable public IP restrictions by setting the environment variable `DEN_ALLOW_PRIVATE_MCP_URLS=1`. This switches the system from `createGuardedFetch()` to `createRealmSafeFetch()`, which maintains HTTPS and header validation while allowing connections to private networks. Development mode (`OPENWORK_DEV_MODE=1`) also bypasses the guard.

### What is the difference between createGuardedFetch and createRealmSafeFetch?

`createGuardedFetch()` provides complete SSRF protection including DNS resolution checks that reject private IP addresses, while `createRealmSafeFetch()` enforces protocol security (HTTPS) and redirect safety but skips the IP address validation. The latter is designed for enterprise deployments where MCP tools legitimately access internal services behind the firewall.