Metadata-Version: 2.4
Name: authsec-crewai
Version: 0.1.0
Summary: AuthSec integration for CrewAI — secure AI delegation token retrieval
Author-email: AuthSec <support@authnull.com>
License: MIT
Project-URL: Homepage, https://authnull.com
Project-URL: Repository, https://github.com/authsec-ai/authsec-ai-integrations
Keywords: authsec,crewai,ai,security,delegation,jwt
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.31.0
Requires-Dist: authsec-langchain-sdk>=0.1.1
Requires-Dist: pydantic>=2.0.0
Provides-Extra: crewai
Requires-Dist: crewai>=0.28.0; extra == "crewai"
Provides-Extra: jwt
Requires-Dist: PyJWT>=2.8; extra == "jwt"
Requires-Dist: cryptography>=41; extra == "jwt"

# AuthSec AI — CrewAI Integration

![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue) ![authsec-langchain-sdk 0.1.1](https://img.shields.io/badge/authsec--langchain--sdk-0.1.1-green) ![MIT License](https://img.shields.io/badge/license-MIT-lightgrey)

**Tool-based delegation** — a CrewAI `BaseTool` acquires a short-lived AuthSec delegation token and uses it to call protected APIs on behalf of an AI agent.

---

## Architecture

```
CrewAI Tool (tools.py)  — BaseTool subclass
  ↓
authsec_helper.py       — thin wrapper, MOCK fallback, debug logging
  ↓
authsec-langchain-sdk   — official SDK (PyPI)
  ↓
AuthSec Delegation Backend
  ↓
Short-lived JWT (RS256, scoped, SPIFFE-identified)
  ↓
Protected API (with Authorization: Bearer header)
```

The **official SDK** owns the entire delegation-token lifecycle.
`authsec_helper.py` is a thin, framework-agnostic wrapper that adds MOCK fallback and structured console logging — it never reimplements the token exchange itself.

---

## File Structure

| File | Role |
|------|------|
| `authsec_helper.py` | Thin wrapper around `authsec-langchain-sdk`; MOCK fallback, debug logging |
| `tools.py` | CrewAI `BaseTool` — `AuthSecSecureFetchTool` |
| `main.py` | Entry point; Security Analyst agent demo (live or simulated) |
| `requirements.txt` | Dependencies including `authsec-langchain-sdk` |

---

## Prerequisites

| Requirement | Details |
|-------------|---------|
| Python | 3.10 or later |
| AuthSec account | Registered AI agent client on the [AuthSec dashboard](https://prod.api.authsec.ai) |
| Trust delegation | Created with target type **"Langchain AI agent"** |
| `authsec-langchain-sdk` | `pip install authsec-langchain-sdk` |

---

## Installation & Setup

```bash
cd integrations/crewai
pip install -r requirements.txt
```

`requirements.txt` pulls in `crewai`, `pydantic`, `requests`, `authsec-langchain-sdk`, and supporting packages.

---

## Running the Demo

### MOCK Mode — zero setup

```bash
python main.py
```

No environment variables required. When `AUTHSEC_BASE_URL` and `AUTHSEC_AGENT_CLIENT_ID` are absent, the wrapper falls back to an offline mock mode with demo data. Useful for exploring the integration pattern without an AuthSec account.

### LIVE Mode — against production

```powershell
# Windows PowerShell
$env:AUTHSEC_BASE_URL      = "https://prod.api.authsec.ai"
$env:AUTHSEC_AGENT_CLIENT_ID = "your-agent-client-uuid"
$env:OPENAI_API_KEY        = "sk-..."   # optional — enables real LLM agent

python main.py
```

```bash
# bash / zsh
export AUTHSEC_BASE_URL="https://prod.api.authsec.ai"
export AUTHSEC_AGENT_CLIENT_ID="your-agent-client-uuid"
export OPENAI_API_KEY="sk-..."

python main.py
```

When `OPENAI_API_KEY` is set, `main.py` launches a full CrewAI agent loop. Without it, the demo runs a high-fidelity simulation that still exercises the real AuthSec token flow.

---

## Example Output (LIVE mode, verified against production)

```
[AuthSec SDK] -- Initializing AuthSec Client (CrewAI) ------------
[AuthSec SDK] [Mode] LIVE — using official authsec-langchain-sdk
  |- Base URL  : https://prod.api.authsec.ai
  |- Client ID : fe6d5a81-58ac-4c4b-85fa-f84b6c9cb73d
[AuthSec SDK] [Init] Official authsec-langchain-sdk client initialized.
[AuthSec SDK] [Delegation] Requesting delegation token via official authsec-langchain-sdk...
  |- Endpoint  : GET https://prod.api.authsec.ai/authsec/uflow/sdk/delegation-token
  |- Client ID : fe6d5a81-58ac-4c4b-85fa-f84b6c9cb73d
[AuthSec SDK] [Success] LIVE delegation token acquired via official SDK.
  |- Token  : eyJhbGciOiJSUzI1NiIsInR5...
  |- Cache  : SDK caches token internally (auto-refreshes on expiry).
```

---

## How the Integration Works

1. **Tool construction** — `AuthSecSecureFetchTool` (in `tools.py`) instantiates an `AuthSecClient` from `authsec_helper.py` when the tool is created.

2. **SDK initialization** — `AuthSecClient.__init__` reads `AUTHSEC_BASE_URL` and `AUTHSEC_AGENT_CLIENT_ID`, then calls `AuthsecClient(AuthsecConfig(...))` from the official `authsec-langchain-sdk`.

3. **CrewAI agent invocation** — the agent's planner decides to call the tool. CrewAI routes the call to `AuthSecSecureFetchTool._run()`.

4. **Delegation token retrieval** — `_run()` calls `client.get_delegation_token()`, which delegates to:
   ```
   GET /authsec/uflow/sdk/delegation-token?client_id=<uuid>
   ```
   The SDK handles the exact request contract required by the AuthSec backend (Trust Delegation target type: **"Langchain AI agent"**).

5. **Token caching** — the SDK caches the token internally and refreshes it automatically on expiry. No manual TTL management.

6. **Downstream API call** — the JWT is passed as `Authorization: Bearer <token>` to the protected endpoint via `client.request_secure_api()`.

7. **Result returned to agent** — the JSON response is serialized and returned to the CrewAI agent, which uses it to complete its task.

---

## Environment Variables Reference

| Variable | Required | Description |
|----------|----------|-------------|
| `AUTHSEC_BASE_URL` | Yes (LIVE) | AuthSec server root, e.g. `https://prod.api.authsec.ai` |
| `AUTHSEC_AGENT_CLIENT_ID` | Yes (LIVE) | Agent's client UUID from the AuthSec dashboard |
| `OPENAI_API_KEY` | Optional | Enables a real LLM-powered CrewAI agent; simulation runs without it |

---

## Security Model

AuthSec replaces static, long-lived API keys with **short-lived delegation tokens**. Each token is a signed RS256 JWT scoped to the specific permissions granted through the trust delegation. Tokens expire automatically — the SDK refreshes them transparently — so there is no secret to rotate or leak into version control.

Every delegation token carries a **SPIFFE identity** (`spiffe://authsec.dev/ns/default/sa/ai-agent`) that cryptographically binds the token to a specific agent workload. Downstream APIs verify both the JWT signature and the SPIFFE subject, establishing a chain of trust from the AuthSec backend through the SDK to the protected resource.

This model means the AI agent never handles raw credentials for the target API. The AuthSec backend acts as a trust broker: it evaluates the delegation policy, mints a scoped token, and the agent simply presents that token. Revoking access is a single dashboard action — no credential rotation required.

---

## Debug Logging

The wrapper emits structured, colour-coded console output under the `[AuthSec SDK]` prefix:

| Prefix | Meaning |
|--------|---------|
| `[Mode] LIVE` | SDK initialized, env vars detected |
| `[Mode] MOCK` | No env vars — running offline |
| `[Init]` | SDK client construction result |
| `[Delegation]` | Token request in progress |
| `[Success]` | Token acquired or API call succeeded |
| `[Error]` | SDK call failed — fallback triggered |
| `[Token] … [MOCK FALLBACK]` | Using locally generated mock JWT |

---

## Troubleshooting

| Symptom | Cause | Fix |
|---------|-------|-----|
| `404 Client not found` | `client_id` not registered, or trust delegation not created | Verify the UUID on the AuthSec dashboard; ensure a trust delegation exists with target type **"Langchain AI agent"** |
| `ImportError: authsec_langchain` | SDK not installed | `pip install authsec-langchain-sdk` |
| SSL / connection errors | Wrong URL scheme or unreachable host | Confirm `AUTHSEC_BASE_URL` uses `https://` for production |
| `400 Invalid client_id format` | Trailing whitespace or characters in UUID | Check for copy-paste artefacts in the env var |

---

## A Note on `secure-vault/…` Endpoints

> **The `secure-vault/metrics`, `secure-vault/records`, etc. endpoints used in this demo are illustrative mock resources.** They are intentionally **not** hosted on `prod.api.authsec.ai`. The delegation token flow succeeds against production — you will see a valid JWT returned — but the subsequent call to `secure-vault/*` will return a 404. **This is expected behaviour, not a bug.** In a real deployment you would replace these paths with your own protected API endpoints.

---

## Further Reading

- [AuthSec LangChain SDK docs](https://docs.authsec.dev/sdk/langchain)
- [Blog — Securing AI Agent API Calls with AuthSec + LangChain](https://authsec.ai/blogs/securing-ai-agent-api-calls-authsec-langchain)
- [Root integration README](../README.md)
