# curadise-agent

Async monitoring agent for Curadise - collects system metrics, sends heartbeats, and executes remote commands with security-first design.

## Features

- **Async-first architecture** - Built on `anyio` for high-performance concurrent operations
- **System metrics collection** - CPU, memory, disk, network via `psutil`
- **HTTP health checks** - Monitor endpoints with customizable checks
- **Buffered transport** - In-memory buffer with optional persistence for reliability
- **Heartbeat service** - Regular health reporting with automatic reconnection
- **Remote command execution** - Secure sandboxed execution with allowlist/denylist
- **mTLS support** - Mutual TLS authentication for secure communication
- **JWT authentication** - Token-based auth with automatic refresh
- **Hot-reload configuration** - Watch config files for changes without restart
- **Structured logging** - JSON logging via `structlog` for easy parsing

## Requirements

- Python 3.12+
- Linux or macOS

## Installation

```bash
# Using pip
pip install curadise-agent

# Using uv (recommended)
uv pip install curadise-agent

# From source
git clone https://github.com/pysingh09/curadise-agent.git
cd curadise-agent
uv pip install -e .
```

## Quick Start

1. Create a configuration file:

```bash
cp examples/agent.yaml /etc/curadise/agent.yaml
```

2. Set your enrollment token:

```bash
export CURADISE_ENROLLMENT_TOKEN="your-token-here"
```

3. Run the agent:

```bash
curadise-agent run --config /etc/curadise/agent.yaml
```

## CLI Commands

```bash
# Run the agent
curadise-agent run --config agent.yaml

# Check agent version
curadise-agent version

# Validate configuration
curadise-agent config validate --config agent.yaml

# Show effective configuration
curadise-agent config show --config agent.yaml
```

## Configuration

The agent is configured via YAML files with Jinja2 templating support for environment variables.

### Minimal Configuration

```yaml
server:
  url: "https://curadise.example.com"

auth:
  enrollment_token: "{{ env('CURADISE_ENROLLMENT_TOKEN') }}"
```

### Key Configuration Sections

| Section | Description |
|---------|-------------|
| `server` | Server URL, timeout, SSL settings |
| `auth` | Enrollment token, mTLS certificates |
| `buffer` | Memory buffer size, persistence, batching |
| `retry` | Retry attempts, backoff, circuit breaker |
| `heartbeat` | Heartbeat interval and health metrics |
| `collectors` | System metrics and HTTP check configuration |
| `executor` | Command execution settings and allowlist |
| `logging` | Log level, format, and file rotation |
| `state` | Persistent state directory |
| `tags` | Custom tags for metrics and heartbeats |

See `examples/agent.yaml` for a complete configuration reference.

### Environment Variables

Configuration values can reference environment variables:

```yaml
auth:
  enrollment_token: "{{ env('CURADISE_ENROLLMENT_TOKEN') }}"

http_checks:
  - url: "https://api.example.com/health"
    headers:
      Authorization: "Bearer {{ env('API_TOKEN') }}"
```

## Architecture

```
curadise-agent/
├── src/curadise_agent/
│   ├── auth/          # JWT tokens, mTLS, registration
│   ├── collectors/    # Metrics collectors (system, HTTP)
│   ├── config/        # Configuration loading, schema, watcher
│   ├── executor/      # Command execution with sandbox
│   ├── heartbeat/     # Heartbeat service and health checks
│   ├── models/        # Pydantic models (domain, API)
│   ├── state/         # Persistent state management
│   ├── transport/     # HTTP client, buffering, batching
│   └── utils/         # Logging, retry, shutdown handling
└── tests/
    ├── unit/          # Unit tests
    └── integration/   # Integration tests
```

## Development

### Setup

```bash
# Clone the repository
git clone https://github.com/pysingh09/curadise-agent.git
cd curadise-agent

# Create virtual environment
uv venv
source .venv/bin/activate

# Install with dev dependencies
uv pip install -e ".[dev]"

# Install pre-commit hooks
pre-commit install
```

### Running Tests

```bash
# Run all tests
pytest

# Run with coverage
pytest --cov=curadise_agent --cov-report=html

# Run only unit tests
pytest tests/unit/

# Run integration tests
pytest tests/integration/ -m integration
```

### Code Quality

```bash
# Linting
ruff check src/ tests/

# Type checking
mypy src/

# Format code
ruff format src/ tests/
```

## Security

The agent implements several security measures:

- **Command allowlist/denylist** - Control which commands can be executed
- **Signature verification** - Optionally require server signatures on commands
- **Sandboxed execution** - Commands run in isolated subprocesses
- **mTLS support** - Mutual TLS for server authentication
- **JWT with refresh** - Short-lived tokens with automatic refresh
- **No secrets in config** - Use environment variables for sensitive data

## License

MIT License - see LICENSE file for details.
