docs: update README with new security configuration, install wizard, and hardening details

This commit is contained in:
2026-02-11 09:16:48 +01:00
parent 875d7b1a15
commit 6a327f6b51

View File

@@ -108,14 +108,16 @@ chmod +x scripts/install.sh
./scripts/install.sh
```
The install script will automatically:
- Generate a `.env` file with secure random secrets
- Build and start all containers (PostgreSQL, MinIO, Backend, Frontend)
- Run database migrations
- Seed the admin user and data sources
- Optionally run the initial MITRE ATT&CK sync
The interactive install wizard will guide you through:
1. **Domain configuration** — your domain or IP, protocol (HTTP/HTTPS), and port
2. **Admin account** — custom username and password (or auto-generated secure password)
3. **Database** — name, user, and password (or auto-generated)
4. **Session duration** — JWT token expiry (default: 15 minutes)
5. **MITRE ATT&CK sync** — optionally import ~700 techniques on first run
Access the application at **http://your-server:80**.
The script automatically generates cryptographically secure random secrets for `SECRET_KEY`, database password, and MinIO credentials. A summary with all credentials is displayed at the end of the installation.
Access the application at the URL shown in the installation summary.
### Development Setup
@@ -132,14 +134,18 @@ Access at **http://localhost:5173** (frontend dev server) and **http://localhost
### Authentication
JWT-based authentication. Default admin credentials after seeding:
JWT-based authentication with HttpOnly cookies. Admin credentials are configured during installation:
```
Username: admin
Password: admin123
- If you set a custom password in the wizard, use that.
- If you left it blank, a secure random password was auto-generated and displayed in the installation summary and backend logs.
To retrieve auto-generated credentials after installation:
```bash
docker logs aegis-backend 2>&1 | grep -A 5 "Initial Admin User Created"
```
> **Important:** Change the default `admin123` password immediately after first login.
> **Note:** Passwords must meet complexity requirements: minimum 12 characters with at least one uppercase letter, one lowercase letter, one digit, and one special character.
### Importing Data Sources
@@ -161,10 +167,11 @@ curl -X POST http://your-server/api/v1/data-sources/sync-all -H "Authorization:
### Production Considerations
- **HTTPS/TLS:** For internet-facing deployments, place a reverse proxy with TLS in front (e.g., Traefik, Caddy, or Nginx with Let's Encrypt).
- **HTTPS/TLS:** For internet-facing deployments, place a reverse proxy with TLS in front (e.g., Traefik, Caddy, or Nginx with Let's Encrypt). Uncomment the HSTS header in `frontend/nginx.conf` once HTTPS is configured.
- **Backups:** Set up regular PostgreSQL backups: `docker exec aegis-postgres pg_dump -U postgres attackdb > backup.sql`
- **Updates:** To update, pull the latest code and run: `docker compose -f docker-compose.prod.yml up -d --build`
- **Firewall:** Only expose port 80/443. All other services (DB, MinIO, backend) are internal only.
- **Reconfigure:** Run `./scripts/install.sh` again to reconfigure the environment (domain, credentials, etc.).
### Configuring Scoring Weights
@@ -221,11 +228,13 @@ Or at runtime via the admin API — see [docs/SCORING.md](docs/SCORING.md).
## API Documentation
Interactive API documentation available at:
Interactive API documentation is available **in development only** (disabled in production for security):
- **Swagger UI**: http://localhost:8000/docs
- **ReDoc**: http://localhost:8000/redoc
> In production (`AEGIS_ENV=production`), these endpoints are disabled. Use the development environment or refer to [docs/API.md](docs/API.md).
### API Endpoints
| Group | Prefix | Key Operations |
@@ -256,22 +265,66 @@ See [docs/API.md](docs/API.md) for the full endpoint reference.
## Configuration
All variables are configured automatically by `scripts/install.sh`. For manual setup, copy `.env.example` to `.env` and fill in the values.
### Required (production)
| Variable | Description |
|----------|-------------|
| `SECRET_KEY` | JWT signing key — **required** in production (app refuses to start without it). Generate with `openssl rand -hex 32` |
| `DB_PASSWORD` | PostgreSQL password |
| `MINIO_SECRET_KEY` | MinIO secret key |
### Security & Auth
| Variable | Default | Description |
|----------|---------|-------------|
| `DATABASE_URL` | `postgresql://postgres:postgres@postgres:5432/attackdb` | PostgreSQL connection |
| `SECRET_KEY` | `change-me-in-production` | JWT signing key |
| `ALGORITHM` | `HS256` | JWT signing algorithm |
| `ACCESS_TOKEN_EXPIRE_MINUTES` | `60` | Token lifetime |
| `MINIO_ENDPOINT` | `minio:9000` | MinIO server |
| `AEGIS_ENV` | — | Set to `production` to enforce security settings |
| `ADMIN_USERNAME` | `admin` | Initial admin account username |
| `ADMIN_PASSWORD` | *(auto-generated)* | Initial admin password. If empty, a secure random password is generated and shown in logs |
| `ACCESS_TOKEN_EXPIRE_MINUTES` | `15` | JWT token lifetime in minutes |
| `CORS_ORIGINS` | `http://localhost:5173` | Comma-separated list of allowed frontend origins |
### Infrastructure
| Variable | Default | Description |
|----------|---------|-------------|
| `DB_USER` | `postgres` | PostgreSQL username |
| `DB_NAME` | `attackdb` | PostgreSQL database name |
| `MINIO_ENDPOINT` | `minio:9000` | MinIO server address |
| `MINIO_ACCESS_KEY` | `minioadmin` | MinIO access key |
| `MINIO_SECRET_KEY` | `minioadmin` | MinIO secret key |
| `MINIO_BUCKET` | `evidence` | Evidence bucket |
| `MAX_RETEST_COUNT` | `3` | Max automatic retests per original test |
| `MINIO_BUCKET` | `evidence` | MinIO bucket for evidence files |
| `MINIO_SECURE` | `false` | Set to `true` if MinIO is behind TLS |
| `FRONTEND_PORT` | `80` | Port exposed by the frontend container |
### Scoring Weights
| Variable | Default | Description |
|----------|---------|-------------|
| `SCORING_WEIGHT_TESTS` | `40` | Weight for test validation component |
| `SCORING_WEIGHT_DETECTION_RULES` | `20` | Weight for detection rules component |
| `SCORING_WEIGHT_D3FEND` | `15` | Weight for D3FEND coverage component |
| `SCORING_WEIGHT_FRESHNESS` | `15` | Weight for freshness component |
| `SCORING_WEIGHT_PLATFORM_DIVERSITY` | `10` | Weight for platform diversity component |
| `MAX_RETEST_COUNT` | `3` | Max automatic retests per original test |
## Security
Aegis includes several security hardening measures:
- **Authentication:** JWT tokens stored in HttpOnly/Secure/SameSite cookies (immune to XSS theft). Token revocation via in-memory blacklist on logout.
- **Rate limiting:** Login endpoint limited to 5 attempts per minute per IP (via slowapi).
- **Password policy:** Minimum 12 characters with uppercase, lowercase, digit, and special character.
- **CORS:** Configurable origins via `CORS_ORIGINS` environment variable. Restrictive method and header lists.
- **Nginx security headers:** CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy.
- **Non-root container:** Backend runs as `appuser` (UID 1001), not root.
- **File uploads:** 50 MB size limit, extension whitelist, filename sanitization.
- **ZIP imports:** Zip Slip (path traversal) and Zip Bomb (size/entry limit) protection.
- **API surface:** Swagger UI, ReDoc, and OpenAPI schema disabled in production.
- **Health endpoint:** Restricted to internal networks via Nginx ACL.
- **Input sanitization:** LIKE wildcard escaping in all search queries; Pydantic schemas on all endpoints.
- **XML parsing:** Uses `defusedxml` to prevent Billion Laughs / XXE attacks.
- **Error handling:** Internal exception details are logged server-side only, never exposed to clients.
## Project Structure