Skip to content

fix(security): Z890 gap analysis remediation — 4 findings - #950

Merged
POWERFULMOVES merged 4 commits into
mainfrom
fix/z890-security-audit-remediation
Mar 15, 2026
Merged

POWERFULMOVES merged 4 commits into
mainfrom
fix/z890-security-audit-remediation

Conversation

@POWERFULMOVES

@POWERFULMOVES POWERFULMOVES commented Mar 15, 2026

Copy link
Copy Markdown
Owner

Summary

Triaged 7 security issues from the PR gap analysis produced during the Phase A-E sprint cleanup. 3 were already resolved on main, 4 required fixes:

# Priority Issue Service Verdict
1 CRITICAL Secret logging to response body github-webhook Already resolved — n8n flow returns generic messages
2 P1 Port 8096 conflict consciousness-service Already resolved — service on 8105, cipher on 8096
3 P1 Hardcoded CHIT passphrase consciousness-service Fixed — removed pmoves-chit-default from Dockerfile + main.py
4 P1 Auth fail-open dev bypass cast-tts Fixed — role downgraded admindev, added warning log
5 P1 NATS auth stripped flute-gateway Fixed — added warning when _build_nats_url() falls back to no-auth
6 P1 4 CodeQL alerts unfixed codeql tools Already resolved — rate-limit installed, generic error messages in place
7 P2 Info leak in audit API pmovesui Fixed — removed docsRoot absolute path from /api/audit/summary response

Changes (4 commits)

  1. consciousness-service/Dockerfile + main.py — Remove hardcoded pmoves-chit-default default, add startup warning when unset
  2. cast-tts-gateway/auth.py — Downgrade dev bypass role from admin to dev, add logger.warning() when auth bypassed
  3. flute-gateway/main.py — Add warning in _build_nats_url() when falling back to unauthenticated connection
  4. ui/app/api/audit/summary/route.ts — Remove docsRoot (absolute server path) from JSON response body

Test plan

  • grep -c "pmoves-chit-default" pmoves/services/consciousness-service/Dockerfile → 0
  • grep '"role"' pmoves/services/cast-tts-gateway/auth.py → first match is "dev" not "admin"
  • grep "without credentials" pmoves/services/flute-gateway/main.py → found
  • docsRoot not present in /api/audit/summary response JSON
  • Existing CI checks pass (no behavioral changes, only defaults/logging/response shape)

Follow-up (out of scope)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Removed unused field from the audit summary API response
  • Chores

    • Added configuration validation warnings when required authentication credentials or signing passphrases are not set
    • Updated environment variable handling to defer configuration injection to runtime instead of build-time
    • Enhanced security logging to track development-mode authentication bypass activity and credential validation events

POWERFULMOVES and others added 4 commits March 15, 2026 15:08
…rvice

Remove `pmoves-chit-default` default from Dockerfile ENV and main.py fallback.
Docker-compose enforces runtime injection via ${CHIT_PROD_PASSPHRASE:?...},
but the Dockerfile default was a security smell if the image ran standalone.

Addresses: Z890 gap analysis Issue #3 (PR #905)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Downgrade dev bypass role from "admin" to "dev" to limit privilege escalation
in development mode. Add logger.warning() when auth is bypassed so operators
can detect misconfiguration in production logs.

Addresses: Z890 gap analysis Issue #4 (PR #926)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
_build_nats_url() silently fell back to unauthenticated nats:// when
NATS_URL and NATS_USER/NATS_PASSWORD were all unset. Add logger.warning()
so operators can detect missing NATS credentials in logs.

Addresses: Z890 gap analysis Issue #5 (PR #927)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The /api/audit/summary response included `docsRoot` — an absolute server
filesystem path — in the JSON body. This leaks internal directory structure
to unauthenticated clients. Remove it from the response payload.

Addresses: Z890 gap analysis Issue #7 (PR #922)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Mar 15, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Multiple services receive updates: authentication layer adds development bypass logging, consciousness service shifts CHIT_PROD_PASSPHRASE from build-time to runtime injection with warning checks, flute gateway adds NATS credential logging, and the audit API response removes the docsRoot field from output.

Changes

Cohort / File(s) Summary
Security & Diagnostics Logging
pmoves/services/cast-tts-gateway/auth.py, pmoves/services/flute-gateway/main.py
Added module-level logging; development bypass now logs security warning before returning modified user context with role changed to "dev"; NATS gateway warns when credentials are unavailable.
CHIT Passphrase Configuration
pmoves/services/consciousness-service/Dockerfile, pmoves/services/consciousness-service/main.py
Dockerfile removes hardcoded CHIT_PROD_PASSPHRASE, deferring to runtime injection. main.py changes default from "pmoves-chit-default" to empty string with added runtime warning when unset; CGP signing remains unaffected.
API Response Structure
pmoves/ui/app/api/audit/summary/route.ts
Removed docsRoot field from GET response; all other response fields and control flow remain intact.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 With logs and warnings now in place,
We guard each service, set the pace,
Passphrases drift to runtime's care,
Simpler responses, cleaner air—
Each small change, a step ahead! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: security fixes for 4 identified findings from a Z890 gap analysis, which matches the 4 remediation fixes in the changeset.
Description check ✅ Passed The description includes all required sections: comprehensive summary with findings table, detailed testing plan with specific grep checks, and required checks marked. Only 'Testing' output is missing, but the test plan is documented.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/z890-security-audit-remediation
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

