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 omittedtoken_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:
- Inject synthetic secrets into probe messages
- Process messages through the full pipeline
- 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, andredactCredentialFieldsensure 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →