# AIRS Python SDK

**Turn the framework into running code.**

The AIRS Python SDK implements the three-layer security architecture as a drop-in library for Python AI applications. Instead of reading about controls, you can `pip install` them. Like the framework itself, the SDK is designed to be risk-proportionate: use the components you need for your risk tier, leave out the ones you do not.

## Bring Your Own Model

The SDK is **model-agnostic**. It does not call AI models for you. It wraps security controls *around* your existing model calls. You continue using whatever model, provider, or framework you already have:

```python
# 1. AIRS checks the input
input_result = await pipeline.evaluate_input(request)

# 2. You call YOUR model - OpenAI, Anthropic, Bedrock, Ollama, local, anything
ai_output = await your_model(request.input_text)

# 3. AIRS checks the output
output_result = await pipeline.evaluate_output(request, response)
```

AIRS only sees the text going in and the text coming out. It doesn't know or care which model you're using, how you're calling it, or what framework it runs on. This means it works with:

- **Any model provider**: OpenAI, Anthropic, Google, Mistral, Cohere, local models
- **Any framework**: LangChain, LlamaIndex, Haystack, raw API calls
- **Any architecture**: single model, RAG, agents, multi-agent orchestration

The one exception is the optional **LLM-as-Judge**, which does call an OpenAI-compatible API to *evaluate* outputs. This is the judge model, a separate, independent model used for security evaluation, not your production model.

## What It Provides

| Component | What It Does |
|-----------|-------------|
| **Guardrails** | Regex-based prompt injection detection, PII filtering, content policy (extensible) |
| **LLM-as-Judge** | Rule-based (no API key) or LLM-based (OpenAI-compatible) output evaluation |
| **Circuit Breaker** | Sliding-window failure tracking, auto-trip, manual emergency stop, recovery |
| **PACE Controller** | State machine for structured degradation (Primary → Alternate → Contingency → Emergency) |
| **Security Pipeline** | Orchestrates all layers with configurable behavior per PACE state |
| **Agent Security** | Identity propagation, delegation depth enforcement, cycle detection, scope narrowing |
| **Tool Policy Engine** | Tool-call → policy → allow/deny. Deny-list, allow-list, per-agent-type restrictions |
| **Telemetry & Audit** | Structured security events with correlation IDs, pluggable audit sinks for SOC integration |
| **CLI Assessment** | Interactive tool that classifies your deployment and recommends controls |
| **FastAPI Middleware** | Drop-in middleware that protects AI endpoints automatically |

## Install

```bash
pip install airs
```

That's it. You now have the core SDK (guardrails, circuit breaker, PACE, telemetry) and the `airs` CLI.

### Optional extras

```bash
# With FastAPI middleware
pip install "airs[fastapi]"

# With LLM-as-Judge (requires OpenAI-compatible API)
pip install "airs[judge]"

# Everything
pip install "airs[all]"
```

### Verify it works

```bash
# Check version
airs version

# Run the interactive assessment
airs assess

# Machine-readable output
airs assess --json --non-interactive
```

!!! tip "No external dependencies for core"
    The core SDK (guardrails, circuit breaker, PACE) requires only `pydantic`, `rich`, and `typer`. No API keys or external services needed to get started.

??? note "Install from source"
    If you prefer to install from source:

    ```bash
    git clone https://github.com/JonathanCGill/airuntimesecurity.io.git
    cd airuntimesecurity.io
    pip install ".[all,dev]"
    ```

## 5-Minute Quick Start

```python
import asyncio
from airs.core.models import AIRequest, AIResponse
from airs.runtime import (
    SecurityPipeline, GuardrailChain, RegexGuardrail,
    CircuitBreaker, PACEController,
)

async def main():
    # Build the pipeline
    pipeline = SecurityPipeline(
        guardrails=GuardrailChain([RegexGuardrail()]),
        circuit_breaker=CircuitBreaker(),
        pace=PACEController(),
    )

    # Evaluate input before calling your model
    request = AIRequest(input_text="What is the capital of France?")
    input_result = await pipeline.evaluate_input(request)

    if not input_result.allowed:
        print(f"Blocked: {input_result.blocked_by}")
        return

    # Call your AI model (replace with your actual model call)
    ai_output = "The capital of France is Paris."

    # Evaluate output before returning to user
    response = AIResponse(request_id=request.request_id, output_text=ai_output)
    output_result = await pipeline.evaluate_output(request, response)

    if output_result.allowed:
        print(ai_output)
    else:
        print(f"Response blocked: {output_result.blocked_by}")

asyncio.run(main())
```

## Model Integration

The SDK is model-agnostic — it wraps security controls around your existing model calls. The quick start above uses a hardcoded string in place of a real model. To test against a live model, use the CLI:

```bash
# Test against OpenAI
airs assess --provider openai --model gpt-4o --non-interactive

# Test against Anthropic
airs assess --provider anthropic --model claude-sonnet-4-20250514 --non-interactive
```

This sends test prompts through the full AIRS pipeline against a live model and shows what gets blocked. See [Live model testing](#live-model-testing-optional) below for details on API keys and costs.

## CLI Assessment

Classify your deployment and get a prioritized implementation plan:

```bash
airs assess
```

The tool asks about your deployment context (audience, data sensitivity, autonomy, architecture) and outputs:

- **Risk tier** (LOW / MEDIUM / HIGH / CRITICAL)
- **Risk factors and mitigations** specific to your deployment
- **PACE resilience posture**: what happens at each degradation level
- **Prioritized control list**: what to implement first
- **Code snippet** to get started

For machine-readable output:

```bash
airs assess --json
```

### Live model testing (optional)

You can also run the assessment against a live AI model. This sends test prompts (clean questions + injection/jailbreak attempts) through the full AIRS security pipeline and shows what gets blocked and what gets through.

```bash
# Test against OpenAI
airs assess --provider openai --model gpt-4o --non-interactive --json

# Test against Anthropic
airs assess --provider anthropic --model claude-sonnet-4-20250514 --non-interactive --json

# Omit --model to use the default for each provider
airs assess --provider openai --non-interactive
```

**No API key? No problem.** The assessment works perfectly without `--provider`. Live model testing is entirely optional — it just adds a real-world demo of the guardrails in action.

!!! info "API keys and costs"
    Live model testing requires an API key from your chosen provider. If the key isn't set as an environment variable, `airs assess` will prompt you to paste it.

    **Get an API key:**

    - **OpenAI**: [platform.openai.com/api-keys](https://platform.openai.com/api-keys)
    - **Anthropic**: [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys)

    **Set it for future runs:**

    ```bash
    # OpenAI
    export OPENAI_API_KEY=sk-your-key-here

    # Anthropic
    export ANTHROPIC_API_KEY=sk-ant-your-key-here
    ```

    **Costs:** Each live test run makes a small number of API calls (4 short prompts). This typically costs a few cents on your account. No calls are made unless you explicitly use `--provider`.

## What's Next

| Guide | Description |
|-------|-------------|
| [Guardrails](guardrails.md) | Layer 1: input/output filtering, custom guardrails, chaining |
| [Judge](judge.md) | Layer 2: rule-based and LLM-based evaluation |
| [Circuit Breaker & PACE](resilience.md) | Emergency stop and structured degradation |
| [Pipeline](pipeline.md) | Full pipeline orchestration and configuration |
| [Agent Security](agents.md) | Identity propagation, delegation enforcement, tool access control |
| [Telemetry & Audit](telemetry.md) | Structured security events, audit sinks, SOC integration |
| [FastAPI Integration](fastapi.md) | Drop-in middleware for FastAPI apps |
| [Examples](examples.md) | Complete working examples |
| [What the Tests Prove](tests.md) | 160 tests that demonstrate every claim — and document every known gap |

## Get the Code

Install from PyPI:

```bash
pip install airs
```

Or install from source for development:

```bash
git clone https://github.com/JonathanCGill/airuntimesecurity.io.git
cd airuntimesecurity.io
pip install ".[all,dev]"
```

## Run the Tests

```bash
python -m pytest tests/ -v
```

All 160 tests pass in under a second with no network access. See [What the Tests Prove](tests.md) for what each test demonstrates and why the adversarial test suite documents both what the guardrails catch *and* what they miss.

## Run the Examples

```bash
# Quickstart: all layers in 60 lines
python examples/quickstart.py

# FastAPI app with AIRS middleware
pip install ".[fastapi]"
uvicorn examples.fastapi_app:app --reload
```

## Architecture

![AIRS Security Pipeline](../images/sdk-pipeline-architecture.svg)

## Project Structure

```
src/airs/
├── agents/
│   ├── identity.py          # AgentIdentity, AgentContext, chain propagation
│   └── delegation.py        # DelegationPolicy, DelegationEnforcer
├── cli/
│   ├── __init__.py          # CLI app setup
│   └── assess.py            # Interactive assessment
├── core/
│   ├── models.py            # RiskTier, PACEState, AIRequest, LayerResult
│   ├── controls.py          # 25+ controls in queryable registry
│   └── risk.py              # Risk classification engine
├── runtime/
│   ├── guardrail.py         # Layer 1: Regex, ContentPolicy, Chain
│   ├── judge.py             # Layer 2: RuleBased, LLM
│   ├── circuit_breaker.py   # Emergency stop
│   ├── pace.py              # PACE state machine
│   ├── pipeline.py          # Full pipeline orchestrator
│   └── tool_policy.py       # Tool access control (allow/deny)
├── telemetry/
│   ├── events.py            # AISecurityEvent schema, EventType, emit()
│   └── audit.py             # AuditSink, LogSink, BufferSink, CallbackSink
└── integrations/
    └── fastapi.py           # Drop-in middleware

tests/                       # 160 tests (run them: python -m pytest tests/ -v)
examples/
├── quickstart.py            # Minimal working example
└── fastapi_app.py           # Complete FastAPI app
```
