Security Considerations for different-ai/openwork: Secret Redaction, Input Validation & Sandbox Design

OpenWork implements defense-in-depth security through automatic secret redaction, strict Zod schema validation, sandboxed development environments, and comprehensive boundary testing to prevent credential leakage across logs, telemetry, and error reports.

The different-ai/openwork repository is an enterprise-grade AI workbench that handles sensitive OAuth credentials, API keys, and JWT tokens. Its architecture prioritizes security by default—every component that processes secrets includes built-in redaction mechanisms. This article examines the security layers implemented across the MCP mock server, enterprise client, and observability pipelines, with direct source references.


Secret Redaction in Logs and Telemetry

Core Redaction Engine

The foundation of OpenWork's secret handling is redactText in enterprise-mcp-mock-server/src/observability/redaction.ts. This utility targets common credential patterns:

  • Bearer tokens and JWT signatures
  • Custom secret strings passed during server initialization
  • Overly-long messages (truncated to prevent data exfiltration)
// From enterprise-mcp-mock-server/src/observability/redaction.ts
// Lines 12-31 implement pattern-based matching with [REDACTED] substitution

The function operates non-destructively—original values remain in memory for legitimate use while sanitized copies flow to external systems.

Probe Message Sanitization

Test harnesses frequently need to verify secret handling without exposing real credentials. The redactProbeMessage function in enterprise-mcp-mock-server/src/testing/probe.ts (lines 288-295) iterates over a configurable secret list and replaces each occurrence before any output operation.

// Example: synthetic secrets in test probes are never echoed
const secrets = ['synthetic-test-client-secret-32-bytes'];
redactProbeMessage(rawMessage, secrets); // Returns scrubbed copy

Response Body Credential Masking

API responses often contain credential fields that must be excluded from excerpts. The redactedResponseBodyExcerpt function in enterprise-mcp-client/src/response-body-excerpt.ts (lines 17-44) applies regular expressions targeting keys like authorization, api_key, jwt, and client_secret.

This ensures that even when logging API responses for debugging, sensitive values never appear in plain text.

Recursive JSON Scrubbing

For arbitrary nested payloads, redactCredentialFields in ee/apps/inference/src/inference-reporting.ts (lines 125-149) traverses objects recursively. This handles edge cases where credentials are buried in deep structures that surface-level redaction might miss.

import { redactCredentialFields } from './inference-reporting';

const telemetryPayload = {
  user: { id: 'user-123' },
  metadata: {
    nested: {
      apiKey: 'sk-live-abc123',  // Deeply nested secret
    }
  }
};

const safePayload = redactCredentialFields(telemetryPayload);
// Result: apiKey replaced with [REDACTED]

Strict Input Validation for Secrets

Zod Schema Enforcement

OpenWork rejects malformed secret inputs before they enter the processing pipeline. In enterprise-mcp-mock-server/src/testing/probe.ts (lines 74-75), the OAuth configuration schema constrains:

  • client_secret: Must be a string or explicitly omitted
  • token_endpoint_auth_method: Restricted to ["none", "client_secret_post"]
// Schema definition prevents injection of unexpected auth methods
z.object({
  client_secret: z.string().optional(),
  token_endpoint_auth_method: z.enum(['none', 'client_secret_post'])
})

This fail-fast approach reduces attack surface by rejecting unknown authentication mechanisms at the boundary.


Sandboxed Development Environment

Electron Mock Keychain

The desktop application (dev/README.md, lines 96-98) supports OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN for development. This environment variable forces use of an in-memory mock credential store instead of the OS keychain, preventing accidental persistence of real credentials during local testing.

Isolated Development Profiles

Each worktree receives a dedicated profile directory via OPENWORK_DEV_PROFILE (lines 94-99). This filesystem isolation ensures:

  • Cross-profile data leakage is impossible
  • Secret caches from one development branch cannot contaminate another
  • Clean teardown between test runs

Network Boundary Controls

The enterprise MCP mock server (test/runtime.test.ts, lines 84-94) launches with automatic free-port assignment and configurable environment objects. Developers can restrict which APIs are exposed during testing, creating minimal network surfaces for secret-bearing traffic.


Observability and Error Reporting Security

Request/Response Scrubbing

The ee/apps/den-web/observability/scrub.ts module (lines 27-33) sanitizes HTTP traffic before it reaches any logging or telemetry destination. Query parameters become [redacted-query], headers are masked, and body fields matching credential patterns are stripped.

import { scrubRequest } from './observability/scrub';

const sanitized = scrubRequest({
  url: 'https://api.example.com/data?token=secret123',
  headers: { 'Authorization': 'Bearer jwt-token-xyz' }
});
// Output: token=[redacted-query], Authorization: [redacted]

Sentry Integration with Redaction

Third-party error aggregation is configured in ee/packages/utils/src/observability.ts (lines 48-51) to apply the same scrubbing rules. Even when crashes occur, Sentry events contain no recoverable secrets.


Security Boundary Testing

OpenWork includes deliberate leakage attempts to verify redaction effectiveness. The probe-boundaries.test.ts file (lines 68-78) implements tests that:

  1. Inject synthetic secrets into probe messages
  2. Process messages through the full pipeline
  3. Assert that output contains only [REDACTED] markers
// From probe-boundaries.test.ts - verifies secrets cannot escape
test('synthetic client_secret is never echoed', async () => {
  const secret = 'synthetic-test-client-secret-32-bytes';
  const result = await sendProbeWithSecret(secret);
  
  expect(result.output).not.toContain(secret);
  expect(result.output).toContain('[REDACTED]');
});

These tests act as a regression prevention mechanism, ensuring that future refactoring cannot accidentally disable redaction.


Practical Implementation Examples

Redacting Arbitrary Payloads for Custom Logging

import { redactCredentialFields } from '@/ee/apps/inference/src/inference-reporting';

function safeLog(label: string, payload: unknown): void {
  const redacted = redactCredentialFields(payload);
  console.log(`[${label}]`, JSON.stringify(redacted));
}

// Usage with nested sensitive data
safeLog('API_RESPONSE', {
  status: 200,
  data: {
    user: 'alice@example.com',
    refreshToken: 'eyJhbGciOiJIUzI1NiIs...'  // Automatically redacted
  }
});

Launching a Hardened Mock Server

import { createEnterpriseMcpMockServer } from 'enterprise-mcp-mock-server';

const server = createEnterpriseMcpMockServer({
  scenario: 'oauth-flow',
  secrets: {
    oauthClientSecret: process.env.TEST_CLIENT_SECRET  // Never logged
  },
  environment: {
    // Restrict available APIs
    ALLOWED_ENDPOINTS: '/token,/userinfo'
  }
});

// All internal logging automatically redacts oauthClientSecret

Configuring Development Sandboxing


# .env.development

OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=true
OPENWORK_DEV_PROFILE=/tmp/openwork-isolated-$(git rev-parse --abbrev-ref HEAD)

# Launch with network isolation

OPENWORK_MCP_PORT=0  # Auto-assign free port

Summary

  • Automatic redaction is woven throughout OpenWork: redactText, redactProbeMessage, redactedResponseBodyExcerpt, and redactCredentialFields ensure secrets never reach external systems
  • Zod schema validation enforces strict constraints on secret-related inputs, rejecting unexpected authentication methods early
  • Sandboxed development via mock keychains, isolated profiles, and controlled network boundaries prevents cross-contamination
  • Comprehensive scrubbing of HTTP traffic and error reports protects third-party observability integrations
  • Boundary tests continuously verify that synthetic secrets cannot leak through any processing path

These mechanisms operate by default—no opt-in configuration required—making secure handling the path of least resistance for developers extending the platform.


Frequently Asked Questions

How does OpenWork prevent secrets from appearing in error logs?

All telemetry flows through scrubRequest in ee/apps/den-web/observability/scrub.ts and redactCredentialFields in ee/apps/inference/src/inference-reporting.ts before external emission. The Sentry integration (ee/packages/utils/src/observability.ts) applies these same rules to crash reports, ensuring credential patterns are replaced with [redacted] placeholders regardless of error origin.

What authentication methods does the MCP mock server accept?

The Zod schema in enterprise-mcp-mock-server/src/testing/probe.ts (lines 74-75) restricts token_endpoint_auth_method to ["none", "client_secret_post"]. Unknown methods are rejected at validation time, preventing experimentation with less-secure or unintended authentication flows.

Can I use real credentials during OpenWork development?

The OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=true setting (documented in dev/README.md) substitutes an in-memory credential store for the OS keychain. Combined with OPENWORK_DEV_PROFILE for filesystem isolation, this allows realistic testing without persisting real secrets to developer machines.

How is secret redaction tested?

The probe-boundaries.test.ts suite injects synthetic secrets like synthetic-test-client-secret-32-bytes through complete request/response cycles, then asserts that outputs contain only [REDACTED] markers. These tests run in CI to prevent regression of redaction behavior across code changes.

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 →