Metadata-Version: 2.4
Name: sentinel-lab
Version: 0.0.1
Summary: Local-first runtime observability for AI agent security experiments.
Author: Sentinel Lab Contributors
License-Expression: MIT
Keywords: ai,agents,security,observability,runtime
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# Sentinel Lab

Sentinel Lab is a local-first runtime observability wrapper for AI-agent security experiments. The deployed dashboard at [attack-log.vercel.app](https://attack-log.vercel.app/) is the visualization layer; the PyPI package runs the local monitor, SQLite database, API, event stream, graph reconstruction, and deterministic evidence-backed diagnosis.

## Install

For local development:

```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
```

After publication:

```bash
python -m pip install sentinel-lab
```

Sentinel Lab supports Python 3.10 and newer and has no runtime dependencies.

## Three-command workflow

Start a monitor session:

```bash
sentinel-lab start \
  --agent "Research Agent" \
  --attack prompt_injection \
  --defense tool_permission_boundary
```

Run your instrumented experiment, then finalize it:

```bash
sentinel-lab stop
```

Open the latest investigation:

```bash
sentinel-lab dashboard
```

The local daemon remains available between experiments. Session data is stored by default in `~/.sentinel-lab/sentinel-lab.sqlite3`.

## Wrap a command

To capture process boundaries, stdout/stderr, structured events, finalize automatically, and open the dashboard when the experiment exits:

```bash
sentinel-lab start \
  --agent "Demo Agent" \
  --attack prompt_injection \
  --defense egress_guard \
  -- python demo_agent.py
```

Plain output becomes `COMMAND_OUTPUT`. A JSON object printed on one line is ingested as a structured event when it contains `type` or `event_type`.

## Instrument a Python agent

After `sentinel-lab start`, the client automatically discovers the active local session:

```python
from sentinel_lab import SentinelLab, SentinelLabClient

observed_agent = SentinelLab.wrap(existing_agent)
result = observed_agent.run("Summarize the supplied page")

log = SentinelLabClient()
log.external_content({
    "origin": "https://research.local/notes",
    "content_excerpt": "Untrusted page content",
})

with log.tool_call("browser.open", payload={"arguments": {"url": "https://example.test"}}):
    result = browser.open("https://example.test")
```

The original `attack-log` CLI and `attack_log` imports remain as compatibility aliases.

Use the explicit environment variables printed by `sentinel-lab start` when an experiment runs in a separate environment or needs a non-default API:

```bash
export ATTACK_LOG_API_URL=http://127.0.0.1:43117
export ATTACK_LOG_SESSION_ID=SESSION-0001
```

## Supporting commands

```bash
sentinel-lab status
sentinel-lab sessions
sentinel-lab inspect SESSION-0001
sentinel-lab inspect SESSION-0001 --json
sentinel-lab version
```

## Local API

The default API is `http://127.0.0.1:43117` and includes:

```text
GET  /api/health
GET  /api/status
GET  /api/sessions
GET  /api/sessions/latest
GET  /api/sessions/{id}
GET  /api/sessions/{id}/events
GET  /api/sessions/{id}/workflow
GET  /api/sessions/{id}/diagnosis
GET  /api/sessions/{id}/evidence
GET  /api/sessions/{id}/investigation
GET  /api/sessions/{id}/stream
GET  /api/events/{id}
POST /api/control/start
POST /api/control/stop
POST /api/sessions/{id}/events
```

SSE sends named `event` and `session` messages. Events are persisted before publication, and connecting clients receive a replay before live messages.

The default allowed browser origin is only `https://attack-log.vercel.app`. Override configuration when required:

```bash
export SENTINEL_LAB_PORT=43117
export SENTINEL_LAB_HOME="$PWD/.sentinel-lab-data"
export SENTINEL_LAB_DASHBOARD_ORIGIN=https://attack-log.vercel.app
export SENTINEL_LAB_DASHBOARD_URL=https://attack-log.vercel.app
```

Legacy `ATTACK_LOG_*` configuration variables remain supported.

## Frontend integration

The deployed UI currently contains mock query functions. [docs/frontend-api-client.ts](docs/frontend-api-client.ts) is a drop-in browser client matching its existing session, event, diagnosis, evidence, graph, and live-monitor shapes. Replace the mock loaders with `attackLogApi.sessions()` and `attackLogApi.investigation(id)`, and subscribe with `subscribeToSession(id, handler)`.

The dashboard must perform these calls in browser code, not during Vercel server rendering, because `127.0.0.1` means the Vercel server when requested from SSR. The local API implements restrictive CORS and Private Network Access preflight support. Some browser policies may still require an approved local HTTPS proxy.

## Publish to PyPI

Run this one command from the repository root:

```bash
./scripts/publish-pypi.sh
```

Enter a PyPI API token when prompted. The first successful upload creates the `sentinel-lab` project on PyPI and publishes version `0.0.1`. See [PUBLISHING.md](PUBLISHING.md) for account and token prerequisites.

## Development

```bash
PYTHONPATH=src python -m unittest discover -s tests -v
python -m pip wheel . --no-deps --wheel-dir dist
```

See [ARCHITECTURE.md](ARCHITECTURE.md) for the system design.
