Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Feb 10, 2026

  • Mitigation 1: /proc/self/environ protection via token cache file + LD_PRELOAD constructor
  • Mitigation 2: Docker Compose file redaction via redactComposeSecrets()
  • Unit tests for redactComposeSecrets() and workflow ordering
  • Fix CRITICAL: Don't delete cache file in constructor — let exit trap clean it up (fixes exec chain token loss)
  • Add GITHUB_PERSONAL_ACCESS_TOKEN to all three token lists for alignment
  • Replace echo with printf '%s\n' for robust token value writing
  • Extract duplicated scrubbing logic into scrub_sensitive_tokens() shell function
  • Add explanation for why redaction must stay after startContainers() (Docker needs to read compose file)
  • Update documentation (README, code comments) to reflect non-deletion of cache file
  • Code review (0 issues) and security scan (0 alerts)
Original prompt

This section details on the original issue you should resolve

<issue_title>fix: restrict /proc/self/environ and docker-compose.yml secret exposure</issue_title>
<issue_description>## Summary

PR #607 adds runtime configuration for the one-shot token library (AWF_ONE_SHOT_TOKENS), which addresses secret leaking via getenv() (path 1 of the attack surface identified in githubnext/gh-aw-security#62).

However, two additional exposure paths remain unmitigated:

1. /proc/self/environ bypasses LD_PRELOAD

The kernel exposes all environment variables of a process through /proc/self/environ. Reading this file directly bypasses getenv() entirely, so the LD_PRELOAD one-shot token library cannot intercept it.

cat /proc/self/environ | tr '\0' '\n' | grep COPILOT_GITHUB_TOKEN

2. Docker Compose file contains plaintext tokens

AWF writes sensitive tokens (e.g., COPILOT_GITHUB_TOKEN) in plaintext into the generated docker-compose.yml at /tmp/awf-*/docker-compose.yml. Since the host filesystem is mounted into the container at /host, the agent can read:

cat /host/tmp/awf-*/docker-compose.yml | grep -A 2 COPILOT_GITHUB_TOKEN

Proposed Mitigations

  1. /proc/self/environ: Mount procfs with restricted access, or overwrite sensitive env vars in the process environment before executing the agent command (after the legitimate consumer has read them).

  2. Docker Compose file: Either:

    • Remove/redact sensitive values from the compose file after containers start
    • Use Docker secrets instead of environment variables
    • Restrict the /host mount to exclude /tmp/awf-*
    • Make the workdir path inaccessible from within the container

Related

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Fix exposure of secrets in environ and docker-compose.yml fix: restrict /proc/self/environ and docker-compose.yml secret exposure Feb 10, 2026
Copilot AI requested a review from Mossaka February 10, 2026 21:23
@Mossaka Mossaka marked this pull request as ready for review February 10, 2026 21:24
Copilot AI review requested due to automatic review settings February 10, 2026 21:24
@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Chroot tests failed Smoke Chroot failed - See logs for details.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

💫 TO BE CONTINUED... Smoke Claude failed! Our hero faces unexpected challenges...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

