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

> Discover OpenWork security features like secret redaction, input validation, and sandboxing. Protect your credentials and ensure safe development practices with this robust platform.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: security-best-practices
- Published: 2026-08-05

---

**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`](https://github.com/different-ai/openwork/blob/main/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)

```typescript
// 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`](https://github.com/different-ai/openwork/blob/main/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.

```typescript
// 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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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.

```typescript
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`](https://github.com/different-ai/openwork/blob/main/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"]`

```typescript
// 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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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.

```typescript
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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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

```typescript
// 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

```typescript
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

```typescript
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

```bash

# .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`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-web/observability/scrub.ts) and `redactCredentialFields` in [`ee/apps/inference/src/inference-reporting.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/inference/src/inference-reporting.ts) before external emission. The Sentry integration ([`ee/packages/utils/src/observability.ts`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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.