@relayer-ws/mtls-proxy-sdk
v1.0.1
Published
Cloudflare Worker SDK for mTLS Proxy
Maintainers
Readme
mTLS Proxy SDK for Cloudflare Workers
A TypeScript SDK that makes it easy to use mTLS proxy functionality from Cloudflare Workers. This SDK handles certificate management and automatic header configuration for proxying requests through an mTLS-enabled Lambda function.
Features
- 🔐 mTLS Support: Automatic client certificate handling
- 🌐 Cloudflare Worker Compatible: Built specifically for Cloudflare Workers
- 📦 TypeScript First: Full TypeScript support with comprehensive type definitions
- 🚀 Easy to Use: Simple API with convenient helper methods
- ⚡ Performance: Optimized for Cloudflare Workers runtime
- 🔧 Flexible: Support for all HTTP methods and custom headers
Installation
npm install @relayer-ws/mtls-proxy-sdkQuick Start
Using the Fetch API (Recommended)
The easiest way to use the SDK is with the fetch-like API:
import { createMtlsFetch } from '@relayer-ws/mtls-proxy-sdk';
// Create an mTLS fetch function
const mtlsFetch = createMtlsFetch({
clientCert: '-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----',
clientKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----'
});
// Use it just like the native fetch API
const response = await mtlsFetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json'
},
body: JSON.stringify({ message: 'Hello World' })
});
const data = await response.json();
console.log(data);Using the Client Class
import { MtlsProxyClient } from '@relayer-ws/mtls-proxy-sdk';
// Create a proxy client with default proxy URL (https://gw.relayer.ws/mtls)
const proxy = new MtlsProxyClient({
clientCert: '-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----',
clientKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----'
});
// Or with custom proxy URL
const proxy = new MtlsProxyClient({
proxyUrl: 'https://your-lambda-url.amazonaws.com',
clientCert: '-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----',
clientKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----'
});
// Make a proxied request
const response = await proxy.get('https://api.example.com/data', {
'Authorization': 'Bearer your-token'
});
console.log(response.status); // 200
console.log(response.body); // Response dataUsing Environment Variables
import { createMtlsFetch } from '@relayer-ws/mtls-proxy-sdk';
// In your Cloudflare Worker
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Create mTLS fetch from environment variables
const mtlsFetch = createMtlsFetch({
proxyUrl: env.MTLS_PROXY_URL, // Optional - defaults to https://gw.relayer.ws/mtls
clientCert: env.MTLS_CLIENT_CERT,
clientKey: env.MTLS_CLIENT_KEY,
timeout: env.MTLS_TIMEOUT ? parseInt(env.MTLS_TIMEOUT, 10) : undefined,
userAgent: env.MTLS_USER_AGENT
});
// Use it just like fetch
const response = await mtlsFetch('https://api.example.com/webhook', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ message: 'Hello World' })
});
return response;
}
};API Reference
createMtlsFetch
Creates an mTLS fetch function that works exactly like the native fetch API.
function createMtlsFetch(config: MtlsProxyConfig): (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>Parameters:
config: Configuration object (same as MtlsProxyClient)
Returns: A fetch-like function that can be used exactly like the native fetch API.
Example:
const mtlsFetch = createMtlsFetch({
clientCert: '-----BEGIN CERTIFICATE-----...',
clientKey: '-----BEGIN PRIVATE KEY-----...'
});
// Use exactly like fetch
const response = await mtlsFetch('https://api.example.com/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ data: 'value' })
});
const result = await response.json();MtlsProxyClient
The main client class for making mTLS proxy requests.
Constructor
new MtlsProxyClient(config: MtlsProxyConfig)Configuration
interface MtlsProxyConfig {
/** The URL of the mTLS proxy Lambda function (default: https://gw.relayer.ws/mtls) */
proxyUrl?: string;
/** Client certificate in PEM format */
clientCert: string;
/** Client private key in PEM format */
clientKey: string;
/** Optional timeout for requests (default: 30000ms) */
timeout?: number;
/** Optional user agent string */
userAgent?: string;
}Methods
request(options: ProxyRequestOptions): Promise<ProxyResponse>
Make a custom proxied request.
const response = await proxy.request({
targetUrl: 'https://api.example.com',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ data: 'value' }),
timeout: 10000
});get(targetUrl: string, headers?: Record<string, string>): Promise<ProxyResponse>
Make a GET request.
const response = await proxy.get('https://api.example.com/users');post(targetUrl: string, body?: string | ArrayBuffer | ReadableStream, headers?: Record<string, string>): Promise<ProxyResponse>
Make a POST request.
const response = await proxy.post(
'https://api.example.com/users',
JSON.stringify({ name: 'John Doe' }),
{ 'Content-Type': 'application/json' }
);put(targetUrl: string, body?: string | ArrayBuffer | ReadableStream, headers?: Record<string, string>): Promise<ProxyResponse>
Make a PUT request.
delete(targetUrl: string, headers?: Record<string, string>): Promise<ProxyResponse>
Make a DELETE request.
patch(targetUrl: string, body?: string | ArrayBuffer | ReadableStream, headers?: Record<string, string>): Promise<ProxyResponse>
Make a PATCH request.
Response Format
interface ProxyResponse {
/** HTTP status code */
status: number;
/** HTTP status text */
statusText: string;
/** Response headers */
headers: Record<string, string>;
/** Response body */
body: string;
/** Whether the response body is base64 encoded */
isBase64Encoded: boolean;
}Cloudflare Worker Example
Here's a complete example of using the SDK in a Cloudflare Worker:
import { createMtlsProxyClientFromEnv } from '@relayer-ws/mtls-proxy-sdk';
interface Env {
MTLS_PROXY_URL?: string; // Optional - defaults to https://gw.relayer.ws/mtls
MTLS_CLIENT_CERT: string;
MTLS_CLIENT_KEY: string;
MTLS_TIMEOUT?: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
try {
// Create proxy client from environment variables
const proxy = createMtlsProxyClientFromEnv(env);
// Parse the incoming request
const url = new URL(request.url);
const targetUrl = url.searchParams.get('target');
if (!targetUrl) {
return new Response('Missing target parameter', { status: 400 });
}
// Forward the request through the mTLS proxy
const response = await proxy.request({
targetUrl,
method: request.method,
headers: Object.fromEntries(request.headers.entries()),
body: request.body
});
// Return the proxied response
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: response.headers
});
} catch (error) {
console.error('Proxy error:', error);
return new Response('Internal Server Error', { status: 500 });
}
}
};Error Handling
The SDK provides comprehensive error handling:
try {
const response = await proxy.get('https://api.example.com');
} catch (error) {
if (error.message.includes('timeout')) {
console.error('Request timed out');
} else if (error.message.includes('Invalid targetUrl')) {
console.error('Invalid URL provided');
} else {
console.error('Request failed:', error.message);
}
}Security Considerations
- Certificate Storage: Store your client certificates securely in Cloudflare Workers secrets or environment variables
- HTTPS Only: Always use HTTPS URLs for both the proxy and target endpoints
- Certificate Validation: The SDK validates certificate format but doesn't validate certificate chains
- Header Filtering: Sensitive headers like
X-Mtls-CertandX-Mtls-Keyare automatically filtered from upstream requests
Browser Testing
You can test the SDK functionality in your browser using the included test page:
# Start the test server
npm run test:browser
# Or from the root directory
yarn test:mtlsThis will open a browser test page at http://localhost:3001 where you can:
- Configure the SDK settings
- Test different HTTP methods
- See simulated responses
- Experiment with the API before implementing in your Cloudflare Worker
License
MIT