📰 DEVELOPING STORY: Smoke Copilot reports failed. Our correspondents are investigating the incident...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 82.18% 82.32% 📈 +0.14%
Statements 82.24% 82.37% 📈 +0.13%
Functions 81.95% 82.05% 📈 +0.10%
Branches 74.54% 74.64% 📈 +0.10%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/docker-manager.ts 83.3% → 83.7% (+0.49%) 82.7% → 83.2% (+0.50%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

@github-actions
Copy link
Contributor

Security Review: Token Cache File Race Condition

I've reviewed PR #647 and found one security concern that should be addressed before merging.

⚠️ Issue: Race Condition in Token Cache File Deletion

Location: containers/agent/one-shot-token/one-shot-token.c:253-257

Vulnerability:
The token cache file mechanism has a time-of-check-to-time-of-use (TOCTOU) race window where malicious code could potentially read plaintext secrets:

  1. entrypoint.sh creates /tmp/.awf-token-cache-$$ with plaintext tokens (mode 0600)
  2. LD_PRELOAD constructor reads the file
  3. Constructor deletes the file with unlink(cache_path)

Attack vector:

  • Malicious code could fork before the LD_PRELOAD constructor completes
  • Child process reads /tmp/.awf-token-cache-$$ (PID is observable via /proc/self/status)
  • Race window exists between file creation and deletion (typically milliseconds, but exploitable)

Code:

/* Delete the cache file immediately to minimize exposure */
if (unlink(cache_path) == 0) {
    fprintf(stderr, "[one-shot-token] Token cache file deleted: %s\n", cache_path);
} else {
    fprintf(stderr, "[one-shot-token] WARNING: Could not delete token cache file: %s\n", cache_path);
}

Recommended Mitigations

Option 1: Use O_TMPFILE (Linux 3.11+)
Create the file with O_TMPFILE flag for anonymous temporary files that never appear in the filesystem namespace:

int fd = open("/tmp", O_TMPFILE | O_RDWR | O_EXCL, 0600);

Option 2: Use memfd_create() (Linux 3.17+)
Create an in-memory file descriptor that's never written to disk:

int fd = memfd_create("awf-token-cache", MFD_CLOEXEC);

Option 3: Add File Locking (Minimum)
Use flock() to prevent concurrent reads during the critical section:

int fd = open(cache_path, O_RDONLY);
flock(fd, LOCK_EX);  // Exclusive lock
// ... read tokens ...
flock(fd, LOCK_UN);
close(fd);
unlink(cache_path);

Option 4: Unix Domain Socket
Pass tokens via Unix domain socket with SCM_RIGHTS instead of filesystem-based cache.

Severity Assessment

Severity: Medium

  • Requires: Code execution inside container + precise timing
  • Impact: Secret exfiltration (GitHub tokens, API keys)
  • Likelihood: Low (tight race window) but exploitable with fork-based attacks

Other Security Aspects ✅

The following security measures are properly implemented:

  • Environment variable scrubbing (unset after caching)
  • docker-compose.yml redaction (***REDACTED***)
  • File permissions (mode 0600 via umask 077)
  • Eager constructor-based caching
  • Token list alignment across components

Recommendation: Address the TOCTOU race condition before merging, preferably using O_TMPFILE or memfd_create() for truly secure token passing.

AI generated by Security Guard

- Add forward declarations for get_token_index() and
  format_token_value() in one-shot-token.c. The constructor
  and load_token_cache_file() call these before their
  definitions, causing implicit declaration errors with -Wall.

- Write docker-compose.yml with mode 0600 so the agent
  container (running as awfuser) cannot read plaintext
  secrets via /host mount. Eliminates the TOCTOU window.

- Fix TOCTOU in redactComposeSecrets: replace existsSync +
  readFileSync with single readFileSync in try/catch.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

📰 DEVELOPING STORY: Smoke Copilot reports failed. Our correspondents are investigating the incident...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Chroot tests failed Smoke Chroot failed - See logs for details.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

💫 TO BE CONTINUED... Smoke Claude failed! Our hero faces unexpected challenges...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

🌑 The shadows whisper... Smoke Codex failed. The oracle requires further meditation...

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements two security mitigations to prevent secret exfiltration from the AWF agent container: (1) scrubbing sensitive environment variables from /proc/self/environ using a token cache file mechanism, and (2) redacting secrets from docker-compose.yml after containers start to prevent exposure via the /host mount.

Changes:

  • Added token cache file mechanism: entrypoint.sh writes token values to a temporary file (mode 0600), unsets env vars before exec; LD_PRELOAD library constructor reads the cache file, populates in-memory cache, and immediately deletes it
  • Added __attribute__((constructor)) to one-shot-token.c to eagerly cache and scrub tokens from environ on library load, ensuring /proc/self/environ never exposes secrets
  • Added redactComposeSecrets() function in docker-manager.ts that replaces sensitive values in docker-compose.yml with ***REDACTED*** using regex patterns
  • Integrated redaction into workflow between startContainers() and runAgentCommand() execution

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/docker-manager.ts Added SENSITIVE_ENV_NAMES set and redactComposeSecrets() function to redact secrets from docker-compose.yml
src/docker-manager.test.ts Added comprehensive tests for redaction function covering various YAML formats and edge cases
src/cli.ts Added redactComposeSecrets to workflow dependencies passed to runMainWorkflow
src/cli-workflow.ts Integrated redactComposeSecrets call after container startup to redact secrets before agent command execution
src/cli-workflow.test.ts Updated workflow tests to verify redaction happens in correct sequence
containers/agent/one-shot-token/one-shot-token.c Added constructor with token cache file loading and eager environ scrubbing
containers/agent/one-shot-token/README.md Updated documentation to describe token cache file mechanism and constructor behavior
containers/agent/entrypoint.sh Added token cache file creation and scrubbing logic for both chroot and non-chroot paths
package-lock.json Added "peer": true flags to various dependencies (appears to be from npm version difference)
Comments suppressed due to low confidence (2)

src/docker-manager.ts:925

  • If redaction fails (line 924), only a warning is logged and execution continues. This means the agent container will run with an unredacted docker-compose.yml file accessible via /host/tmp/awf-*/docker-compose.yml, creating a security exposure. Consider whether this should be treated as a critical error that stops execution. At minimum, the warning should clearly indicate this is a security concern. Alternatively, document why continuing with unredacted secrets is acceptable (e.g., if other mitigations are sufficient).
      fs.writeFileSync(composePath, content, { mode: 0o600 });
      logger.info(`Redacted ${redactedCount} sensitive value(s) from docker-compose.yml`);
    }

containers/agent/one-shot-token/one-shot-token.c:295

  • The constructor calls unsetenv() for tokens found in the environment (line 295), but there's no check for unsetenv() failure. While unsetenv() rarely fails, if it does (e.g., due to invalid token name format or system error), the token would remain in /proc/self/environ, defeating the purpose of this scrubbing mechanism. Consider checking the return value and logging a warning or treating it as a critical error in security-sensitive contexts.
            char *value = real_getenv(sensitive_tokens[i]);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +912 to +913
`(${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})(=|:\\s*)([^\\n]+)`,
'g'
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern ([^\\n]+) will match everything up to a newline, including trailing whitespace and quotes. In YAML, values can be quoted (e.g., GITHUB_TOKEN: "ghp_abc123"), and this pattern would preserve the quotes in the redacted output, resulting in GITHUB_TOKEN: "***REDACTED*** (missing closing quote). Consider adjusting the pattern to handle quoted values properly, or trimming whitespace and quotes from captured values before redaction. For example, the pattern could be ([^\\n]*?)\\s*$ to capture the value more precisely.

This issue also appears on line 923 of the same file.

Suggested change
`(${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})(=|:\\s*)([^\\n]+)`,
'g'
`(${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})(=|:\\s*)([^\\n]*?)\\s*$`,
'gm'

Copilot uses AI. Check for mistakes.
Comment on lines +216 to +218
fprintf(stderr, "[one-shot-token] WARNING: Could not open token cache file: %s\n", cache_path);
return;
}
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The line buffer is fixed at 8192 bytes. If a token value exceeds this length (e.g., a very long JWT or concatenated secrets), fgets will read only the first 8191 characters, potentially splitting the line. The next fgets call will read the remainder as a new line, which may parse incorrectly. While 8KB is generous for typical tokens, consider either validating line length, handling partial reads, or documenting this limitation. Alternatively, use getline() which dynamically allocates buffer space.

Copilot uses AI. Check for mistakes.

