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

# Template Security Config

> Govern template source loading with ~/.praison/security.yaml

`~/.praison/security.yaml` decides which template sources PraisonAI may load — and now fails closed if that file cannot be parsed.

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

agent = Agent(
    name="Recipe Runner",
    instructions="Run the requested agent recipe",
)
agent.start("Load the internal onboarding recipe")
```

The template-loading side of that request is governed by the file below — a bad `security.yaml` aborts startup instead of silently reopening permissive defaults.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    Cfg["📄 ~/.praison/security.yaml"] --> Sec["🛡️ TemplateSecurity"]
    Sec --> Load["📦 template add / load"]
    Cfg -->|unparseable / non-mapping| Fail["🛑 RuntimeError — fail closed"]

    classDef cfg fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef proc fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef ok fill:#10B981,stroke:#7C90A0,color:#fff
    classDef fail fill:#8B0000,stroke:#7C90A0,color:#fff

    class Cfg cfg
    class Sec proc
    class Load ok
    class Fail fail
```

## Quick Start

<Steps>
  <Step title="Write a hardened config">
    ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # ~/.praison/security.yaml
    allow_local: false
    allow_any_github: false
    ```
  </Step>

  <Step title="Construct TemplateSecurity">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.templates import TemplateSecurity

    # Reads ~/.praison/security.yaml; raises RuntimeError on a broken file.
    security = TemplateSecurity()
    print(security.is_source_allowed("github:MervinPraison/agent-recipes"))
    ```
  </Step>
</Steps>

***

## File Location

`TemplateSecurity` reads its config from a fixed path relative to your home directory.

| Setting | Value |
| - | - |
| Path | `~/.praison/security.yaml` |
| Source | `TemplateSecurity.CONFIG_FILE = ".praison/security.yaml"` (joined with `Path.home()`) |
| Missing file | Permissive `SecurityConfig()` defaults |

***

## Configuration Options

Every field maps to `praisonai.templates.security.SecurityConfig`.

| Option | Type | Default | Description |
| - | - | - | - |
| `allowed_sources` | `Set[str]` | `{"github:MervinPraison/agent-recipes", "package:agent_recipes"}` | Explicit allowlist of template sources. |
| `allow_local` | `bool` | `True` | Allow loading templates from any local path. |
| `allow_any_github` | `bool` | `True` | Allow loading templates from any `github:` source, not just the allowlist. |
| `allow_http` | `bool` | `False` | Allow non-HTTPS URLs. |
| `require_checksum` | `bool` | `False` | Require an integrity checksum for downloads. |
| `max_template_size` | `int` | `10485760` (10 MiB) | Cap on template payload size. |

<Warning>
  Class defaults stay permissive (`allow_local=True`, `allow_any_github=True`). A config file that exists and parses cleanly but omits those keys still gets `True`. Set them explicitly to harden.
</Warning>

***

## File-Parse Behaviour

`_load_config` fails closed — a broken file aborts startup rather than silently reverting to permissive defaults.

| Input | Behaviour |
| - | - |
| No file | `SecurityConfig()` defaults |
| Empty file (`yaml.safe_load → None`) | `SecurityConfig()` defaults |
| Valid mapping | Parsed into `SecurityConfig` |
| Non-mapping (bare scalar, list, `false`) | Raises `RuntimeError("Refusing to start: security config <path> must be a mapping, got <type>.")` |
| YAML syntax error / permission error / any parse exception | Raises `RuntimeError("Refusing to start: security config <path> could not be parsed: <exc>")` |

Quote these verbatim so operators can grep for them:

```text theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
RuntimeError: Refusing to start: security config /home/user/.praison/security.yaml could not be parsed: <cause>
RuntimeError: Refusing to start: security config /home/user/.praison/security.yaml must be a mapping, got <type>.
```

***

## Common Patterns

Harden every field explicitly so an omitted key never re-opens a default:

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# ~/.praison/security.yaml
allowed_sources:
  - github:internal/agent-recipes
  - package:agent_recipes
allow_local: false
allow_any_github: false
allow_http: false
require_checksum: true
max_template_size: 5242880  # 5 MiB
```

This file governs *template source* loading. `PRAISONAI_ALLOW_LOCAL_TOOLS` governs *tool code execution*. They are complementary, not redundant — a hardened `security.yaml` still needs `PRAISONAI_ALLOW_LOCAL_TOOLS` left unset to keep `tools.py` autoload off.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Q{What are you gating?}
    Q -->|Template source| Y["📄 security.yaml<br/>allow_local / allow_any_github"]
    Q -->|Tool code execution| E["🔒 PRAISONAI_ALLOW_LOCAL_TOOLS"]

    classDef decision fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef cfg fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef env fill:#8B0000,stroke:#7C90A0,color:#fff

    class Q decision
    class Y cfg
    class E env
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Keep the file under source control">
    Version `security.yaml` for your ops team so `allow_any_github: false` and the allowlist are auditable.
  </Accordion>

  <Accordion title="Validate YAML before deploying">
    A single bad line now aborts startup rather than silently reopening permissive defaults. Lint the file in CI before it ships.
  </Accordion>

  <Accordion title="Do not rely on restrictive class defaults">
    An existing config that omits `allow_local` / `allow_any_github` still gets `True`. Set both keys explicitly.
  </Accordion>

  <Accordion title="Pair with the tool-execution gate">
    `security.yaml` controls template sources; keep `PRAISONAI_ALLOW_LOCAL_TOOLS` unset to keep tool-code execution off.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Security Environment Variables" icon="shield-check" href="/docs/features/security-environment-variables">
    Control tool-code execution with `PRAISONAI_ALLOW_LOCAL_TOOLS`
  </Card>

  <Card title="Templates" icon="file-code" href="/docs/cli/templates">
    Load and render agent recipe templates
  </Card>

  <Card title="Tools Override" icon="wrench" href="/docs/cli/tools-override">
    Load custom tools from files and modules
  </Card>

  <Card title="tools add" icon="download" href="/docs/features/tools-add">
    Install a tool package from the CLI
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.