Skip to content
Back to skills

072 Configuration Ab845f2c

ASecurity

Setup and configuration for Cloudflare TURN service in Workers and applications.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
securitytypescriptgobashapisecurity

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 072-configuration_ab845f2c --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 072 Configuration Ab845f2c?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 072 Configuration Ab845f2c
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-072-configuration-ab845f2c/badge)](https://www.skillsdirectory.com/skills/tools-only-072-configuration-ab845f2c)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# TURN Configuration

Setup and configuration for Cloudflare TURN service in Workers and applications.

## Environment Variables

```bash
# .env
CLOUDFLARE_ACCOUNT_ID=your_account_id
CLOUDFLARE_API_TOKEN=your_api_token
TURN_KEY_ID=your_turn_key_id
TURN_KEY_SECRET=your_turn_key_secret
```

Validate with zod:

```typescript
import { z } from 'zod'

const envSchema = z.object({
  CLOUDFLARE_ACCOUNT_ID: z.string().min(1),
  CLOUDFLARE_API_TOKEN: z.string().min(1),
  TURN_KEY_ID: z.string().min(1),
  TURN_KEY_SECRET: z.string().min(1),
})

export const config = envSchema.parse(process.env)
```

## wrangler.jsonc

```jsonc
{
  "name": "turn-credentials-api",
  "main": "src/index.ts",
  "compatibility_date": "2025-01-01",
  "vars": {
    "TURN_KEY_ID": "your-turn-key-id", // Non-sensitive, can be in vars
  },
  "env": {
    "production": {
      "kv_namespaces": [
        {
          "binding": "CREDENTIALS_CACHE",
          "id": "your-kv-namespace-id",
        },
      ],
    },
  },
}
```

**Store secrets separately**:

```bash
wrangler secret put TURN_KEY_SECRET
```

## Cloudflare Worker Integration

### Worker Binding Types

```typescript
interface Env {
  TURN_KEY_ID: string
  TURN_KEY_SECRET: string
  CREDENTIALS_CACHE?: KVNamespace
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // See patterns.md for implementation
  },
}
```

### Basic Worker Example

```typescript
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.url.endsWith('/turn-credentials')) {
      // Validate client auth
      const authHeader = request.headers.get('Authorization')
      if (!authHeader) {
        return new Response('Unauthorized', { status: 401 })
      }

      const response = await fetch(
        `https://rtc.live.cloudflare.com/v1/turn/keys/${env.TURN_KEY_ID}/credentials/generate`,
        {
          method: 'POST',
          headers: {
            Authorization: `Bearer ${env.TURN_KEY_SECRET}`,
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ ttl: 3600 }),
        },
      )

      if (!response.ok) {
        return new Response('Failed to generate credentials', { status: 500 })
      }

      const data = await response.json()

      // Filter port 53 for browser clients
      const filteredUrls = data.iceServers.urls.filter((url: string) => !url.includes(':53'))

      return Response.json({
        iceServers: [
          { urls: 'stun:stun.cloudflare.com:3478' },
          {
            urls: filteredUrls,
            username: data.iceServers.username,
            credential: data.iceServers.credential,
          },
        ],
      })
    }

    return new Response('Not found', { status: 404 })
  },
}
```

## IP Allowlisting (Enterprise/Firewall)

For strict firewalls, allowlist these IPs for `turn.cloudflare.com`:

| Type | Address               | Protocol |
| ---- | --------------------- | -------- |
| IPv4 | 141.101.90.1/32       | All      |
| IPv4 | 162.159.207.1/32      | All      |
| IPv6 | 2a06:98c1:3200::1/128 | All      |
| IPv6 | 2606:4700:48::1/128   | All      |

**IMPORTANT**: These IPs may change with 14-day notice. Monitor DNS:

```bash
# Check A and AAAA records
dig turn.cloudflare.com A
dig turn.cloudflare.com AAAA
```

Set up automated monitoring to detect IP changes and update allowlists within 14 days.

## IPv6 Support

- **Client-to-TURN**: Both IPv4 and IPv6 supported
- **Relay addresses**: IPv4 only (no RFC 6156 support)
- **TCP relaying**: Not supported (RFC 6062)

Clients can connect via IPv6, but relayed traffic uses IPv4 addresses.

## TLS Configuration

### Supported TLS Versions

- TLS 1.1
- TLS 1.2
- TLS 1.3

### Recommended Ciphers (TLS 1.3)

- AEAD-AES128-GCM-SHA256
- AEAD-AES256-GCM-SHA384
- AEAD-CHACHA20-POLY1305-SHA256

### Recommended Ciphers (TLS 1.2)

- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-SHA (also TLS 1.1)
- AES128-GCM-SHA256

## See Also

- [api.md](./api.md) - TURN key creation, credential generation API
- [patterns.md](./patterns.md) - Full Worker implementation patterns
- [gotchas.md](./gotchas.md) - Security best practices, troubleshooting

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.