Docker Hardening Validation

Hardening Validation Report

Validated: Sun Mar 15 19:11:32 UTC 2026

Services Checked

PMOVES.AI Docker Hardening Validation

[INFO] Checking: pmoves/docker-compose.hardened.yml

[INFO] Validating: hi-rag-gateway-v2
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: extract-worker
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: langextract
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: presign
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: render-webhook
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: retrieval-eval
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: pdf-ingest
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: jellyfin-bridge
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: invidious-companion-proxy
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: ffmpeg-whisper
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: media-video
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: media-audio
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: hi-rag-gateway-v2-gpu
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: hi-rag-gateway-gpu
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: deepresearch
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: supaserch
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: publisher-discord
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: mesh-agent
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: nats-echo-req
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: nats-echo-res
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: publisher
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: analysis-echo
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: graph-linker
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: comfy-watcher
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: grayjay-plugin-host
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: agent-zero
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: archon
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: channel-monitor
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: pmoves-yt
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: notebook-sync
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: supabase_service_role_key
[WARN] No user directive
[WARN] No read_only directive
[WARN] No cap_drop: ["ALL"]
[WARN] No no-new-privileges
[WARN] No resource limits

[INFO] Validating: supabase_jwt_secret
[WARN] No user directive
[WARN] No read_only directive
[WARN] No cap_drop: ["ALL"]
[WARN] No no-new-privileges
[WARN] No resource limits

======================================
Summary: 120 passed, 40 warnings, 0 errors

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
pmoves/services/consciousness-service/main.py (1)

40-42: Use central secret loader for CHIT_PROD_PASSPHRASE instead of direct env read.

This segment removes the insecure default (good), but it still bypasses the shared secret-loading path used elsewhere in services.

♻️ Suggested refactor
@@
 import os
+from services.common.env import get_secret
@@
-CHIT_PASSPHRASE = os.environ.get("CHIT_PROD_PASSPHRASE", "")
+CHIT_PASSPHRASE = get_secret("CHIT_PROD_PASSPHRASE", "") or ""
 if not CHIT_PASSPHRASE:
     logger.warning("CHIT_PROD_PASSPHRASE not set — CGP signing disabled")

As per coding guidelines "pmoves/services/**: Prefer central env helpers and *_FILE secret loading paths" and "Flag direct critical-secret reads and plaintext fallbacks."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pmoves/services/consciousness-service/main.py` around lines 40 - 42, Replace
the direct os.environ.get read for CHIT_PASSPHRASE with the project's central
secret loader (e.g., call the shared helper used by other services such as
load_secret / secrets.get_secret) so it honors the *_FILE pattern
(CHIT_PROD_PASSPHRASE_FILE) and secure file-backed secrets; do not use a
plaintext default "", and keep the existing logger.warning when the secret is
absent but sourced via the central loader API; update references to the
CHIT_PASSPHRASE variable to use the value returned by that loader.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pmoves/services/consciousness-service/main.py`:
- Around line 40-42: Replace the direct os.environ.get read for CHIT_PASSPHRASE
with the project's central secret loader (e.g., call the shared helper used by
other services such as load_secret / secrets.get_secret) so it honors the *_FILE
pattern (CHIT_PROD_PASSPHRASE_FILE) and secure file-backed secrets; do not use a
plaintext default "", and keep the existing logger.warning when the secret is
absent but sourced via the central loader API; update references to the
CHIT_PASSPHRASE variable to use the value returned by that loader.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 020bc0b6-06ff-4e35-a9fe-186e7374225d

📥 Commits

Reviewing files that changed from the base of the PR and between da2e3d8 and 2496348.

📒 Files selected for processing (5)
  • pmoves/services/cast-tts-gateway/auth.py
  • pmoves/services/consciousness-service/Dockerfile
  • pmoves/services/consciousness-service/main.py
  • pmoves/services/flute-gateway/main.py
  • pmoves/ui/app/api/audit/summary/route.ts
💤 Files with no reviewable changes (1)
  • pmoves/ui/app/api/audit/summary/route.ts

@POWERFULMOVES
POWERFULMOVES merged commit a9ce493 into main Mar 15, 2026
23 of 25 checks passed
@POWERFULMOVES
POWERFULMOVES deleted the fix/z890-security-audit-remediation branch March 15, 2026 19:32
POWERFULMOVES added a commit that referenced this pull request Mar 16, 2026
All 5 TAC_MODEL_INFRA branches (B/D, A, C, F, E) verified as
complete on main — registry seed (1511 lines), persona seed (8
personas), resolution view, readiness check (652 lines, 10 checks),
service-model mappings (30+).

Add Branch G (Agent Zero bootstrap integration) referencing PR #960.
Update production audit dashboard with verification status and merged
PR summary (#950-958, #960).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant