mirror of
https://github.com/mblanke/ThreatHunt.git
synced 2026-03-01 05:50:21 -05:00
12 KiB
12 KiB
Architecture Documentation
This document describes the architecture and design decisions for VelociCompanion.
System Overview
VelociCompanion is a multi-tenant, cloud-native threat hunting companion designed to work with Velociraptor. It provides secure authentication, data isolation, and role-based access control.
┌─────────────┐ ┌─────────────┐ ┌──────────────┐
│ │ │ │ │ │
│ Frontend │────▶│ Backend │────▶│ PostgreSQL │
│ (React) │ │ (FastAPI) │ │ Database │
│ │ │ │ │ │
└─────────────┘ └─────────────┘ └──────────────┘
│
▼
┌─────────────┐
│ │
│ Velociraptor│
│ Servers │
│ │
└─────────────┘
Technology Stack
Backend
- FastAPI: Modern, fast web framework for building APIs
- SQLAlchemy: SQL toolkit and ORM
- PostgreSQL: Relational database
- Alembic: Database migration tool
- Python-Jose: JWT token handling
- Passlib: Password hashing with bcrypt
Frontend
- React: UI library
- TypeScript: Type-safe JavaScript
- Axios: HTTP client
- React Router: Client-side routing
Infrastructure
- Docker: Containerization
- Docker Compose: Multi-container orchestration
Core Components
1. Authentication System
JWT Token Flow
1. User submits credentials (username/password)
2. Backend verifies credentials
3. Backend generates JWT token with:
- user_id (sub)
- tenant_id
- role
- expiration time
4. Frontend stores token in localStorage
5. All subsequent requests include token in Authorization header
6. Backend validates token and extracts user context
Password Security
- Passwords are hashed using bcrypt with automatic salt generation
- Password hashes are never exposed in API responses
- Plaintext passwords are never logged or stored
Token Security
- Tokens expire after 30 minutes (configurable)
- Tokens are signed with HS256 algorithm
- Secret key must be at least 32 characters
2. Multi-Tenancy
Data Isolation
Every database query is automatically scoped to the user's tenant:
# Example: Listing hosts
hosts = db.query(Host).filter(Host.tenant_id == current_user.tenant_id).all()
Tenant Creation
- Default tenant is created automatically on first user registration
- Admin users can create additional tenants
- Users are assigned to exactly one tenant
Cross-Tenant Access
- Regular users: Can only access data in their tenant
- Admin users: Can access all data in their tenant
- Super-admin (future): Could access multiple tenants
3. Role-Based Access Control (RBAC)
Roles
- user: Standard user with read/write access to their tenant's data
- admin: Elevated privileges within their tenant
- Can manage users in their tenant
- Can create/modify/delete resources
- Can view all data in their tenant
Permission Enforcement
# Endpoint requiring admin role
@router.get("/users")
async def list_users(
current_user: User = Depends(require_role(["admin"]))
):
# Only admins can access this
pass
4. Database Schema
Core Tables
tenants
- id (PK)
- name (unique)
- description
- created_at
users
- id (PK)
- username (unique)
- password_hash
- role
- tenant_id (FK → tenants)
- is_active
- created_at
hosts
- id (PK)
- hostname
- ip_address
- os
- tenant_id (FK → tenants)
- host_metadata (JSON)
- created_at
- last_seen
cases
- id (PK)
- title
- description
- status (open, closed, investigating)
- severity (low, medium, high, critical)
- tenant_id (FK → tenants)
- created_at
- updated_at
artifacts
- id (PK)
- artifact_type (hash, ip, domain, email, etc.)
- value
- description
- case_id (FK → cases)
- artifact_metadata (JSON)
- created_at
Relationships
tenants (1) ──< (N) users
tenants (1) ──< (N) hosts
tenants (1) ──< (N) cases
cases (1) ──< (N) artifacts
5. API Design
RESTful Principles
- Resources are nouns (users, hosts, cases)
- HTTP methods represent actions (GET, POST, PUT, DELETE)
- Proper status codes (200, 201, 401, 403, 404)
Authentication
All endpoints except /auth/register and /auth/login require authentication.
Authorization: Bearer <jwt_token>
Response Format
Success:
{
"id": 1,
"username": "john",
"role": "user",
"tenant_id": 1
}
Error:
{
"detail": "User not found"
}
6. Frontend Architecture
Component Structure
src/
├── components/ # Reusable UI components
│ └── PrivateRoute.tsx
├── context/ # React Context providers
│ └── AuthContext.tsx
├── pages/ # Page components
│ ├── Login.tsx
│ └── Dashboard.tsx
├── utils/ # Utilities
│ └── api.ts # API client
├── App.tsx # Main app component
└── index.tsx # Entry point
State Management
- AuthContext: Global authentication state
- Current user
- Login/logout functions
- Loading state
- Authentication status
Routing
/login → Login page (public)
/ → Dashboard (protected)
/* → Redirect to / (protected)
7. Security Architecture
Authentication Flow
- Frontend sends credentials to
/api/auth/login - Backend validates and returns JWT token
- Frontend stores token in localStorage
- Token included in all API requests
- Backend validates token on each request
Authorization Flow
- Extract JWT from Authorization header
- Verify token signature and expiration
- Extract user_id from token payload
- Load user from database
- Check user's role for endpoint access
- Apply tenant scoping to queries
Security Headers
# CORS configuration
allow_origins=["http://localhost:3000"]
allow_credentials=True
allow_methods=["*"]
allow_headers=["*"]
Data Flow Examples
User Registration
1. POST /api/auth/register
{username: "john", password: "pass123"}
2. Backend hashes password
3. Create default tenant if needed
4. Create user record
5. Return user object (without password_hash)
Host Ingestion
1. Velociraptor sends data to POST /api/ingestion/ingest
- Must include valid JWT token
2. Extract tenant_id from current user
3. Find or create host with hostname
4. Update host metadata
5. Return success response
Listing Resources
1. GET /api/hosts with Authorization header
2. Validate JWT token
3. Extract tenant_id from user
4. Query: SELECT * FROM hosts WHERE tenant_id = ?
5. Return filtered results
Deployment Architecture
Development
┌──────────────────────────────────────┐
│ Docker Compose │
├──────────────────────────────────────┤
│ Frontend:3000 Backend:8000 DB:5432│
└──────────────────────────────────────┘
Production (Recommended)
┌─────────────┐ ┌─────────────┐
│ Nginx/ │ │ Frontend │
│ Traefik │────▶│ (Static) │
│ (HTTPS) │ └─────────────┘
└──────┬──────┘
│
▼
┌─────────────┐ ┌──────────────┐
│ Backend │ │ PostgreSQL │
│ (Multiple │────▶│ (Managed) │
│ instances) │ └──────────────┘
└─────────────┘
Performance Considerations
Database Indexing
- Primary keys on all tables
- Unique index on usernames
- Index on tenant_id columns for fast filtering
- Index on hostname for host lookups
Query Optimization
- Always filter by tenant_id early in queries
- Use pagination for large result sets (skip/limit)
- Lazy load relationships when not needed
Caching (Future)
- Cache tenant information
- Cache user profiles
- Cache frequently accessed hosts
Monitoring & Logging
Health Checks
GET /health → {"status": "healthy"}
Logging
- Request logging via Uvicorn
- Error tracking in application logs
- Database query logging (development only)
Metrics (Future)
- Request count per endpoint
- Authentication success/failure rate
- Database query performance
- Active user count
Migration Strategy
Database Migrations
# Create migration
alembic revision --autogenerate -m "Description"
# Apply migration
alembic upgrade head
# Rollback
alembic downgrade -1
Schema Evolution
- Create migration for schema changes
- Test migration in development
- Apply to staging environment
- Verify data integrity
- Apply to production during maintenance window
Testing Strategy
Unit Tests (Future)
- Test individual functions
- Mock database connections
- Test password hashing
- Test JWT token creation/verification
Integration Tests (Future)
- Test API endpoints
- Test authentication flow
- Test multi-tenancy isolation
- Test RBAC enforcement
Manual Testing
- Use test_api.sh script
- Use FastAPI's /docs interface
- Test frontend authentication flow
Future Enhancements
Phase 2
- Refresh tokens for longer sessions
- Password reset functionality
- Email verification
- Two-factor authentication (2FA)
Phase 3
- Audit logging
- Advanced search and filtering
- Real-time notifications
- Velociraptor direct integration
Phase 4
- Machine learning for threat detection
- Automated playbooks
- Integration with SIEM systems
- Advanced reporting and analytics
Troubleshooting Guide
Common Issues
Token Expired
- Tokens expire after 30 minutes
- User must login again
- Consider implementing refresh tokens
Permission Denied
- User lacks required role
- Check user's role in database
- Verify endpoint requires correct role
Data Not Visible
- Check tenant_id of user
- Verify data belongs to correct tenant
- Ensure tenant_id is being applied to queries
Database Connection Failed
- Check DATABASE_URL environment variable
- Verify PostgreSQL is running
- Check network connectivity
Development Guidelines
Adding New Endpoints
- Create route in
app/api/routes/ - Add authentication dependency
- Apply tenant scoping to queries
- Add role check if needed
- Create Pydantic schemas
- Update router registration in main.py
- Test with /docs interface
Adding New Models
- Create model in
app/models/ - Add tenant_id foreign key
- Create migration
- Create Pydantic schemas
- Create CRUD routes
- Apply tenant scoping
Code Style
- Follow PEP 8 for Python
- Use type hints
- Write docstrings for functions
- Keep functions small and focused
- Use meaningful variable names