How the Integration Broker's Loopback Secret Broker Works with Per-Worker Capability Tokens

The loopback secret broker in Munder Difflin acts as a zero-knowledge bridge by binding exclusively to 127.0.0.1 and issuing ephemeral per-worker capability tokens that allow workers to invoke specific integrations without ever handling the underlying secrets.

The integration broker's loopback secret broker in the chaitanyagiri/munder-difflin repository provides cryptographic isolation between ephemeral worker processes and sensitive third-party credentials. Implemented in src/main/integrationBroker.ts, this lightweight HTTP server mediates all outbound integration traffic by validating opaque capability tokens and injecting real secrets only at the broker layer, ensuring workers operate with a strict need-to-know boundary.

Architecture Overview

The broker exposes a local-only HTTP endpoint that workers use as a proxy for all integration calls. When initialized via start() at src/main/integrationBroker.ts:87-102, the server binds to an OS-assigned port on the 127.0.0.1 interface, rendering it unreachable from external network interfaces. Workers construct request URLs using the pattern:


http://127.0.0.1:<port>/i/<integrationId>/<path>

Rather than authenticating with real integration secrets, workers present a per-worker capability token—a random 32-byte base64url opaque handle—in either the Authorization: Bearer header or the custom X-MD-Broker-Token header. The broker validates this token against an in-memory capability map, verifies the worker is authorized for the requested integration ID, decrypts the real secret internally, and forwards the sanitized request upstream.

Per-Worker Capability Token Lifecycle

Minting Tokens via grant()

When the main process spawns a worker, it calls grant(workerId, allowedIds) at src/main/integrationBroker.ts:26-35 to issue a new capability token. This method first revokes any existing token for the same worker ID to prevent token accumulation, then generates a cryptographically random 32-byte value encoded as base64url. The broker maintains two maps:

  • worker → token: Tracks the current token for each worker
  • token → capability: Stores the allowed integration IDs and grant timestamp

The returned token is injected into the worker's environment variables (typically MD_BROKER_TOKEN), while the broker URL is provided via MD_BROKER_URL.

Revoking Access via revoke()

Upon worker termination, the main process invokes revoke(workerId) at src/main/integrationBroker.ts:37-41. This removes the worker's token from both internal maps, ensuring that any in-flight or subsequent requests using that token will fail authentication. The cleanup is synchronous and absolute, preventing stale tokens from persisting in memory after worker exit.

Security Mechanisms and Isolation

Loopback Interface Enforcement

Before processing any request, the broker executes isLoopback() at src/main/integrationBroker.ts:68-73 to verify the connection originates from the local machine. The guard rejects any socket address that does not match 127.* IPv4 ranges or the IPv6 loopback ::1. This ensures that even if the port were exposed through firewall misconfiguration, remote hosts could not reach the secret broker.

Timing-Safe Token Validation

To prevent timing side-channel attacks, the broker implements resolveCapability() at src/main/integrationBroker.ts:44-51 using timingSafeEqual for token comparison. Rather than using standard string equality that short-circuits on mismatch, the function compares the presented token against stored entries in constant time, preventing attackers from inferring valid token prefixes through response timing analysis.

Integration Scope Authorization

After validating the token's authenticity, the broker checks authorization at src/main/integrationBroker.ts:89-92 by verifying that the requested <integrationId> exists in the capability's allowedIds array. This creates fine-grained per-worker access control: a worker granted capabilities for ['slack', 'github'] cannot access the linear integration even with a valid token.

Request Flow and Secret Injection

Token Extraction

Incoming requests trigger tokenFrom() at src/main/integrationBroker.ts:60-68, which extracts the capability token from either:

  • The Authorization header with Bearer prefix
  • The custom X-MD-Broker-Token header

If neither header is present, the broker immediately returns a 401 response.

Secret Resolution and Upstream Forwarding

