Skip to content

fix(deps): bump python-dotenv to 1.2.2 for VULN-88817 - #151

Merged
shuningc merged 11 commits into
mainfrom
VULN-88817-python-dotenv-upgrade
Aug 11, 2026
Merged

fix(deps): bump python-dotenv to 1.2.2 for VULN-88817#151
shuningc merged 11 commits into
mainfrom
VULN-88817-python-dotenv-upgrade

Conversation

@shuningc

@shuningc shuningc commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes VULN-88817 by upgrading python-dotenv to >=1.2.2.

Prior to 1.2.2, set_key() and unset_key() follow symbolic links when rewriting .env files. A local attacker can overwrite arbitrary files via a crafted symlink when a cross-device rename fallback is triggered.

Changes

  • Bump python-dotenv constraint to >=1.2.2
  • Regenerate poetry.lock
  • Update example dependency pins where applicable

Vulnerability

  • Ticket: VULN-88817
  • Package: python-dotenv
  • Fixed in: 1.2.2

shuningc and others added 3 commits July 27, 2026 13:15
Lock-only bump for transitive python-dotenv (1.1.1 → 1.2.2) to fix
symlink-following in set_key()/unset_key(). Example pins set to 1.2.2.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Add direct python-dotenv floor and regenerate poetry.lock (1.1.1 → 1.2.2).
Fixes symlink-following in set_key()/unset_key(). Reverts accidental
requests bump from prior lock edit.

Co-authored-by: Cursor <cursoragent@cursor.com>
@shuningc
shuningc marked this pull request as ready for review July 27, 2026 21:04
…env-upgrade

Regenerate poetry.lock after conflict with merged dependency PRs.

Co-authored-by: Cursor <cursoragent@cursor.com>
@shuningc

shuningc commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

Resolve poetry.lock conflict and regenerate lock with python-dotenv 1.2.2
on latest main.

Co-authored-by: Cursor <cursoragent@cursor.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cdc6b7d634

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pyproject.toml
opentelemetry-exporter-otlp-proto-http = "^1.38.0"
filelock = ">=3.20.1"
idna = ">=3.15,<4"
python-dotenv = ">=1.2.2"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Constrain dotenv in the a2a package too

This lower bound only fixes the root splunk-ao package; repo-wide search still shows the separately packaged splunk-ao-a2a manifest allows python-dotenv>=1.1.0 (splunk-ao-a2a/pyproject.toml:52). In environments that install splunk-ao-a2a standalone or use constraints that keep dotenv below 1.2.2, the vulnerable versions remain admissible, so the security bump does not actually cover all published package manifests in this repo.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is already addressed in the current head (d5cc6f7) — splunk-ao-a2a/pyproject.toml:53 now reads "python-dotenv>=1.2.2" in the examples extra. The comment was authored against cdc6b7d, before that bump landed.

The underlying concern about non-root manifests is valid, though, and is still live for other paths — most importantly examples/agent/langgraph-fsi-agent/before/poetry.lock, which pins 1.1.1 exactly. Flagged separately.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Confirming this is resolved at the current head: splunk-ao-a2a/pyproject.toml:53 reads "python-dotenv>=1.2.2" in the examples extra. The comment was authored against cdc6b7d, before that bump landed.

The follow-up concern about non-root manifests is also resolved for the path called out: examples/agent/langgraph-fsi-agent/before/poetry.lock:3597 now locks 1.2.2, not 1.1.1. I checked the remaining lock files repo-wide — poetry.lock and examples/agent/langgraph-fsi-agent/before/poetry.lock are the only two, and both are at 1.2.2. This thread can be resolved.

@shuningc
shuningc marked this pull request as draft August 4, 2026 22:08
shuningc and others added 2 commits August 4, 2026 16:30
Align splunk-ao-a2a dependency group with root >=1.2.2 so standalone
installs and constraint resolution cannot admit vulnerable dotenv versions.

Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve conflicts after requests>=2.33.0 landed on main; keep both
python-dotenv>=1.2.2 and requests floors with lock at 1.2.2/2.34.2.

Co-authored-by: Cursor <cursoragent@cursor.com>
@shuningc
shuningc marked this pull request as ready for review August 5, 2026 06:25