*eq = '\0';
const char *name = line;
const char *value = eq + 1;
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function checks !token_accessed[idx] before caching a token from the file, but if a token appears multiple times in the cache file, only the first occurrence will be loaded. While this might be intentional (first-wins policy), it's not documented. If the entrypoint.sh script accidentally writes duplicate entries, the later value will be silently ignored. Consider either warning about duplicates or documenting this behavior.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added (first-wins for duplicates) comment to the code in e767a90. This is intentional — entrypoint.sh writes each token exactly once, so duplicates would only occur from manual cache file editing.

Comment on lines 248 to 252
}

fclose(f);

/* Delete the cache file immediately to minimize exposure */
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If unlink() fails (line 249-252), a warning is printed but execution continues. In a security-sensitive context where the cache file contains plaintext tokens, leaving the file on disk is a potential exposure risk. Consider whether the failure to delete the cache file should be treated as a critical error. At minimum, the warning message should emphasize the security implications to help with debugging and monitoring.

This issue also appears on line 295 of the same file.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e767a90 — the cache file is no longer deleted in the constructor. It must survive the full exec chain (capsh → gosu → user command) since each exec() resets static data. Cleanup is handled by the EXIT trap in entrypoint.sh. The file is created with mode 0600 and owned by awfuser.

'GITHUB_API_TOKEN',
'GITHUB_PAT',
'GH_ACCESS_TOKEN',
'GITHUB_PERSONAL_ACCESS_TOKEN',
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token name 'GITHUB_PERSONAL_ACCESS_TOKEN' exists in SENSITIVE_ENV_NAMES but is not present in DEFAULT_SENSITIVE_TOKENS in one-shot-token.c (lines 35-51) or in the SENSITIVE_TOKENS default list in entrypoint.sh (lines 406 and 464). According to the PR description and code comments, these three lists must stay aligned. While the PR description notes that GITHUB_PERSONAL_ACCESS_TOKEN is "only present in compose files (not passed to the agent process in default mode)", this creates a risk of misalignment and confusion. Consider either adding it to all three lists for consistency, or adding a clear comment explaining why this token is intentionally only in the TypeScript list.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e767a90GITHUB_PERSONAL_ACCESS_TOKEN is now in all three lists (one-shot-token.c, entrypoint.sh, docker-manager.ts).

fi
done
# Also add cache file cleanup to the exit trap
CLEANUP_CMD="${CLEANUP_CMD}; rm -f ${TOKEN_CACHE_FILE} 2>/dev/null || true"
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token cache file is created at /host${TOKEN_CACHE_FILE} (/host/tmp/.awf-token-cache-$$) from the chroot context, but the cleanup command uses ${TOKEN_CACHE_FILE} without the /host prefix. Since the trap runs within the chroot, this path should work, but if the cleanup trap executes after the chroot context has changed or if there's an error, the file might not be deleted. Consider making the cleanup path more explicit or documenting why the /host prefix is intentionally omitted in the cleanup command.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good observation. In e767a90 this is clarified with a comment: the cleanup trap uses ${TOKEN_CACHE_FILE} (without /host prefix) because it runs inside the chroot where the file is at that path. The chroot exec chain always runs within the chroot context, so the path is correct.

Comment on lines 57 to 59
// Step 2.5: Redact secrets from docker-compose.yml after containers start
// This prevents exposure via /host/tmp/awf-*/docker-compose.yml
dependencies.redactComposeSecrets(config.workDir);
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a small race condition window between when containers start and when redaction occurs. The agent container could theoretically read the unredacted docker-compose.yml file via /host/tmp/awf-*/docker-compose.yml before redactComposeSecrets() completes. While this window is narrow (milliseconds) and requires the agent to immediately seek out and read this file, it represents an exposure risk. Consider either: (1) performing redaction before starting containers (if containers don't need the real values), (2) not mounting /tmp into the container at all, or (3) using Docker secrets/configs instead of environment variables in the compose file. The current approach relies on the agent code taking longer to start than the redaction, which may not be reliable under all conditions.

See below for a potential fix:

  // Step 2: Redact secrets from docker-compose.yml before containers start
  // This prevents exposure via /host/tmp/awf-*/docker-compose.yml inside containers
  dependencies.redactComposeSecrets(config.workDir);

  // Step 3: Start containers
  await dependencies.startContainers(config.workDir, config.allowedDomains, config.proxyLogsDir, config.skipPull);

  onContainersStarted?.();

  // Step 4: Wait for agent to complete
  const result = await dependencies.runAgentCommand(config.workDir, config.allowedDomains, config.proxyLogsDir);

  // Step 5: Cleanup (logs will be preserved automatically if they exist)

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redaction cannot be moved before startContainers() — Docker reads the compose file during docker compose up to configure container environment variables. Redacting before would prevent containers from receiving the tokens. The race window is mitigated by writing the compose file with mode 0600 (root-only readable), so the agent process (running as awfuser) cannot read it regardless of timing. Added explanatory comment in e767a90.

Copy link
Contributor Author

Copilot AI commented Feb 10, 2026

Security Review

Issues Fixed (in 0a5631a)...

All four issues addressed in e767a90:

1. Cache file consumed by wrong process: Fixed by removing unlink() and unsetenv() from load_token_cache_file(). The cache file now survives the full exec chain and is cleaned up by the EXIT trap in entrypoint.sh instead.

2. Token list misalignment: Added GITHUB_PERSONAL_ACCESS_TOKEN to DEFAULT_SENSITIVE_TOKENS in both one-shot-token.c and entrypoint.sh, aligning all three lists.

3. Shell echo corruption: Replaced echo "${TOKEN_NAME}=${TOKEN_VALUE}" with printf '%s=%s\n' "$token_name" "$token_value".

4. Duplicated scrubbing code: Extracted into a scrub_sensitive_tokens() shell function called from both chroot and non-chroot paths.

@copilot please address review comments

All review comments addressed in e767a90.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

📰 DEVELOPING STORY: Smoke Copilot reports failed. Our correspondents are investigating the incident...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Chroot tests failed Smoke Chroot failed - See logs for details.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

💫 TO BE CONTINUED... Smoke Claude failed! Our hero faces unexpected challenges...

@lpcox
Copy link
Contributor

lpcox commented Feb 10, 2026

@Mossaka looks like some of the CI checks are not passing.

This was from a smoke test:

yaml: line 154: did not find expected alphabetic or numeric character
Error: Failed to stop containers: Error: Command failed with exit code 1: docker compose down -v
at makeError (/home/runner/work/gh-aw-firewall/gh-aw-firewall/node_modules/execa/lib/error.js:60:11)
at handlePromise (/home/runner/work/gh-aw-firewall/gh-aw-firewall/node_modules/execa/index.js:118:26)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async stopContainers (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/docker-manager.js:1042:9)
at async performCleanup (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/cli.js:769:13)
at async runMainWorkflow (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/cli-workflow.js:32:5)
at async Command. (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/cli.js:798:20) {
shortMessage: 'Command failed with exit code 1: docker compose down -v',
command: 'docker compose down -v',
escapedCommand: 'docker compose down -v',
exitCode: 1,
signal: undefined,
signalDescription: undefined,
stdout: undefined,
stderr: undefined,
failed: true,
timedOut: false,
isCanceled: false,
killed: false
}
Error: [ERROR] Fatal error: Error: Command failed with exit code 1: docker compose down -v
at makeError (/home/runner/work/gh-aw-firewall/gh-aw-firewall/node_modules/execa/lib/error.js:60:11)
at handlePromise (/home/runner/work/gh-aw-firewall/gh-aw-firewall/node_modules/execa/index.js:118:26)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async stopContainers (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/docker-manager.js:1042:9)
at async performCleanup (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/cli.js:769:13)
at async runMainWorkflow (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/cli-workflow.js:32:5)
at async Command. (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/cli.js:798:20) {
shortMessage: 'Command failed with exit code 1: docker compose down -v',
command: 'docker compose down -v',
escapedCommand: 'docker compose down -v',
exitCode: 1,
signal: undefined,
signalDescription: undefined,
stdout: undefined,
stderr: undefined,
failed: true,
timedOut: false,
isCanceled: false,
killed: false
}
[INFO] Stopping containers...
yaml: line 154: did not find expected alphabetic or numeric character
Error: Failed to stop containers: Error: Command failed with exit code 1: docker compose down -v
at makeError (/home/runner/work/gh-aw-firewall/gh-aw-firewall/node_modules/execa/lib/error.js:60:11)
at handlePromise (/home/runner/work/gh-aw-firewall/gh-aw-firewall/node_modules/execa/index.js:118:26)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async stopContainers (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/docker-manager.js:1042:9)
at async performCleanup (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/cli.js:769:13)
at async Command. (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/cli.js:820:9) {
shortMessage: 'Command failed with exit code 1: docker compose down -v',
command: 'docker compose down -v',
escapedCommand: 'docker compose down -v',
exitCode: 1,
signal: undefined,
signalDescription: undefined,
stdout: undefined,
stderr: undefined,
failed: true,
timedOut: false,
isCanceled: false,
killed: false
}
node:internal/process/promises:391
triggerUncaughtException(err, true /* fromPromise */);
^

Error: Command failed with exit code 1: docker compose down -v
at makeError (/home/runner/work/gh-aw-firewall/gh-aw-firewall/node_modules/execa/lib/error.js:60:11)
at handlePromise (/home/runner/work/gh-aw-firewall/gh-aw-firewall/node_modules/execa/index.js:118:26)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async stopContainers (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/docker-manager.js:1042:9)
at async performCleanup (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/cli.js:769:13)
at async Command. (/home/runner/work/gh-aw-firewall/gh-aw-firewall/dist/cli.js:820:9) {
shortMessage: 'Command failed with exit code 1: docker compose down -v',
command: 'docker compose down -v',
escapedCommand: 'docker compose down -v',
exitCode: 1,
signal: undefined,
signalDescription: undefined,
stdout: undefined,
stderr: undefined,
failed: true,
timedOut: false,
isCanceled: false,
killed: false
}

Node.js v20.20.0
Error: Process completed with exit code 1.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

💫 TO BE CONTINUED... Smoke Claude failed! Our hero faces unexpected challenges...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

📰 DEVELOPING STORY: Smoke Copilot reports failed. Our correspondents are investigating the incident...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Chroot tests failed Smoke Chroot failed - See logs for details.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

🌑 The shadows whisper... Smoke Codex failed. The oracle requires further meditation...

The `***REDACTED***` replacement value contains `*` which is a YAML
alias character. When unquoted, docker compose fails to parse the file
with "did not find expected alphabetic or numeric character". Wrapping
in double quotes produces valid YAML that docker compose can still read
during cleanup (docker compose down -v).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Chroot tests failed Smoke Chroot failed - See logs for details.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

📰 DEVELOPING STORY: Smoke Copilot reports failed. Our correspondents are investigating the incident...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

💫 TO BE CONTINUED... Smoke Claude failed! Our hero faces unexpected challenges...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

🌑 The shadows whisper... Smoke Codex failed. The oracle requires further meditation...

@github-actions
Copy link
Contributor

PR titles: feat: implement selective mounting to prevent credential exfiltration | fix: add apt-get install retry logic to handle stale package archives
Tests: merged-PR review ✅; safeinputs-gh PR list ✅; Playwright ✅; Tavily search ❌ (tool missing); file write+cat ✅; discussion comment ✅; build ✅
Overall: FAIL

AI generated by Smoke Codex

@Mossaka Mossaka closed this Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: restrict /proc/self/environ and docker-compose.yml secret exposure

3 participants