MAES: The M365 Analyzer & Extractor Suite is an open-source, full-stack SaaS platform for Microsoft 365 forensic data extraction and analysis.
⚠️ This project is heavily under development
Built on the amazing work of:
- Microsoft-Analyzer-Suite - Give them a STAR! ⭐
- Microsoft-Extractor-Suite - Give them a STAR! ⭐
- M365 Data Extraction: Audit logs, Azure AD, Exchange, SharePoint, Teams
- Advanced Analytics: MITRE ATT&CK mapping, behavioral analysis, threat hunting
- Upload & Analyze: Support for pre-extracted log files (JSON, CSV, TXT, LOG)
- Elasticsearch Integration: Full-text search and real-time analytics
- Security & Compliance: Multi-tenant, RBAC, audit logging
- Enterprise-Ready: Docker containerization, microservices architecture
- Real-time Progress: Live analysis progress tracking with WebSocket updates
- Docker Desktop or Docker Engine
- Docker Compose
- 8GB+ RAM recommended
- 20GB+ free disk space
- For production: Custom domain with DNS pointing to your server
git clone https://github.com/ionsec/maes-platform.git
cd maes-platform
docker-compose up -d --build
Access: https://localhost (accept self-signed certificate)
git clone https://github.com/ionsec/maes-platform.git
cd maes-platform
# Set up environment variables
cp .env.example .env
# Edit .env with your domain and secure passwords
# One-command setup with Let's Encrypt SSL
./scripts/setup-domain.sh maes.yourdomain.com [email protected]
Access: https://maes.yourdomain.com
-
Apply database migrations (if needed):
docker exec -i maes-postgres psql -U maes_user -d maes_db < database/migrations/update_user_roles_fixed.sql
-
Access the application:
- Web Interface: https://localhost (dev) or https://yourdomain.com (prod)
- API Documentation: https://localhost/api/docs (proxied via nginx)
- Default Login: [email protected] / admin123
MAES supports flexible SSL configuration:
Mode | Use Case | SSL | Command |
---|---|---|---|
Localhost | Development | Self-signed | docker-compose up -d |
Production | Custom domain | Let's Encrypt | ./scripts/setup-domain.sh domain.com [email protected] |
Staging | Testing | Let's Encrypt Staging | ./scripts/setup-domain.sh domain.com [email protected] --staging |
Copy and customize the environment file:
cp .env.example .env
# Edit .env with your domain and settings
Required environment variables for production:
# Domain Configuration
DOMAIN=yourdomain.com # Your domain (e.g., maes-demo.ionsec.io)
USE_LETS_ENCRYPT=true # Enable Let's Encrypt
[email protected] # Required for Let's Encrypt
# CORS Configuration (automatically configured based on DOMAIN)
# PUBLIC_IP=1.2.3.4 # Alternative: Use public IP instead of domain
# FRONTEND_URL=https://your-frontend-url.com # Alternative: Explicit frontend URL
# CORS_ORIGIN=https://domain1.com,https://domain2.com # Manual override
# Security (CHANGE THESE!)
POSTGRES_PASSWORD=your_secure_postgres_password
REDIS_PASSWORD=your_secure_redis_password
JWT_SECRET=your_jwt_secret_min_32_characters
SERVICE_AUTH_TOKEN=your_service_token
ENCRYPTION_KEY=your-32-character-secret-key-here!
# Database
DATABASE_URL=postgresql://maes_user:your_secure_postgres_password@postgres:5432/maes_db
# Redis
REDIS_URL=redis://:your_secure_redis_password@redis:6379
# API Configuration
NODE_ENV=production
PORT=3000 # Internal port only (not exposed publicly)
API_URL=https://yourdomain.com # Frontend API URL (nginx proxies /api/ internally)
Frontend configuration (frontend/.env):
# Point frontend to your domain (nginx proxies API internally)
VITE_API_URL=https://yourdomain.com
- Register an Organization: Set up Azure AD app registration
- Configure Credentials: Add tenant ID, client ID, and certificate
- Run Extractions: Choose data types (UAL, Azure logs, etc.)
- Monitor Progress: Real-time extraction status
- Connect to Microsoft 365 directly
- Extract and analyze in real-time
- Automatic analysis triggering
- Upload existing log files (JSON, CSV, TXT, LOG)
- Support for various M365 log formats
- No M365 connection required
To upload logs:
- Go to Analysis page
- Click "Upload Logs"
- Select data type (UAL, Azure Sign-in, etc.)
- Choose your log file
- Set optional metadata (date ranges)
- Run analysis on uploaded data
Supported file formats:
- JSON: Native M365 export format
- CSV: Tabular log data
- TXT/LOG: Plain text logs
- Live Progress Tracking: See extraction/analysis progress in real-time
- WebSocket Updates: Instant status updates across the platform
- CORS Support: Works with localhost and custom domains
# Start with development configuration (exposes API port 3000)
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build
# Access API directly at: http://localhost:3000/api/docs
# Access frontend at: https://localhost
Add this to your .env
file:
API_COMMAND=npm run dev
Then restart the API container:
docker compose restart api
Note: In production, port 3000 is not exposed publicly. All API requests go through nginx proxy at /api/
# Build and tag images
docker compose build
docker tag maes-api:latest your-registry/maes-api:latest
docker tag maes-frontend:latest your-registry/maes-frontend:latest
docker tag maes-extractor:latest your-registry/maes-extractor:latest
docker tag maes-analyzer:latest your-registry/maes-analyzer:latest
# Push to registry
docker push your-registry/maes-api:latest
docker push your-registry/maes-frontend:latest
docker push your-registry/maes-extractor:latest
docker push your-registry/maes-analyzer:latest
- Check logs:
docker compose logs <service-name>
- Ensure all environment variables are set correctly
- Verify port availability (80, 443, 5432, 6379, 9200)
- Note: Port 3000 is internal only (not exposed in production)
- Ensure database migrations have been applied
- Check API logs for specific errors
- Verify Azure AD app registration permissions
- Check that analysis jobs are created in database
- Verify analyzer service is processing jobs
- Check WebSocket connection in browser dev tools
- Adjust Elasticsearch memory: Update
ES_JAVA_OPTS
in docker-compose - Monitor resource usage:
docker stats
- Check available disk space for logs and data
- Common error: "Access to XMLHttpRequest blocked by CORS policy"
- Solution: Set
DOMAIN
environment variable to your deployment domain - Example: For deployment on
maes-demo.ionsec.io
:DOMAIN=maes-demo.ionsec.io API_URL=https://maes-demo.ionsec.io
- Frontend: Ensure
VITE_API_URL=https://maes-demo.ionsec.io
(no port 3000) - Alternative: Use
PUBLIC_IP
for IP-based deployments orCORS_ORIGIN
for manual override - Development: Use
docker-compose.dev.yml
to expose port 3000 for direct API access - Check API logs for CORS-related errors:
docker logs maes-api
# Backup PostgreSQL database
docker exec maes-postgres pg_dump -U maes_user maes_db > backup.sql
# Restore database
docker exec -i maes-postgres psql -U maes_user maes_db < backup.sql
# Check all services status
docker compose ps
# View service logs
docker compose logs -f <service-name>
# Monitor resource usage
docker stats
# Clean up old containers and images
docker system prune -f
# Remove volumes (WARNING: This deletes all data)
docker compose down -v
We welcome contributions! Please see our Contributing Guide for details.
This project is licensed under the MIT License - see the LICENSE file for details.
MAES Platform - Microsoft 365 Forensic Analysis Made Simple