File size: 2,095 Bytes
180d1d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b51092e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# Deployment Guide

## Local Development

```bash
uvicorn app.api.main:app --reload --port 8000
python gradio_app/app.py
```

## Docker

```bash
# Build
docker build -t ai-code-review-agent .

# Run
docker run -p 8000:8000 --env-file .env ai-code-review-agent
```

## Kubernetes

```bash
# Apply all manifests
kubectl apply -f kubernetes/

# Check status
kubectl get pods
kubectl get services

# View logs
kubectl logs -l app=ai-code-review-agent
```

## Environment Variables

Copy `.env.example` to `.env` and fill in:
- `OPENROUTER_API_KEY` — get from https://openrouter.ai

## Security model for untrusted code execution

The agent clones and analyses arbitrary public repositories. Any cloned
repo may contain malicious code that tries to escape the analysis sandbox.

### Current protections (all environments)

| Control | Implementation |
|---|---|
| Wall-clock timeout | `subprocess.run(timeout=120)` — SIGKILL after 2 min |
| CPU time cap | `RLIMIT_CPU = 60s` (Linux only) |
| Memory cap | `RLIMIT_AS = 512 MB` (Linux only) |
| Process cap | `RLIMIT_NPROC = 64` (Linux only) |
| File descriptor cap | `RLIMIT_NOFILE = 256` (Linux only) |
| Secret stripping | Subprocess inherits only `PATH`, `HOME=/tmp`, no API keys |
| OOM detection | Exit code 137 is caught and logged |

### What is NOT protected (known gaps)

- **Network access**: the subprocess can make outbound network calls.
  Full isolation requires running analysis inside a disposable Docker
  container with `--network=none`. This is the recommended production
  hardening step.
- **Filesystem writes**: the subprocess can write anywhere it has
  permission within the cloned directory. The clone dir is deleted after
  analysis completes.
- **macOS / Windows**: `RLIMIT_*` calls are Linux-only and are skipped
  on other platforms. Local dev is unaffected but has no memory/CPU cap.

### Recommended production hardening

Run the Celery worker inside a Docker-in-Docker setup where each
`analyze_repository_task` spawns a fresh container with
`--network=none --memory=512m --cpus=1` and discards it after completion.