# Local Development

Complete setup guide for running AgentIdP locally.

## Prerequisites

| Tool | Minimum version | Purpose |
|------|----------------|---------|
| Docker | 24+ | Container runtime |
| Docker Compose | 2.20+ | Multi-container orchestration |
| Node.js | 18.0.0 | Run the application, portal, and migrations |
| npm | 9+ | Package management and scripts |
| nvm | any | Recommended for managing Node.js versions |
| openssl | any | RSA key generation |

Verify versions:

```bash
docker --version
docker-compose --version
node --version
npm --version
```

> **nvm activation:** If using nvm, activate it before running any Node.js commands:
> ```bash
> export NVM_DIR="$HOME/.nvm" && source "$NVM_DIR/nvm.sh"
> ```

---

## Step 1 — Clone and install dependencies

```bash
git clone https://git.sentryagent.ai/vijay_admin/sentryagent-idp.git
cd sentryagent-idp
npm install

# Install portal dependencies
cd portal && npm install && cd ..
```

---

## Step 2 — Generate JWT keys

AgentIdP signs tokens with RS256. You need an RSA-2048 keypair.

```bash
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
```

Keep these files in the project root. They are used only locally and should not be committed.

---

## Step 3 — Configure environment

Create a `.env` file in the project root:

```bash
cat > .env << 'ENVEOF'
DATABASE_URL=postgresql://sentryagent:sentryagent@localhost:5432/sentryagent_idp
REDIS_URL=redis://localhost:6379
PORT=3000
NODE_ENV=development
CORS_ORIGIN=*
ENVEOF
```

Append the JWT keys to `.env`:

```bash
echo "JWT_PRIVATE_KEY=\"$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' private.pem)\"" >> .env
echo "JWT_PUBLIC_KEY=\"$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' public.pem)\"" >> .env
```

Verify the file has all required variables:

```bash
grep -E "^(DATABASE_URL|REDIS_URL|JWT_PRIVATE_KEY|JWT_PUBLIC_KEY)" .env
```

---

## Step 4 — Start infrastructure services

The `docker-compose.yml` defines three services: `postgres`, `redis`, and `app`. For local development, start only the infrastructure services — the application runs directly via Node.js.

```bash
docker-compose up -d postgres redis
```

Expected output:

```
[+] Running 2/2
 ✔ Container sentryagent-idp-postgres-1  Healthy
 ✔ Container sentryagent-idp-redis-1     Healthy
```

Both services must show `Healthy` before proceeding. If they show `Starting`, wait a few seconds and run `docker-compose ps` to recheck.

### Service ports

| Service | Port | Health check |
|---------|------|-------------|
| PostgreSQL | 5432 | `pg_isready -U sentryagent -d sentryagent_idp` |
| Redis | 6379 | `redis-cli ping` → `PONG` |

Verify manually:

```bash
docker-compose exec postgres pg_isready -U sentryagent -d sentryagent_idp
docker-compose exec redis redis-cli ping
```

### Docker volumes

Data is persisted in named Docker volumes:

| Volume | Service | Contents |
|--------|---------|---------|
| `sentryagent-idp_postgres_data` | PostgreSQL | All database data |
| `sentryagent-idp_redis_data` | Redis | Redis persistence (if enabled) |

---

## Step 5 — Run database migrations

```bash
npm run db:migrate
```

Expected output:

```
Running database migrations...
  ✓ Applied: 001_create_agents.sql
  ...
  ✓ Applied: 026_add_tenant_tiers.sql

Migrations complete. 26 migration(s) applied.
```

See [database.md](database.md) for full migration documentation.

---

## Step 6 — Start the application

### Development mode (TypeScript source, no compile step)

```bash
npm run dev
```

Expected startup output:

```
SentryAgent.ai AgentIdP listening on port 3000
```

The application connects to PostgreSQL and Redis on first request (lazy initialisation). If either service is unreachable, the first request will fail with a connection error — not startup.

### Production mode (compiled JavaScript)

```bash
npm run build
npm start
```

The compiled output is written to `dist/`. `npm start` runs `node dist/server.js`.

---

## Step 7 — Start the Next.js portal (optional)

The portal is a Next.js 14 application in the `portal/` directory. It communicates with the
AgentIdP backend at `http://localhost:3000`.

Start the portal development server:

```bash
cd portal && npm run dev
```

The portal starts on port 3001 by default. Open http://localhost:3001.

Available routes:

| Route | Description |
|-------|-------------|
| `/login` | OAuth 2.0 login page |
| `/agents` | Agent registry |
| `/credentials` | Credential management |
| `/audit` | Audit log viewer |
| `/analytics` | Token trend and agent activity charts |
| `/settings/tier` | Tier status and upgrade |
| `/compliance` | AGNTCY compliance report |
| `/webhooks` | Webhook subscription management |
| `/marketplace` | Agent marketplace |

Build the portal for production:

```bash
cd portal && npm run build
cd portal && npm start  # serves the production build
```

Ensure `CORS_ORIGIN` in your `.env` includes `http://localhost:3001`:
```
CORS_ORIGIN=http://localhost:3001
```

---

## Full Docker Compose Stack

> The full Docker Compose stack (including the `app` container) is available for field trial
> deployments — see the [field trial guide](field-trial.md). For day-to-day development, start
> only the infrastructure services and run the application directly.

When the Dockerfile is available, the entire stack (infrastructure + application) can be started with:

```bash
docker-compose up -d
```

The `app` service depends on `postgres` and `redis` with health check conditions, so it will not start until both services are healthy.

Environment variables for the container are loaded from `.env` via the `env_file` directive in `docker-compose.yml`.

---

## Stopping Services

Stop infrastructure only (preserves volumes):

```bash
docker-compose stop postgres redis
```

Stop and remove containers (preserves volumes):

```bash
docker-compose down
```

Stop and remove containers AND volumes (destroys all data):

```bash
docker-compose down -v
```

> Use `-v` only when you want a clean slate. This deletes all PostgreSQL data and Redis data permanently.

---

## Running Tests

Unit tests (no infrastructure required):

```bash
npm run test:unit
```

Integration tests (require running PostgreSQL and Redis):

```bash
npm run test:integration
```

All tests:

```bash
npm test
```

Integration tests connect to the same `DATABASE_URL` and `REDIS_URL` from `.env`. Ensure infrastructure is running before executing integration tests.
