From 39b87250753fb8ccdcf652f14d987d9c11c12aa4 Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Thu, 6 Aug 2026 11:03:54 -0400 Subject: [PATCH 1/8] fix(security): enforce patched transitive dependency floors --- requirements.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/requirements.txt b/requirements.txt index 8faf598..a356d45 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,3 +14,8 @@ prometheus-client>=0.21.0 PyJWT>=2.12.0 passlib[bcrypt]>=1.7.4 python-json-logger>=2.0.7 + +# Security floors for transitive packages identified by the container scan. +cryptography>=50.0.0 +msgpack>=1.2.1 +setuptools>=78.1.1 From 019d6a6d47d0a839778ed98368dfbb2781b1cd5d Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Thu, 6 Aug 2026 11:04:24 -0400 Subject: [PATCH 2/8] ci(security): retain failed dependency audit evidence --- .github/workflows/trojanchat-hygiene.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/trojanchat-hygiene.yml b/.github/workflows/trojanchat-hygiene.yml index df06253..655a400 100644 --- a/.github/workflows/trojanchat-hygiene.yml +++ b/.github/workflows/trojanchat-hygiene.yml @@ -112,6 +112,7 @@ jobs: run: | pip-audit -r requirements.txt --progress-spinner off --format json --output pip-audit.json - name: Upload dependency audit + if: always() uses: actions/upload-artifact@v7 with: name: pip-audit-report From d33592269c89b950dc41ac76ed42e17acf548e37 Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Thu, 6 Aug 2026 11:06:32 -0400 Subject: [PATCH 3/8] fix(build): keep MLflow resolver on Python 3.14-compatible releases --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a356d45..a72627a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ openai>=1.68.0 groq>=1.1.2 streamlit>=1.44.0 -mlflow>=2.22.0 +mlflow>=3.14.0 pydantic>=2.10.0 pydantic-settings>=2.8.0 python-dotenv>=1.1.0 From 5b4cad2f6deb7173de16277e5de1eca417cdf3d3 Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Thu, 6 Aug 2026 11:11:05 -0400 Subject: [PATCH 4/8] fix(security): remove incompatible unused MLflow dependency --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a72627a..2d8783a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,6 @@ openai>=1.68.0 groq>=1.1.2 streamlit>=1.44.0 -mlflow>=3.14.0 pydantic>=2.10.0 pydantic-settings>=2.8.0 python-dotenv>=1.1.0 From d2249d3c12edc86d39a19a0fef8771b95a42efaa Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Thu, 6 Aug 2026 11:11:08 -0400 Subject: [PATCH 5/8] fix(security): remove unused MLflow tracking helper --- ml/tracking/mlflow_utils.py | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 ml/tracking/mlflow_utils.py diff --git a/ml/tracking/mlflow_utils.py b/ml/tracking/mlflow_utils.py deleted file mode 100644 index 0a41b15..0000000 --- a/ml/tracking/mlflow_utils.py +++ /dev/null @@ -1,13 +0,0 @@ -import mlflow - -def start_run(run_name: str): - mlflow.set_experiment("trojanchat-llm") - return mlflow.start_run(run_name=run_name) - -def log_metrics(latency_ms: float, tokens: int): - mlflow.log_metric("latency_ms", latency_ms) - mlflow.log_metric("tokens_used", tokens) - -def log_params(params: dict): - for key, value in params.items(): - mlflow.log_param(key, value) \ No newline at end of file From 8aa3c4a03aec0655a9e7d09f50bc853df5caf7ee Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Thu, 6 Aug 2026 11:11:11 -0400 Subject: [PATCH 6/8] fix(security): remove stale MLflow prompt experiment --- ml/experiments/prompt_eval.py | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 ml/experiments/prompt_eval.py diff --git a/ml/experiments/prompt_eval.py b/ml/experiments/prompt_eval.py deleted file mode 100644 index 3e0402c..0000000 --- a/ml/experiments/prompt_eval.py +++ /dev/null @@ -1,12 +0,0 @@ -import time -from app.core.llm_client import LLMClient -from ml.tracking.mlflow_utils import log_chat_metrics - -def run_experiment(prompt: str): - llm = LLMClient(api_key="DUMMY") - start = time.time() - output = llm.generate(prompt) - latency = (time.time() - start) * 1000 - - log_chat_metrics(latency, len(output.split()), "v1") - return output \ No newline at end of file From 5309e8c12c55276269d89134eec755fc87625b64 Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Thu, 6 Aug 2026 11:11:13 -0400 Subject: [PATCH 7/8] fix(security): remove duplicate MLflow prompt experiment --- ml/ml/experiments/prompt_eval.py | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 ml/ml/experiments/prompt_eval.py diff --git a/ml/ml/experiments/prompt_eval.py b/ml/ml/experiments/prompt_eval.py deleted file mode 100644 index 2fccc04..0000000 --- a/ml/ml/experiments/prompt_eval.py +++ /dev/null @@ -1,19 +0,0 @@ -import time -from app.core.llm_client import LLMClient -from ml.tracking.mlflow_utils import start_run, log_metrics, log_params -from ml.metrics import token_count - -def run_prompt_experiment(prompt: str, api_key: str): - llm = LLMClient(api_key) - with start_run("prompt-eval-v1"): - start = time.time() - output = llm.generate(prompt) - latency = (time.time() - start) * 1000 - - log_params({ - "model": "gpt-4.1", - "prompt_version": "v1" - }) - log_metrics(latency, token_count(output)) - - return output \ No newline at end of file From 9c40be00ef4a1ee5dde01e4162a0fcc712a80993 Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Thu, 6 Aug 2026 11:15:18 -0400 Subject: [PATCH 8/8] fix(container): remove vulnerable base-image installer payloads --- Dockerfile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 13a1919..d7b0552 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,10 +18,11 @@ ENV PATH=/opt/venv/bin:$PATH \ PYTHONDONTWRITEBYTECODE=1 \ PYTHONPATH=/app -# The base image ships build tooling that is unnecessary at runtime. Removing it -# also prevents scanners from treating setuptools' vendored build dependencies -# as remotely exploitable application packages. -RUN python -m pip uninstall --yes setuptools wheel \ +# The runtime executes Uvicorn from /opt/venv and does not install packages. +# Remove the base image's package-management tooling and bundled installer +# payloads so they cannot ship vulnerable vendored dependencies. +RUN python -m pip uninstall --yes pip setuptools wheel \ + && rm -rf /usr/local/lib/python3.14/ensurepip \ && useradd --create-home --uid 10001 appuser WORKDIR /app