Skip to content

docs: document PRAISONAI_ALLOW_TEMPLATE_TOOLS opt-in (GHSA-xcmw-grxf-wjhj, PR #1579) #285

@MervinPraison

Description

@MervinPraison

Background

Upstream PR MervinPraison/PraisonAI#1579 (merged on main, head SHA 0892578b03622cf53d8eb9497cc268c6d22e133b) ships a security fix that changes documented behaviour: implicit tools.py autoload from the current working directory and from a recipe template directory is now disabled by default, gated behind a new opt-in environment variable.

This issue tracks the documentation updates required so the public docs match the new behaviour. Several existing pages in MervinPraison/PraisonAIDocs are now outdated/misleading and one page (security env vars) is missing a new entry.

Note for the doc-writing agent: This is a content update + augmentation task — it does not require a brand-new top-level page. Two existing pages must be updated, one existing page must get a new env var section, and a security callout should be added to the recipe pages where appropriate. Do not modify any file under docs/concepts/ (per AGENTS.md folder placement rules — concepts is human-approved-only).


Summary of the SDK change

File changed: src/praisonai/praisonai/templates/tool_override.py
Advisory: GHSA-xcmw-grxf-wjhj
New env var: PRAISONAI_ALLOW_TEMPLATE_TOOLS
Accepted truthy values: 1, true, yes, on (case-insensitive, whitespace-stripped)
Default: unset → disabled → safe-by-default

Threat that was fixed

Previously, create_tool_registry_with_overrides() and resolve_tools() walked into the current working directory and the recipe template directory and exec_module()-d any tools.py they found. When a recipe is fetched from a remote registry (e.g. via the GitHub recipe-share workflow), this gave an unauthenticated attacker arbitrary code execution in the server process the moment the recipe was loaded — tools.py ran at import time, before any allow-list, sandbox, or approval check fired.

What is now gated behind the opt-in

Path Status before PR #1579 Status after PR #1579
Implicit ./tools.py (CWD) autoload Always on Off by default; opt in with PRAISONAI_ALLOW_TEMPLATE_TOOLS=1
Implicit <template_dir>/tools.py autoload Always on Off by default; opt in with PRAISONAI_ALLOW_TEMPLATE_TOOLS=1

What still works without the opt-in (no change)

Entry point Status
override_files=[...] (explicit file paths) Unchanged — supported
override_dirs=[...] (explicit directory scan) Unchanged — supported
tools_sources=... (from TEMPLATE.yaml) Unchanged — supported
registry={...} (caller-built registry) Unchanged — supported

Reference helper added in the SDK

# praisonai/templates/tool_override.py
def _autoload_tools_enabled() -> bool:
    val = os.environ.get("PRAISONAI_ALLOW_TEMPLATE_TOOLS", "").strip().lower()
    return val in ("1", "true", "yes", "on")

Failure to load a tools.py is now logged at DEBUG level (it used to be silently swallowed) — opt-in users can see why a broken tools.py did not load.

Relationship to the existing PRAISONAI_ALLOW_LOCAL_TOOLS variable

Important — these are two different env vars. Do not merge them.

Env var Module Scope Advisory
PRAISONAI_ALLOW_LOCAL_TOOLS (already documented) CLI / AgentsGenerator / YAML workflows tool resolver CLI-level CWD tools.py autoload GHSA-g985-wjh9-qxxc
PRAISONAI_ALLOW_TEMPLATE_TOOLS (new — this issue) praisonai.templates.tool_override Template-registry CWD + template_dir/tools.py autoload GHSA-xcmw-grxf-wjhj

Both gate tools.py autoload, but at different layers. They must be documented as separate, complementary controls.


Files to update in PraisonAIDocs

1. docs/cli/tools-override.mdxcontent update (highest priority, currently misleading)

The page currently tells users that ./tools.py is "Priority 1" and is automatically loaded, and the Security section claims "No automatic code execution on import" — both statements are now incorrect/misleading without the opt-in env var.

Required edits:

  • Remove or rewrite the existing <Note> that says "If a tools.py file exists in your current working directory, it will be automatically loaded when running templates or agents. This is the easiest way to add project-specific tools." It is not the easiest way any more — explicit override_files=[...] is. Replace with a <Warning> callout that explains the implicit CWD autoload is disabled by default and requires PRAISONAI_ALLOW_TEMPLATE_TOOLS=1.
  • In the Default Custom Tool Directories table, mark the ./tools.py row as "opt-in only — requires PRAISONAI_ALLOW_TEMPLATE_TOOLS=1". The ~/.praisonai/tools and ~/.config/praison/tools rows are unaffected (they are override_dirs-style, explicit-by-config).
  • Update the Security → Safe Defaults bullet list. Replace the misleading "No automatic code execution on import" with a more accurate phrasing such as "Implicit tools.py autoload from CWD or template directories is disabled by default — opt in with PRAISONAI_ALLOW_TEMPLATE_TOOLS=1".
  • Add a new short subsection "Opting in to implicit tools.py autoload" under Security, with:
    • The env var name and accepted truthy values (1, true, yes, on).
    • A copy-paste opt-in example: export PRAISONAI_ALLOW_TEMPLATE_TOOLS=1.
    • A one-liner explaining the recommended path is explicit override_files/override_dirs/tools_sources and that the env var exists only to preserve legacy local workflows.
    • Cross-link to docs/features/security-environment-variables.mdx.
  • Add a friendly mermaid diagram showing the decision tree:
    • "Did the caller pass override_files/override_dirs/tools_sources?" → yes → loaded.
    • Otherwise → "Is PRAISONAI_ALLOW_TEMPLATE_TOOLS=1 set?" → yes → CWD/template tools.py loaded; no → skipped.

2. docs/features/security-environment-variables.mdxadd a new env var section

This is where the project keeps its catalogue of opt-in security env vars. The new variable belongs here next to PRAISONAI_ALLOW_LOCAL_TOOLS, not folded into it.

Required edits:

  • Add a new ### PRAISONAI_ALLOW_TEMPLATE_TOOLS section, modelled on the existing PRAISONAI_ALLOW_LOCAL_TOOLS section, including:
    • One-line description: "Controls implicit tools.py autoload by the template tool-override system, both from the current working directory and from a recipe's template directory."
    • Security risk: "Remote Code Execution (RCE) when loading recipes/templates from untrusted sources (e.g. recipes fetched from a remote registry)."
    • Default: unset → disabled.
    • Accepted truthy values: 1, true, yes, on.
    • Code blocks for enabling and unsetting.
    • Affected components: praisonai.templates.tool_override.create_tool_registry_with_overrides, praisonai.templates.tool_override.resolve_tools.
    • A short note that explicit override_files / override_dirs / tools_sources continue to work without the opt-in and are the recommended way to load custom tools.
  • Update the Security Advisories table at the bottom. Add a new row:
    • Advisory: GHSA-xcmw-grxf-wjhj
    • Severity: per the upstream advisory (the doc-writing agent should fetch the GHSA page on github.com to confirm; if unreachable, mark as "see advisory" — do not invent a severity).
    • Description: "Implicit RCE via template/CWD tools.py autoload"
    • Env var: PRAISONAI_ALLOW_TEMPLATE_TOOLS
  • Update Common Patterns → Development Mode to also export PRAISONAI_ALLOW_TEMPLATE_TOOLS=true. Update Production Mode to explicitly unset PRAISONAI_ALLOW_TEMPLATE_TOOLS.
  • Update Migration Guide → Identify Usage to add a fourth bullet: "Recipes / templates that ship a tools.py and rely on it being implicitly loaded."
  • Update Migration Guide → Add Environment Variables to add the new export with the conditional comment "# If you rely on implicit template/CWD tools.py autoload".
  • Update the Best Practices → File System Security accordion to mention that the same caution applies when PRAISONAI_ALLOW_TEMPLATE_TOOLS is set, and to highlight that this is especially risky for recipes fetched from remote registries.

3. docs/cli/recipes.mdxadd a security callout

This page documents praison templates run … for built-in recipes. Most listed recipes are first-party so the day-to-day risk is low, but the page is also the natural surface where users discover the recipe runner — and the threat model in PR #1579 is specifically about recipes whose source is not fully trusted.

Required edits:

  • Near the top of the page (after Prerequisites), add a <Warning> callout:

    "Recipes shipped with PraisonAI are trusted, but if you run a third-party or remotely fetched recipe, its tools.py will only execute if you have explicitly set PRAISONAI_ALLOW_TEMPLATE_TOOLS=1. This default-deny behaviour was introduced in PR #1579 (GHSA-xcmw-grxf-wjhj). Always inspect a recipe's tools.py before opting in."

  • Cross-link to docs/features/security-environment-variables.mdx#praisonai_allow_template_tools.

4. docs/features/modular-recipes.mdxadd the same security callout

This page covers the modular-recipe surface (where users author/share recipes). Add the same <Warning> callout described in (3), worded for an author audience: "If you publish a recipe that needs custom tools, prefer declaring them under the tools_sources: / override_files: directives in TEMPLATE.yaml — those load without requiring users to set PRAISONAI_ALLOW_TEMPLATE_TOOLS."

5. docs/cli/tools-resolve.mdxadd one cross-reference line

Append a sentence at the bottom of the Code Usage section:

"resolve_tools() no longer implicitly loads <template_dir>/tools.py unless PRAISONAI_ALLOW_TEMPLATE_TOOLS=1. See Tools Override → Security for details."

6. docs/concepts/recipes.mdxDO NOT EDIT

docs/concepts/ is human-approved-only per AGENTS.md. If the doc-writing agent believes a concept-level callout is warranted, it should flag that as a follow-up in the PR description rather than editing the file.


Source-of-truth references for the doc-writing agent

When you (the next agent) pick this up, do not paraphrase from this issue alone — verify against the SDK as the agent instructions require:

  1. Read src/praisonai/praisonai/templates/tool_override.py at SHA 0892578b03622cf53d8eb9497cc268c6d22e133b (the merged head of PR #1579) — specifically _autoload_tools_enabled(), create_tool_registry_with_overrides(), and resolve_tools().
  2. Read src/praisonai/tests/unit/templates/test_tool_override_autoload_gate.py (added in this PR) for the canonical behaviour matrix — the test names are an excellent template for the doc's "what works / what doesn't" section.
  3. Read the merged PR description at fix(security): gate template tools.py autoload behind PRAISONAI_ALLOW_TEMPLATE_TOOLS PraisonAI#1579 for the threat model and the "What still works" table.
  4. Confirm GHSA-xcmw-grxf-wjhj severity / CVE on github.com before quoting it; do not invent a severity.

Suggested branch / PR

  • Branch: claude/admiring-euler-H1T0v (per the per-session branch instructions issued to the agent that picks this up).
  • Single PR is fine — these edits are tightly coupled and reviewing them together avoids drift.
  • Verify docs.json is still valid JSON if any nav entries are added (none are required by this issue, but double-check).

Acceptance criteria

  • docs/cli/tools-override.mdx no longer claims ./tools.py is auto-loaded by default; the misleading "No automatic code execution on import" line is replaced.
  • docs/features/security-environment-variables.mdx has a new PRAISONAI_ALLOW_TEMPLATE_TOOLS section, an updated advisories table, and updated Development/Production/Migration patterns.
  • docs/cli/recipes.mdx and docs/features/modular-recipes.mdx have a security <Warning> callout about untrusted recipe tools.py.
  • docs/cli/tools-resolve.mdx has a one-line cross-reference.
  • No file under docs/concepts/ is modified.
  • All code blocks copy-paste-run; truthy values match the SDK exactly (1, true, yes, on).
  • All cross-links resolve.

Triggered by webhook for pull_request.closed on MervinPraison/PraisonAI#1579 (merged into main 2026-04-28).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingclaudeTrigger Claude Code analysisdocumentationImprovements or additions to documentationsecurity

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions