> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Security Environment Variables

> Control security-sensitive features with environment variables

Security environment variables control opt-in access to potentially dangerous operations, ensuring secure defaults for RCE and session hijacking prevention.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Security Model"
        App[🚀 App Start] --> Check{🔍 Env Var?}
        Check -->|Set| Allow[✅ Allow Feature]
        Check -->|Unset| Block[🛡️ Block Feature]
        Block --> Safe[💼 Safe Mode]
        Allow --> Risk[⚠️ Risk Mode]
    end
    
    classDef app fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef check fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef safe fill:#10B981,stroke:#7C90A0,color:#fff
    classDef risk fill:#8B0000,stroke:#7C90A0,color:#fff
    
    class App app
    class Check check
    class Allow,Risk risk
    class Block,Safe safe
```

## Quick Start

<Steps>
  <Step title="Enable Local Tools">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    export PRAISONAI_ALLOW_LOCAL_TOOLS=true
    python -m praisonai "Create a report using tools.py"
    ```
  </Step>

  <Step title="Enable Job Workflows">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    export PRAISONAI_ALLOW_JOB_WORKFLOWS=true
    praisonai --workflow job_workflow.yaml
    ```
  </Step>

  <Step title="Enable Remote Browser">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    export PRAISONAI_BROWSER_ALLOW_REMOTE=true
    praisonai browser --host 0.0.0.0 --port 8080
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant PraisonAI
    participant SecurityCheck
    participant Feature
    
    User->>PraisonAI: Request Feature
    PraisonAI->>SecurityCheck: Check Env Var
    SecurityCheck-->>PraisonAI: Allowed/Blocked
    alt Environment Variable Set
        PraisonAI->>Feature: Execute
        Feature-->>User: Result
    else Environment Variable Unset
        PraisonAI-->>User: Security Block
    end
```

| Phase       | Action                            | Default Behavior           |
| ----------- | --------------------------------- | -------------------------- |
| **Startup** | Check environment variables       | Block dangerous features   |
| **Request** | Validate security permissions     | Allow only safe operations |
| **Execute** | Run with appropriate restrictions | Fail-safe mode active      |

***

## Environment Variables

### PRAISONAI\_ALLOW\_LOCAL\_TOOLS

Controls automatic loading of `tools.py` files from the current working directory.

**Security Risk**: Remote Code Execution (RCE) via malicious tools.py files

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Enable local tools loading
export PRAISONAI_ALLOW_LOCAL_TOOLS=true

# Disable (default - secure)
unset PRAISONAI_ALLOW_LOCAL_TOOLS
```

**Affected Components** (verified against PR #1583 head `12eb019b`):

* `praisonaiagents` agent generator (`load_tools_from_tools_py`, `generate_crew_and_kickoff`)
* `praisonai run` YAML workflows (recipe `tools.py` under `_run_yaml_workflow`)
* `praisonai research --tools <file.py>`
* `praisonai chat --rewrite-tools <file.py>` and `--expand-tools <file.py>`
* Generic CLI `_load_tools(tools_path)`
* HTTP API: `praisonai.api.call.import_tools_from_file` (raises `ValueError` if disabled)
* Path-traversal guard: files outside the current working directory are refused even when `PRAISONAI_ALLOW_LOCAL_TOOLS=true`

<Note>
  Even when `PRAISONAI_ALLOW_LOCAL_TOOLS=true`, the loader refuses any path outside the current working directory. This is a deliberate defence-in-depth layer for HTTP-API callers (`praisonai.api.call.import_tools_from_file`) where the path can come from network input. Move the `tools.py` you want to load into your CWD if you hit `Refusing to exec ... outside working directory.` in the logs.
</Note>

`PRAISONAI_ALLOW_LOCAL_TOOLS` accepts only `true` (case-insensitive). Values like `1`, `yes`, or `on` are **not** truthy for this variable (unlike `PRAISONAI_ALLOW_TEMPLATE_TOOLS`).

**Usage Example**:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent

# This will only work if PRAISONAI_ALLOW_LOCAL_TOOLS=true
agent = Agent(
    name="Tool User",
    instructions="Use tools from tools.py to help the user"
)

agent.start("Calculate using local tools")
```

**Error & Warning Messages**

| When                                                            | Where it appears         | Message                                                                                       |
| --------------------------------------------------------------- | ------------------------ | --------------------------------------------------------------------------------------------- |
| Env var unset, CLI tool loader (research/rewrite/expand/recipe) | stdout (rich `[yellow]`) | `Warning: Tools loading disabled. Set PRAISONAI_ALLOW_LOCAL_TOOLS=true to enable.`            |
| Env var unset, agent generator                                  | logger.warning           | `Refusing to exec tools.py: set PRAISONAI_ALLOW_LOCAL_TOOLS=true to enable.`                  |
| Env var unset, HTTP API (`api/call.py`)                         | raised exception         | `ValueError("Local tools loading disabled. Set PRAISONAI_ALLOW_LOCAL_TOOLS=true to enable.")` |
| Path outside CWD, env var **set**                               | logger.warning           | `Refusing to exec <path>: outside working directory.`                                         |
| Path outside CWD via HTTP API, env var **set**                  | raised exception         | `LocalToolsDisabled("Refusing to exec <path>: outside working directory.")`                   |

### PRAISONAI\_ALLOW\_TEMPLATE\_TOOLS

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)

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Enable template tools autoload
export PRAISONAI_ALLOW_TEMPLATE_TOOLS=1

# Disable (default - secure)
unset PRAISONAI_ALLOW_TEMPLATE_TOOLS
```

**Default**: unset → disabled\
**Accepted truthy values**: `1`, `true`, `yes`, `on` (case-insensitive, whitespace-stripped)

**Affected Components**:

* `praisonai.templates.tool_override.create_tool_registry_with_overrides`
* `praisonai.templates.tool_override.resolve_tools`

**Note**: Explicit `override_files`, `override_dirs`, and `tools_sources` continue to work without this opt-in and are the recommended way to load custom tools.

**Usage Example**:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.templates.tool_override import create_tool_registry_with_overrides

# This will only load implicit tools.py if PRAISONAI_ALLOW_TEMPLATE_TOOLS=1
registry = create_tool_registry_with_overrides(include_defaults=True)

# Explicit loading works without the env var
registry = create_tool_registry_with_overrides(
    override_files=["./my_tools.py"],  # Always works
    include_defaults=True
)
```

### PRAISONAI\_ALLOW\_JOB\_WORKFLOWS

Controls execution of job and hybrid workflow types that can run shell commands and scripts.

**Security Risk**: Remote Code Execution (RCE) via malicious YAML workflows

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Enable job workflows
export PRAISONAI_ALLOW_JOB_WORKFLOWS=true

# Disable (default - secure)  
unset PRAISONAI_ALLOW_JOB_WORKFLOWS
```

**Workflow Types Affected**:

* **Job workflows**: Direct shell, Python, and script execution
* **Hybrid workflows**: Combined agent + job execution

**Usage Example**:

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# job_workflow.yaml
type: job
steps:
  - name: setup
    shell: |
      echo "Setting up environment"
      pip install requirements.txt
      
  - name: process
    python: |
      import os
      result = os.listdir(".")
      print(f"Files: {result}")
```

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Only works with PRAISONAI_ALLOW_JOB_WORKFLOWS=true
praisonai --workflow job_workflow.yaml
```

### PRAISONAI\_BROWSER\_ALLOW\_REMOTE

Controls browser server binding to non-loopback interfaces (0.0.0.0, remote IPs).

**Security Risk**: WebSocket session hijacking and unauthorized browser access

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Enable remote browser access
export PRAISONAI_BROWSER_ALLOW_REMOTE=true

# Disable (default - secure, localhost only)
unset PRAISONAI_BROWSER_ALLOW_REMOTE
```

**Default Behavior**:

* Binds to `127.0.0.1` (localhost only)
* Blocks attempts to bind to `0.0.0.0` or remote interfaces

**Usage Example**:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.browser import BrowserServer

# This will only bind to 0.0.0.0 if PRAISONAI_BROWSER_ALLOW_REMOTE=true
# Otherwise falls back to 127.0.0.1
server = BrowserServer(host="0.0.0.0", port=8080)
server.start()
```

### PRAISONAI\_RUN\_SYNC\_TIMEOUT

Default maximum seconds the wrapper's sync-to-async bridge will wait for a coroutine to complete.

**Default:** `300` (5 minutes)

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Tighten for latency-sensitive servers
export PRAISONAI_RUN_SYNC_TIMEOUT=30

# Loosen for long-running batch jobs
export PRAISONAI_RUN_SYNC_TIMEOUT=3600
```

Applies to every `praisonai` CLI entry and wrapper-based server (gateway, a2u, mcp\_server, scheduler). The SDK (`praisonaiagents`) uses a separate bridge — see [Async Bridge](/docs/features/async-bridge).

***

## Common Patterns

<Tabs>
  <Tab title="Development Mode">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Enable all features for development
    export PRAISONAI_ALLOW_LOCAL_TOOLS=true
    export PRAISONAI_ALLOW_TEMPLATE_TOOLS=true
    export PRAISONAI_ALLOW_JOB_WORKFLOWS=true  
    export PRAISONAI_BROWSER_ALLOW_REMOTE=true
    export PRAISONAI_RUN_SYNC_TIMEOUT=30

    # Add to ~/.bashrc or ~/.zshrc for persistence
    echo 'export PRAISONAI_ALLOW_LOCAL_TOOLS=true' >> ~/.bashrc
    ```
  </Tab>

  <Tab title="Production Mode">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Secure defaults - explicitly unset dangerous variables
    unset PRAISONAI_ALLOW_LOCAL_TOOLS
    unset PRAISONAI_ALLOW_TEMPLATE_TOOLS
    unset PRAISONAI_ALLOW_JOB_WORKFLOWS
    unset PRAISONAI_BROWSER_ALLOW_REMOTE
    export PRAISONAI_RUN_SYNC_TIMEOUT=300

    # Or use systemd service with secure environment
    # /etc/systemd/system/praisonai.service
    [Service]
    Environment="PRAISONAI_ALLOW_LOCAL_TOOLS=false"
    Environment="PRAISONAI_ALLOW_TEMPLATE_TOOLS=false"
    Environment="PRAISONAI_ALLOW_JOB_WORKFLOWS=false"
    Environment="PRAISONAI_BROWSER_ALLOW_REMOTE=false"
    Environment="PRAISONAI_RUN_SYNC_TIMEOUT=300"
    ```
  </Tab>

  <Tab title="Docker Deployment">
    ```dockerfile theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Secure Docker deployment
    FROM python:3.11-slim

    # Secure defaults - do not set dangerous env vars
    # ENV PRAISONAI_ALLOW_LOCAL_TOOLS=true  # DON'T DO THIS

    COPY . /app
    WORKDIR /app
    RUN pip install praisonai

    # Only enable specific features if needed
    # ENV PRAISONAI_ALLOW_JOB_WORKFLOWS=true  # Only if required

    CMD ["python", "-m", "praisonai"]
    ```
  </Tab>
</Tabs>

***

## Migration Guide

### Upgrading from Vulnerable Versions

<Steps>
  <Step title="Identify Usage">
    Check if you use any of these features:

    * Local `tools.py` files
    * Recipes / templates that ship a `tools.py` and rely on it being implicitly loaded
    * Job or hybrid workflows with shell/script execution
    * Browser server binding to `0.0.0.0`
    * HTTP API callers that pass a `file_path` to `praisonai.api.call.import_tools_from_file` — these now raise `ValueError` until you opt in
  </Step>

  <Step title="Add Environment Variables">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Only add variables for features you actually use
    export PRAISONAI_ALLOW_LOCAL_TOOLS=true      # If you use tools.py
    export PRAISONAI_ALLOW_TEMPLATE_TOOLS=1      # If you rely on implicit template/CWD tools.py autoload
    export PRAISONAI_ALLOW_JOB_WORKFLOWS=true    # If you use job workflows
    export PRAISONAI_BROWSER_ALLOW_REMOTE=true   # If you bind browser to 0.0.0.0
    export PRAISONAI_RUN_SYNC_TIMEOUT=300        # Adjust timeout as needed
    ```
  </Step>

  <Step title="Test Functionality">
    Verify your existing workflows still work:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Test local tools
    praisonai "Use local tools to help me"

    # Test job workflows  
    praisonai --workflow your_job_workflow.yaml

    # Test remote browser
    praisonai browser --host 0.0.0.0
    ```
  </Step>

  <Step title="Review Security">
    Evaluate if you really need each dangerous feature:

    * Can you avoid local tools.py files?
    * Can you use agent workflows instead of job workflows?
    * Can you use localhost-only browser access?
  </Step>
</Steps>

***

## Best Practices

<AccordionGroup>
  <Accordion title="🔒 Principle of Least Privilege">
    Only enable environment variables for features you actively use. Each variable increases your attack surface.

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # BAD - Enables everything
    export PRAISONAI_ALLOW_LOCAL_TOOLS=true
    export PRAISONAI_ALLOW_JOB_WORKFLOWS=true
    export PRAISONAI_BROWSER_ALLOW_REMOTE=true

    # GOOD - Only enable what you need
    export PRAISONAI_ALLOW_LOCAL_TOOLS=true  # Only if you use tools.py
    ```
  </Accordion>

  <Accordion title="🏢 Production Environment Isolation">
    Never enable dangerous variables in production unless absolutely necessary. Use staging environments for testing.

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Production - secure defaults
    unset PRAISONAI_ALLOW_LOCAL_TOOLS
    unset PRAISONAI_ALLOW_JOB_WORKFLOWS
    unset PRAISONAI_BROWSER_ALLOW_REMOTE

    # Development/Staging - enable as needed
    export PRAISONAI_ALLOW_LOCAL_TOOLS=true
    ```
  </Accordion>

  <Accordion title="📁 File System Security">
    When `PRAISONAI_ALLOW_LOCAL_TOOLS=true` or `PRAISONAI_ALLOW_TEMPLATE_TOOLS=1` is set, ensure your working directory doesn't contain untrusted `tools.py` files. This is especially risky for recipes fetched from remote registries.

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Check for tools.py before running
    ls -la tools.py 2>/dev/null && echo "WARNING: tools.py found"

    # Run from clean directory
    mkdir -p /tmp/clean_workspace
    cd /tmp/clean_workspace
    praisonai "Your task here"
    ```
  </Accordion>

  <Accordion title="🌐 Network Security">
    When `PRAISONAI_BROWSER_ALLOW_REMOTE=true`, use firewalls and authentication to protect browser endpoints.

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Use specific IP instead of 0.0.0.0 when possible
    export PRAISONAI_BROWSER_ALLOW_REMOTE=true
    praisonai browser --host 192.168.1.100 --port 8080

    # Consider using reverse proxy with authentication
    # nginx, caddy, or similar with basic auth
    ```
  </Accordion>
</AccordionGroup>

***

## Security Advisories

These environment variables address the following security vulnerabilities:

| Advisory                | Severity | Description                                     | Environment Variable             |
| ----------------------- | -------- | ----------------------------------------------- | -------------------------------- |
| **GHSA-g985-wjh9-qxxc** | High     | RCE via Automatic tools.py Import               | `PRAISONAI_ALLOW_LOCAL_TOOLS`    |
| **GHSA-xcmw-grxf-wjhj** | High     | Implicit RCE via template/CWD tools.py autoload | `PRAISONAI_ALLOW_TEMPLATE_TOOLS` |
| **GHSA-vc46-vw85-3wvm** | Critical | RCE via job workflow YAML                       | `PRAISONAI_ALLOW_JOB_WORKFLOWS`  |
| **GHSA-8x8f-54wf-vv92** | Critical | WebSocket session hijacking                     | `PRAISONAI_BROWSER_ALLOW_REMOTE` |

**CVE IDs**: Pending assignment by GitHub Security Advisory system

**Fixed Versions**:

* **praisonai**: `>=0.0.57`
* **praisonaiagents**: `>=0.0.23`

PR #1583 (2026-04-30) extended `PRAISONAI_ALLOW_LOCAL_TOOLS` enforcement to research/rewrite/expand/recipe tool-loading paths and the HTTP API, and added a CWD-only path constraint as defence-in-depth. No new advisory was filed; the threat model is unchanged from GHSA-g985-wjh9-qxxc.

***

## Related

<CardGroup cols={2}>
  <Card title="Guardrails" icon="shield" href="/docs/features/guardrails">
    Content filtering and safety controls
  </Card>

  <Card title="Permissions" icon="key" href="/docs/features/permissions">
    Agent permission management system
  </Card>
</CardGroup>