@fercor-cisco fercor-cisco left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 This review was generated by the Astra agent (claude-opus-5). It may contain mistakes.

Verdict: request_changes — The sweep is incomplete: a committed lockfile in the repo still pins the exact vulnerable python-dotenv 1.1.1, and several example manifests still allow pre-1.2.2, so the vulnerability remains reachable from this repo on main.

General Comments

  • 🟠 major (security): The sweep over in-repo manifests is incomplete, and inconsistently so.

This PR updates 4 example dependency files, which establishes that examples are in scope for the fix. But repo-wide search shows the vulnerable range is still admissible — and in one case still pinned — elsewhere:

  1. examples/agent/langgraph-fsi-agent/before/poetry.lock:3590-3599 locks python-dotenv 1.1.1 exactly, with hashes, in groups = ["main"]. This is the precise version and artifact type (poetry.lock) that VULN-88817 flagged. Anyone running poetry install in that example installs the vulnerable release, and a FOSSA rescan of the branch is likely to re-open the ticket on this path.
  2. Floors that still admit <1.2.2:
    • examples/agent/langgraph-fsi-agent/before/pyproject.toml:16>=1.1.0
    • examples/agent/langgraph-fsi-agent/after/pyproject.toml:17>=1.1.0
    • examples/agent/langgraph-otel/pyproject.toml:17>=1.1.0
    • examples/agent/langgraph-telecom-agent/pyproject.toml:17>=1.1.0
    • examples/agent/langgraph-traceloop/pyproject.toml:13>=1.1.0
    • examples/agent/langgraph-open-telemetry/pyproject.toml:11>=1.1.0
    • examples/chatbot/elevenlabs-chatbot/{pyproject.toml:7,requirements.txt:1}, examples/rag/cli-rag-demo/requirements.txt:25, examples/agent/minimal-agent-example/requirements.txt:20, examples/experiments/upload_experiment/requirements.txt:2>=1.0.0

Item 1 is the one I'd consider blocking — it is a concrete vulnerable pin committed to the repo, not merely a permissive range. Please regenerate that lockfile (or, if that example is dead and intentionally frozen, say so on the ticket so ProdSec can VEX-scope it rather than leaving it silently behind).

For item 2, either raise the floors for consistency with the 4 files you did touch, or explain in the PR body why unpinned/loose example manifests are considered out of scope — right now a reader can't tell which files were deliberately skipped versus missed. (Entries that are bare python-dotenv with no specifier will resolve to the latest release and are genuinely fine.)

  • 🟡 minor (other): The PR is currently in a conflicted state (mergeable_state: dirty, rebaseable: false) after 7 commits against a moving main. Since poetry.lock is one of the changed files and carries a content-hash bound to pyproject.toml, please rebase and re-run poetry lock rather than hand-resolving the conflict — a manually merged lock can end up with a content-hash that no longer matches pyproject.toml, which makes poetry install fail in CI (or worse, silently drift).

Follow-ups

Suggested follow-up work that could be tracked as Jira tickets:

  • examples/agent/langgraph-fsi-agent/before/poetry.lock:1-1: Committed example lockfiles (examples/agent/langgraph-fsi-agent/before/poetry.lock is the only one) are not covered by any automated dependency-update or scan job, so they drift and silently reintroduce fixed CVEs. Consider either adding them to Dependabot/Renovate coverage or deleting them and documenting poetry install from the manifest instead, so future VULN tickets don't need a manual repo-wide grep to find every stale pin.
  • examples/rag/elastic-chatbot-rag-app/requirements.txt:381-381: This file and examples/logging-samples/openai-responses/requirements.txt are machine-generated (pip-compile / uv pip compile, per their headers) but were hand-edited here. The edits are consistent with what a regeneration would produce today, so no action is needed for this PR — but a repo convention or CI check that these are regenerated rather than edited would prevent the generated files from diverging from their .in/pyproject.toml sources over time.

pyjwt==2.13.0
python-dateutil==2.9.0.post0
python-dotenv==1.1.0
python-dotenv==1.2.2

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 minor (bug): python-dotenv 1.2.x raises its floor to Requires-Python >=3.10 (the root poetry.lock diff shows this: python-versions went >=3.9>=3.10). This example advertises and gates on older interpreters:

  • README.md:222 — "Ensure you're using Python 3.8+"
  • TUTORIAL.md:31 — "Check Python version (should be 3.8+)"
  • start.sh:17required_version="3.8", exits only below 3.8
  • start.bat:11 — "Please install Python 3.8+"

So on Python 3.8/3.9 start.sh now passes its version gate and then pip install -r requirements.txt fails to resolve. Either bump the documented/enforced floor to 3.10 in those four places, or leave this pin at a 1.1.x-compatible value and note the example as out of scope for the CVE. (README.md:49 and :283 already say 3.10+, so the docs are self-inconsistent today — worth settling on one number while you're here.)

🤖 Generated by the Astra agent

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This concern is valid and only partially addressed by the subsequent commits.

The four spots named here were fixed (README.md:222, TUTORIAL.md:31, start.sh:11,17,20, start.bat:11), and the author chose the "bump the floor to 3.10" option. But the actual enforcement logic in test_setup.py:18 was missed — only its message string was changed to "3.10+", while the comparison still reads py_version.minor < 8. So the specific failure mode described here still reproduces, just via a different entry point: on 3.9, test_setup.py reports ✅ Python 3.9.x is compatible and then blames a missing python-dotenv. Commented inline.

One refinement on the chosen number: 3.10 satisfies python-dotenv, but requirements.txt:8 pulls in splunk-ao, whose requires-python is >=3.11,<3.15. So this example is arguably 3.11+, not 3.10+, and picking 3.10 leaves a narrow band (exactly 3.10) that passes every gate and still fails to install. Worth settling on 3.11 across all five files.

Comment thread pyproject.toml
opentelemetry-exporter-otlp-proto-http = "^1.38.0"
filelock = ">=3.20.1"
idna = ">=3.15,<4"
python-dotenv = ">=1.2.2"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 minor (question): splunk_ao never imports dotenvrg -n dotenv src/ returns nothing. This adds python-dotenv to the published splunk-ao package's direct runtime requirements purely to raise a floor on a transitive dep (it arrives via galileo-core's python-dotenv = ">=1.1.1", pydantic-settings, and litellm).

I see this matches an existing convention here (filelock, idna are the same shape), so I'm not blocking on it — but it does mean every downstream consumer of splunk-ao now inherits a hard constraint on a package we don't use, and it will silently rot once galileo-core bumps its own floor past 1.2.2. Was bumping galileo-core (whose floor is the actual source of the 1.1.1 resolution) considered as an alternative? If the direct-floor approach is the deliberate house pattern for CVE remediation, a one-line comment above these entries marking them as vuln floors — rather than real dependencies — would keep a future reader from treating them as load-bearing.

Also worth a thought: unlike the adjacent idna = ">=3.15,<4", this has no upper bound, so a future python-dotenv 2.0 is admissible for a dependency we never exercise.

🤖 Generated by the Astra agent

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Independently confirmed the factual premise: rg -n dotenv src/ returns nothing, so splunk_ao does not import dotenv, and poetry.lock:839 shows the resolution genuinely originates from galileo-core's python-dotenv = ">=1.1.1". The floor here is a pure vuln floor on a package the SDK never exercises.

On the concrete, non-blocking part of the ask — the explanatory comment — that suggestion has effectively been accepted elsewhere in this same PR but not here: examples/rag/elastic-chatbot-rag-app/requirements.in:1 now carries # security floor (VULN-88817 — python-dotenv symlink overwrite). Applying the identical one-liner above pyproject.toml:62 (and splunk-ao-a2a/pyproject.toml:53) would make the treatment consistent and costs nothing. I have raised that as a PR-level comment.

On the upper-bound point: I would not add one. A <2 cap on a floor-only constraint we never import converts a silent-rot problem into an active-blocker problem — it would force a release of splunk-ao the moment any real consumer of dotenv in the tree wants 2.x. The rot risk you describe (constraint becomes redundant once galileo-core moves past 1.2.2) is the cheaper failure mode, and the explanatory comment is the right mitigation for it.

Regenerate poetry.lock after merge, bump langgraph example dotenv floors
to >=1.2.2, and update langgraph-fsi-agent/before lock (1.1.1 -> 1.2.2).
Normalize every example requirements.txt/pyproject.toml to python-dotenv
>=1.2.2, add floor to elastic-chatbot requirements.in, align startup-
simulator Python docs with dotenv 1.2.x (>=3.10), and regenerate locks.

@shuningc shuningc left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 This review was generated by the Astra agent (claude-opus-5). It may contain mistakes.

Verdict: request_changes — The dotenv 1.2.x bump raises the interpreter floor to Python 3.10, but the accompanying version-gate sweep is incomplete: test_setup.py updated only the message and not the comparison, and elevenlabs-chatbot still declares requires-python = ">=3.9" with a now-unresolvable dependency set.

General Comments

  • 🟠 major (bug): The Python-floor sweep triggered by this bump is incomplete.

python-dotenv 1.2.x raises Requires-Python to >=3.10 (visible in both lock diffs: python-versions >=3.9>=3.10). That makes every manifest that now pins >=1.2.2/==1.2.2 unresolvable on 3.8/3.9. The PR correctly chased this down for startup-simulator-3000's docs and shell scripts, but the same class of problem is left unfixed elsewhere:

  • examples/chatbot/elevenlabs-chatbot/pyproject.toml:5requires-python = ">=3.9", now with python-dotenv>=1.2.2. This is a declared, machine-readable floor that is now self-contradictory, not just prose.
  • examples/rag/cli-rag-demo/README.md:13 — "Python 3.8+"
  • examples/agent/weather-vibes-agent/00-tutorial/{01-weather-vibes-overview.md:9, 02-installation-instructions.md:9,261, weather-vibes-cookbook.md:24} — "Python 3.8+"

And within startup-simulator-3000, test_setup.py:18 had its message updated to "3.10+" while the comparison still tests < 8 (flagged inline).

A repo-wide rg -n '3\.8\+|3\.9|requires-python' over every directory whose manifest this PR touched would close this out. Suggest doing that sweep rather than fixing these four spots piecemeal, since the next dependency floor bump will hit the same set of files.

  • 🟡 minor (design): The remediation is applied inconsistently — some manifests document why the floor exists, most don't.

examples/rag/elastic-chatbot-rag-app/requirements.in:1 gets a genuinely useful marker:

# security floor (VULN-88817 — python-dotenv symlink overwrite)

None of the other ~30 edited manifests get this, including pyproject.toml:62 where a reviewer explicitly asked for it. This matters more than it looks: for the manifests where dotenv is not actually imported (root pyproject.toml, splunk-ao-a2a), a future reader has no way to distinguish "vuln floor, safe to drop once the transitive floor moves past it" from "load-bearing dependency". Adding the one-line comment to at least the two published package manifests would make these self-documenting and prevent them rotting into permanent unexplained constraints.

Follow-ups

Suggested follow-up work that could be tracked as Jira tickets:

  • examples/agent/langchain-agent/requirements.txt:1-7: main.py:1 does from dotenv import load_dotenv, but python-dotenv is not declared in this requirements file at all — it only works today by arriving transitively. Because it is undeclared, this PR's floor sweep necessarily skipped it. Declaring python-dotenv>=1.2.2 here would make the dependency explicit and bring it under the same security floor as its sibling examples. Pre-existing gap, not introduced by this PR.
  • examples/dataset-experiments/requirements.txt:1-3: Same pattern as examples/agent/langchain-agent: app.py:14, app-simple.py:5, and experiment_compare_two_models.py:11 all import dotenv, but python-dotenv is undeclared in this requirements file, so it fell outside this PR's sweep. Worth declaring it explicitly with the >=1.2.2 floor.
  • examples/agent/langchain-agent/00-tutorial/00-Getting-Started.md:8-8: Advertises "Python 3.8+" and the tutorial body (line 56) uses from dotenv import load_dotenv. Not strictly broken by this PR since this example's requirements file declares no dotenv pin, but it is the same stale-floor documentation issue and would be worth folding into a single repo-wide interpreter-floor cleanup.

Comment on lines +18 to +19
if py_version.major < 3 or (py_version.major == 3 and py_version.minor < 8):
print(f"❌ Python {py_version.major}.{py_version.minor} is too old. Need Python 3.8+")
print(f"❌ Python {py_version.major}.{py_version.minor} is too old. Need Python 3.10+")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🟠 major (bug): The error message was updated to "3.10+" but the comparison still checks minor < 8. The two now disagree, and the branch is unreachable for exactly the versions the bump broke.

Concretely, on Python 3.9: py_version.minor < 8 is false, so this prints ✅ Python 3.9.x is compatible — then test_dependencies() reports python-dotenv missing (it cannot be installed at all on 3.9 now), and the script tells the user to run pip install -r requirements.txt, which is precisely the command that just failed to resolve. The setup-verification script actively misdiagnoses the one failure mode this PR introduced.

Note also that this example's requirements.txt:8 depends on splunk-ao, whose own requires-python is >=3.11 — so 3.10 is arguably the wrong number here and in start.sh:17. Worth confirming the intended floor is 3.10 and not 3.11 while settling this.

Suggested change
if py_version.major < 3 or (py_version.major == 3 and py_version.minor < 8):
print(f"❌ Python {py_version.major}.{py_version.minor} is too old. Need Python 3.8+")
print(f"❌ Python {py_version.major}.{py_version.minor} is too old. Need Python 3.10+")
if py_version.major < 3 or (py_version.major == 3 and py_version.minor < 10):
print(f"❌ Python {py_version.major}.{py_version.minor} is too old. Need Python 3.10+")

🤖 Generated by the Astra agent

Comment on lines +5 to +7
requires-python = ">=3.9"
dependencies = [
"python-dotenv>=1.0.0",
"python-dotenv>=1.2.2",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🟠 major (bug): This manifest declares requires-python = ">=3.9" (line 5) but now requires python-dotenv>=1.2.2, which is Requires-Python >=3.10. The dependency set is unsatisfiable on 3.9: a user on 3.9 passes the metadata gate and then gets a resolver error with no indication of the real cause.

Unlike the startup-simulator-3000 case — which was prose and shell scripts — this is declared metadata that packaging tools act on, so it should be corrected rather than left as a doc inconsistency. README.md:64 already says "Python 3.10+", so 3.10 looks like the intended value and the >=3.9 here is just stale.

(Same applies to requirements.txt:1 in this directory, which has no interpreter metadata to correct — fixing pyproject.toml is what makes the constraint discoverable.)

Suggested change
requires-python = ">=3.9"
dependencies = [
"python-dotenv>=1.0.0",
"python-dotenv>=1.2.2",
requires-python = ">=3.10"
dependencies = [
"python-dotenv>=1.2.2",

🤖 Generated by the Astra agent

Comment on lines +381 to 382
python-dotenv==1.2.2
# via pydantic-settings

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🟡 minor (other): This compiled file appears to have been hand-edited rather than regenerated from the updated requirements.in, so the two are now out of sync.

requirements.in was changed to declare python-dotenv as a direct requirement, but the annotation here still lists only the transitive source:

python-dotenv==1.2.2
    # via pydantic-settings

If pip-compile had actually been re-run, this would read # via\n# -r requirements.in\n# pydantic-settings — compare flask==3.1.0 at line 77 and elastic-opentelemetry==0.8.0 at line 63, which both carry the -r requirements.in annotation. The version pin happens to be correct, so nothing is broken today, but the next genuine pip-compile run will produce a spurious diff and the file no longer demonstrates that the pin is reproducible from its source.

Suggest re-running pip-compile in that directory and committing the result.

Suggested change
python-dotenv==1.2.2
# via pydantic-settings
python-dotenv==1.2.2
# via
# -r requirements.in
# pydantic-settings

🤖 Generated by the Astra agent

sentence-transformers>=2.5.1
numpy>=1.24.0 # Required by FAISS and sentence-transformers
python-dotenv>=1.0.0 # Added for dotenv support
python-dotenv>=1.2.2 # Added for dotenv support

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🟡 minor (documentation): This pin now requires Python 3.10+, but README.md:13 in this same directory still advertises "Python 3.8+". A user following the README on 3.8/3.9 gets an unexplained resolver failure at pip install -r requirements.txt (README step 2). Please bump the documented prerequisite to match — the same fix that was applied to startup-simulator-3000's docs in this PR.

🤖 Generated by the Astra agent

fastapi
uvicorn
python-dotenv
python-dotenv>=1.2.2

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🟡 minor (documentation): As above: this pin requires Python 3.10+, but this example's tutorial still advertises 3.8 in four places — 00-tutorial/01-weather-vibes-overview.md:9, 00-tutorial/02-installation-instructions.md:9, 00-tutorial/02-installation-instructions.md:261 ("Check Python Version: Ensure you're using Python 3.8 or newer"), and 00-tutorial/weather-vibes-cookbook.md:24.

Worth noting 02-installation-instructions.md:239 has a troubleshooting entry for No module named 'dotenv' whose suggested fix is pip install python-dotenv — which is exactly what will fail on 3.9, so the troubleshooting guide would send a user in a circle.

🤖 Generated by the Astra agent

Raise elevenlabs-chatbot requires-python to >=3.11 so metadata matches
python-dotenv>=1.2.2 and splunk-ao. Fix startup-simulator version checks
and docs to use 3.11 consistently (test_setup.py was still gating on 3.8).

Co-authored-by: Cursor <cursoragent@cursor.com>

@shuningc shuningc left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 This review was generated by the Astra agent (claude-opus-5). It may contain mistakes.

Verdict: approve — The vuln floor is now applied consistently across every manifest and lock file in the repo, and all previously-raised major issues are fixed at HEAD; only two minor consistency items remain.

General Comments

  • 🟡 minor (design): Coverage check — the floor itself is complete. I verified repo-wide that no manifest, requirements file, or lock file still admits python-dotenv < 1.2.2: both poetry.lock (root, line 4459) and examples/agent/langgraph-fsi-agent/before/poetry.lock (line 3591) resolve 1.2.2 with updated content hashes, splunk-ao-a2a/pyproject.toml:53 is bumped, and every example pin is >=1.2.2 or ==1.2.2. Good.

One scope note worth recording in the PR description. Three examples import dotenv at runtime but never declare it — examples/agent/langchain-agent/main.py:1, examples/dataset-experiments/app.py:14, examples/chatbot/basic-examples/app.py:4. They are currently protected only because this PR added python-dotenv = ">=1.2.2" to the root pyproject.toml, so they inherit the floor transitively through splunk-ao. That is a real effect of the chosen approach and it does close the hole, but it is implicit — if the root floor is ever removed as redundant (the "silent rot" scenario discussed on pyproject.toml:62), those three examples quietly lose their protection with no local pin to fall back on. Worth either noting this dependency in the PR body or declaring the pin locally in those three files. Raised as follow-ups rather than blockers since they are pre-existing missing declarations, not something this PR introduced.

Follow-ups

Suggested follow-up work that could be tracked as Jira tickets:

  • examples/rag/cli-rag-demo/README.md:13-13: Prerequisites say "Python 3.8+", but requirements.txt:1 depends on splunk-ao (requires-python = ">=3.11,<3.15"), so installation has never worked on 3.8/3.9. Pre-existing doc rot, not caused by the dotenv bump. Bump to "Python 3.11+" to match — 3.11 rather than 3.10, since 3.10 satisfies python-dotenv but not splunk-ao.
  • examples/agent/weather-vibes-agent/00-tutorial/02-installation-instructions.md:9-9: This example advertises Python 3.8 in four places (01-weather-vibes-overview.md:9, 02-installation-instructions.md:9 and :261, weather-vibes-cookbook.md:24) while requirements.txt:8 depends on splunk-ao (>=3.11). Bump all four to 3.11+. While there, revisit the troubleshooting entry at 02-installation-instructions.md:239, whose suggested fix for No module named 'dotenv' is pip install python-dotenv — that cannot succeed on the interpreters the tutorial currently claims to support.
  • examples/agent/langchain-agent/requirements.txt:1-6: main.py:1 does from dotenv import load_dotenv and 00-tutorial/00-Getting-Started.md:25 documents python-dotenv as a dependency, but it is not listed here. It installs only transitively via splunk-ao. Declare it explicitly with the >=1.2.2 floor so the example is self-describing and not dependent on the root manifest's vuln floor staying in place. Separately, 00-Getting-Started.md:8 says "Python 3.8+" while splunk-ao requires >=3.11.
  • examples/dataset-experiments/requirements.txt:1-3: app.py:14, app-simple.py:5, and experiment_compare_two_models.py:11 all import dotenv, but python-dotenv is not declared here — it is satisfied only transitively through splunk-ao. Add an explicit python-dotenv>=1.2.2 entry for consistency with the other examples the PR touched. The same applies to examples/chatbot/basic-examples, whose requirements.txt omits it and whose README.md:89 instructs an unpinned pip install openai splunk-ao python-dotenv.
  • examples/agent/crewAI/research_crew/pyproject.toml:6-10: requires-python = ">=3.10,<3.14" is satisfiable for python-dotenv>=1.2.2 (needs >=3.10) but not for splunk-ao on line 9, whose requires-python is >=3.11,<3.15. A user on exactly 3.10 passes the metadata gate and then hits a resolver error. Pre-existing and unrelated to the CVE bump, but it is the same class of mismatch this PR corrected in elevenlabs-chatbot/pyproject.toml; consider aligning to >=3.11,<3.14.

Comment on lines +381 to 382
python-dotenv==1.2.2
# via pydantic-settings

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🟡 minor (other): This compiled file looks hand-edited rather than regenerated, so it is now out of sync with its source.

requirements.in:1-2 was changed to declare python-dotenv as a direct requirement, but the annotation here still lists only the transitive source. If pip-compile had actually been re-run it would read # via / # -r requirements.in / # pydantic-settings — compare flask==3.1.0 at line 77 and elastic-opentelemetry==0.8.0 at line 63, which both carry the -r requirements.in line.

The version pin is correct, so nothing installs wrong today. The cost is that the next genuine pip-compile run produces a spurious diff, and the file no longer demonstrates that the pin is reproducible from its declared source — which is the whole point of committing a compiled output. Prefer re-running pip-compile in that directory over applying the suggestion below by hand.

Suggested change
python-dotenv==1.2.2
# via pydantic-settings
python-dotenv==1.2.2
# via
# -r requirements.in
# pydantic-settings

🤖 Generated by the Astra agent

Comment thread pyproject.toml
opentelemetry-exporter-otlp-proto-http = "^1.38.0"
filelock = ">=3.20.1"
idna = ">=3.15,<4"
python-dotenv = ">=1.2.2"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🟡 minor (documentation): The explanatory comment convention introduced in this PR was applied in one place but not the other two.

examples/rag/elastic-chatbot-rag-app/requirements.in:1 now carries # security floor (VULN-88817 — python-dotenv symlink overwrite), which is exactly the right annotation. The same one-liner is missing here and at splunk-ao-a2a/pyproject.toml:53.

This matters more than usual because the entry is genuinely not a real dependency: I confirmed src/ contains no dotenv import, and the resolution actually originates from galileo-core's python-dotenv = ">=1.1.1" (poetry.lock:839). It is also not obvious from context — filelock (line 60), idna (line 61), and requests (line 63) are likewise never imported in src/, so the whole cluster reads as load-bearing runtime deps when none of them are. Without the marker, a future reader has no way to tell which of these can be dropped once the upstream floor moves past them.

Applying the identical comment in both manifests costs nothing and makes the treatment consistent across the PR.

Suggested change
python-dotenv = ">=1.2.2"
# security floor (VULN-88817 — python-dotenv symlink overwrite)
python-dotenv = ">=1.2.2"

🤖 Generated by the Astra agent

fercor-cisco
fercor-cisco previously approved these changes Aug 11, 2026
Combine python-dotenv>=1.2.2 with uv/aiohttp from main and regenerate poetry.lock files.
@shuningc
shuningc merged commit b262d25 into main Aug 11, 2026
17 checks passed
@shuningc
shuningc deleted the VULN-88817-python-dotenv-upgrade branch August 11, 2026 17:36
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.

3 participants