Camofox-Browser OpenClaw Skill-Scanner Rule Isolation: Environment Variables vs Child Process Separation
Camofox-browser enforces OpenClaw skill-scanner rule isolation by strictly segregating all process.env access into lib/config.js while confining every child_process import and execution to lib/launcher.js and lib/youtube.js, guaranteeing no single file mixes environment harvesting with network operations or dangerous subprocess calls.
The jo-inc/camofox-browser repository implements a rigorous module-boundary architecture to satisfy OpenClaw’s static analysis requirements. By decoupling environment-variable configuration from subprocess execution and network logic, the codebase eliminates false-positive security alerts while maintaining clean separation of concerns.
OpenClaw Skill-Scanner Rules Explained
OpenClaw identifies problematic code patterns through three specific security rules. The env-harvesting rule (CRITICAL) flags any file containing both process.env references and network-related calls such as fetch, http.request, or HTTP method strings like 'POST'. The dangerous-exec rule (CRITICAL) triggers when a file imports child_process and subsequently invokes exec or spawn. The potential-exfiltration rule (WARN) monitors for filesystem reads combined with network operations.
Camofox-browser satisfies these constraints through strict physical file separation, ensuring that sensitive capabilities never coexist within the same module scope.
Centralized Environment Configuration
All environment variable access is centralized in lib/config.js. This module exports a plain JavaScript object containing values derived from process.env, such as prometheusEnabled: process.env.PROMETHEUS_ENABLED === '1'. Crucially, this file contains no HTTP request helpers, no network method strings, and no child_process imports.
// lib/config.js
const config = {
prometheusEnabled: process.env.PROMETHEUS_ENABLED === '1',
// other env vars …
};
module.exports = config;
By isolating these reads entirely, the env-harvesting rule never triggers because lib/config.js lacks any network functionality that could exfiltrate credentials.
Isolated Child Process Execution
Subprocess logic is confined to two specialized modules that never touch environment variables. lib/launcher.js provides a generic wrapper around child_process.spawn for arbitrary command execution:
// lib/launcher.js
const { spawn } = require('child_process');
function launch(command, args, opts = {}) {
return spawn(command, args, { stdio: 'pipe', ...opts });
}
module.exports = { launch };
lib/youtube.js handles YouTube transcript extraction via yt-dlp using child_process.execFile. Neither module references process.env directly or performs HTTP requests, cleanly satisfying the dangerous-exec rule.
Clean Integration via the Server Layer
The server.js file serves as the Express routing layer that orchestrates the application without violating isolation boundaries. It imports the centralized configuration and the launcher utility but contains neither direct process.env reads nor child_process usage:
// server.js
const express = require('express');
const { launch } = require('./lib/launcher');
const config = require('./lib/config');
const app = express();
app.post('/youtube/transcript', async (req, res) => {
const { videoId } = req.body;
const yt = launch('yt-dlp', ['--write-subs', '--skip-download', videoId]);
// … handle output …
});
Supporting utilities maintain the same discipline. lib/request-utils.js contains HTTP method strings ('POST', 'GET') but no environment access, while lib/metrics.js lazily loads the Prometheus client based on the config flag without embedding HTTP literals. File-system operations like cookie I/O reside exclusively in lib/cookies.js, which never initiates network requests, preventing potential-exfiltration warnings.
Summary
- Environment isolation: All
process.envreferences live exclusively inlib/config.js, separated from network code. - Execution isolation: All
child_processusage is restricted tolib/launcher.jsandlib/youtube.js, with no access to sensitive configuration. - Clean boundaries: The Express server (
server.js) imports functional modules but mixes no concerns internally. - Static analysis compliance: No single file contains the forbidden pattern combinations required to trigger OpenClaw’s critical rules.
Frequently Asked Questions
What triggers the OpenClaw env-harvesting rule?
The env-harvesting rule flags any file containing both process.env references and network operations such as fetch, http.request, or HTTP method strings. Camofox-browser prevents this by keeping all environment reads in lib/config.js, which exclusively handles configuration exports without network functionality.
Why does dangerous-exec require module separation?
The dangerous-exec rule identifies files importing child_process and subsequently calling exec or spawn, as this pattern could indicate unauthorized command execution. By moving these calls into dedicated modules like lib/launcher.js and ensuring they never access environment variables, the codebase proves each subprocess launch is intentional and controlled.
How does camofox-browser handle metrics without violating isolation?
The lib/metrics.js module checks the prometheusEnabled value (sourced from lib/config.js) to conditionally load the Prometheus client. Because the module contains no HTTP method literals or direct process.env reads, it avoids triggering either the env-harvesting or potential-exfiltration rules.
Can this isolation pattern prevent actual credential leaks?
While the primary design goal is satisfying OpenClaw’s static analysis to eliminate false positives, the enforced separation naturally limits the attack surface. Credentials never pass through modules that execute shell commands, and subprocess modules cannot accidentally exfiltrate environment secrets via network calls embedded in the same file.
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 →