Once authorized, the broker resolves the integration record via getRecord and decrypts the secret using getSecret at src/main/integrationBroker.ts:94-106. This decryption occurs exclusively inside the broker process; the worker never observes the real credential.

The forward() implementation at src/main/integrationBroker.ts:112-140 then:

  1. Sanitizes inbound headers by stripping authorization, host, and other hop-by-hop headers
  2. Constructs upstream authentication headers using buildAuthHeaders with the decrypted secret
  3. Streams the request body to the integration endpoint
  4. Scrubs sensitive response headers before returning the payload to the worker

This pipeline creates a zero-knowledge bridge: workers invoke integrations by path and ID alone, while the broker handles all cryptographic material.

Implementation Examples

Starting the Broker and Granting Capabilities

import { IntegrationBroker } from '@/main/integrationBroker';
import { getIntegrationRecord, decryptSecret } from '@/shared/integrations';

// Initialize with secret resolution dependencies
const broker = new IntegrationBroker({
  getRecord: getIntegrationRecord,
  getSecret: decryptSecret,
});

// Start loopback listener on OS-assigned port
await broker.start();  // Returns { ok: true, port: 53741 }
const brokerUrl = broker.url();  // "http://127.0.0.1:53741"

// Grant worker-42 access only to Slack integration
const workerId = 'worker-42';
const token = broker.grant(workerId, ['slack']);
// Token is passed to worker via environment variables

Worker Request Pattern

import fetch from 'node-fetch';

// Environment injected by main process
const brokerUrl = process.env.MD_BROKER_URL;   // http://127.0.0.1:53741
const token = process.env.MD_BROKER_TOKEN;     // opaque capability token

// Worker invokes Slack without knowing the real Slack token
await fetch(`${brokerUrl}/i/slack/postMessage`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ channel: '#general', text: 'Hello' }),
});

Token Revocation on Cleanup

// Main process cleanup when worker exits
broker.revoke('worker-42');
// Subsequent requests with this token now receive HTTP 401

Summary

  • The loopback secret broker binds exclusively to 127.0.0.1, ensuring only local processes can access the integration proxy.
  • Per-worker capability tokens are ephemeral 32-byte random handles that map to specific integration whitelists, not actual secrets.
  • The grant() and revoke() lifecycle methods provide fine-grained, time-bound access control for worker processes.
  • Timing-safe comparison via timingSafeEqual prevents side-channel attacks during token validation.
  • Real secrets are decrypted and injected only inside the broker's forward() method, maintaining a zero-knowledge architecture for workers.

Frequently Asked Questions

What happens if a worker tries to reuse a revoked capability token?

The broker returns an HTTP 401 Unauthorized response. When revoke(workerId) is called at src/main/integrationBroker.ts:37-41, the token is immediately deleted from both the worker-to-token and token-to-capability maps. Any subsequent request bearing that token fails the resolveCapability() lookup, rejecting the request before any secret material is accessed.

How does the broker enforce which integrations a worker can access?

During request processing at src/main/integrationBroker.ts:89-92, the broker compares the <integrationId> path segment against the allowedIds array stored in the capability map. If the integration ID is not present in the worker's granted capabilities, the broker rejects the request with a 403 Forbidden status, ensuring workers cannot pivot to unauthorized services even if they possess a valid token.

Why does the broker validate tokens using timingSafeEqual?

The resolveCapability() method at src/main/integrationBroker.ts:44-51 uses Node.js's timingSafeEqual to compare the presented token against stored entries in constant time. Standard string comparison operators short-circuit on the first mismatched character, potentially leaking information about valid token prefixes through timing analysis. Constant-time comparison eliminates this side channel.

Can the broker be configured to listen on interfaces other than loopback?

No. The isLoopback() guard at src/main/integrationBroker.ts:68-73 explicitly rejects any connection where socket.remoteAddress is not within the 127.0.0.0/8 range or the IPv6 loopback ::1. This hardening measure ensures that integration secrets remain inaccessible to network attackers even if the host firewall is misconfigured to expose the broker port.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →