Metadata-Version: 2.4
Name: kairosai-identity
Version: 0.1.0
Summary: Official Python SDK for the KairosAI Identity platform
Home-page: https://identity.kairosaistudio.com
Author: KairosAI
Author-email: KairosAI <hello@kairosaistudio.com>
License: MIT
Project-URL: Homepage, https://identity.kairosaistudio.com
Project-URL: Documentation, https://identity.kairosaistudio.com/docs
Project-URL: Repository, https://github.com/xkaali/kairos-identity-sdk-python
Keywords: ai,agent,identity,did,jwt,kairosai,verification
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.24.0
Dynamic: author
Dynamic: home-page
Dynamic: requires-python

# kairosai-identity

Official Python SDK for the [KairosAI Identity](https://identity.kairosaistudio.com) platform — AI agent identity, permissioning, and tamper-evident audit.

## Installation

```bash
pip install kairosai-identity
```

## Quick start

```python
from kairosai_identity import KairosIdentity

kairos = KairosIdentity(api_key="ki_your_api_key_here")
```

Get your API key from the [KairosAI Identity dashboard](https://identity.kairosaistudio.com/api-keys).

---

## Usage

### Register an agent

```python
agent = kairos.agents.register(
    name="My Email Agent",
    description="Reads and summarizes emails",
    capabilities=["read:email", "browse:web"],
    signing_key_pub="""-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
-----END PUBLIC KEY-----""",
)

print(agent.did)   # did:kairos:abc123xyz
print(agent.token) # eyJhbGc... — save this in your env vars!
```

> **Important:** Store `agent.token` in your agent's environment variables (e.g. `AGENT_TOKEN`). It won't be shown again.

---

### Verify an agent

```python
result = kairos.verify(
    token=agent_jwt,               # from os.environ["AGENT_TOKEN"]
    target_resource="email-service",
    scopes_requested=["read:email"],
)

if not result.allowed:
    print(result.decision)  # 'DENIED' | 'REVOKED' | 'EXPIRED'
    print(result.reason)    # 'Agent lacks required scopes: read:email'
    raise PermissionError("Agent not authorized")

print(result.agent.did)           # did:kairos:abc123xyz
print(result.agent.active_scopes) # ['read:email', 'browse:web']
```

#### verify_or_raise — one-liner gate

```python
# Raises KairosVerificationError if not allowed
agent = kairos.verify_or_raise(
    token=agent_jwt,
    scopes_requested=["read:email"],
)

# Safe to proceed — agent is verified
print(agent.active_scopes)
```

---

### Revoke an agent

```python
kairos.agents.revoke(
    "did:kairos:abc123xyz",
    reason="compromised",
    notes="Private key was exposed in a log file",
)

# All future verify() calls for this agent return allowed=False
```

---

### Manage scopes

```python
# Grant new scopes
kairos.agents.update_scopes(
    "did:kairos:abc123xyz",
    grant=[
        {"scope": "write:calendar"},
        {"scope": "read:files", "expires_at": "2025-12-31T00:00:00Z"},
    ],
)

# Revoke specific scopes
kairos.agents.update_scopes(
    "did:kairos:abc123xyz",
    revoke=["browse:web"],
)
```

---

### Fetch audit log

```python
log = kairos.agents.audit_log(
    "did:kairos:abc123xyz",
    decision="DENIED",
    limit=50,
)

print(log.pagination.total)  # Total matching events
for entry in log.entries:
    print(entry.event_type)  # 'AGENT_DENIED'
    print(entry.reason)      # 'Agent lacks required scopes'
    print(entry.entry_hash)  # SHA-256 hash chain entry
```

---

### Batch verify

```python
results = kairos.batch_verify([
    {"token": jwt1, "scopes_requested": ["read:email"]},
    {"token": jwt2, "scopes_requested": ["browse:web"]},
])

print(results.summary.allowed)  # 1
print(results.summary.denied)   # 1

for result in results.results:
    print(result.allowed, result.decision)
```

---

## Async usage

Full async support via `AsyncKairosIdentity` — uses `httpx.AsyncClient` under the hood.

```python
import asyncio
from kairosai_identity import AsyncKairosIdentity

async def main():
    async with AsyncKairosIdentity(api_key="ki_...") as kairos:
        result = await kairos.verify(token=agent_jwt)
        if not result.allowed:
            raise PermissionError("Agent not authorized")

        agent = result.agent
        print(agent.did)

asyncio.run(main())
```

### FastAPI integration

```python
from fastapi import FastAPI, Header, HTTPException, Depends
from kairosai_identity import AsyncKairosIdentity, KairosVerificationError
import os

app = FastAPI()
kairos = AsyncKairosIdentity(api_key=os.environ["KAIROS_API_KEY"])

async def require_agent(x_agent_token: str = Header(...)):
    try:
        return await kairos.verify_or_raise(
            token=x_agent_token,
            scopes_requested=["read:data"],
        )
    except KairosVerificationError as e:
        raise HTTPException(status_code=403, detail=str(e))

@app.get("/api/data")
async def get_data(agent=Depends(require_agent)):
    return {"data": "...", "verified_agent": agent.did}
```

---

## Error handling

```python
from kairosai_identity import (
    KairosIdentity,
    KairosError,
    KairosAuthError,
    KairosNotFoundError,
    KairosVerificationError,
    KairosTimeoutError,
)

try:
    result = kairos.verify(token=agent_jwt)
except KairosAuthError:
    print("Invalid API key")
except KairosTimeoutError:
    print("Request timed out")
except KairosError as e:
    print(f"Error {e.code} ({e.status}): {e}")
```

---

## Configuration

```python
kairos = KairosIdentity(
    api_key="ki_...",

    # Point to your own instance (default: https://identity.kairosaistudio.com)
    base_url="https://identity.yourdomain.com",

    # Request timeout in seconds (default: 10.0)
    timeout=5.0,
)
```

---

## Requirements

- Python 3.9+
- `httpx` >= 0.24.0

---

## License

MIT © KairosAI
