An agentic screenshot analyzer that lights up phishing and smishing lures.
Named for the anglerfish's bioluminescent lure — Lurelit illuminates the deceptive glow of phishing attacks, making the invisible threat visible.
- AI-Powered Classification — Claude Opus 4.7 vision analyzes screenshots to classify phishing, smishing, spam, or legitimate messages
- IOC Extraction & Enrichment — Automatically extracts URLs, domains, IPs, and hashes, then enriches via VirusTotal and urlscan.io
- Environment Threat Hunting — ES|QL queries hunt your Elasticsearch data for evidence of extracted IOCs in your org's logs
- Human-in-the-Loop Approval — Configurable approval gates before high-cost threat hunting operations
- Real-Time Progress Tracking — Live workflow timeline with step-by-step progress and elapsed timers
- Bulk Analysis — Submit multiple screenshots in parallel for batch processing
- Slack Notifications — Formatted Block Kit reports delivered to your team's Slack channel
- Cost Tracking — Token usage and estimated costs displayed for each AI operation
- History & Metrics — Full execution history with filtering, stats cards, and trend dashboards
git clone https://github.com/jamesspi/lurelit.git
cd lurelit
npm install
npm run dev
# Open http://localhost:5001
# Admin key shown in terminalgit clone https://github.com/jamesspi/lurelit.git
cd lurelit
docker compose up
# Open http://localhost:5001
# Admin key shown in container logs: docker compose logs lurelitdocker compose up -e KIBANA_URL=https://your-kibana:5601 -e WORKFLOW_ID=your-workflow-id -e CONFIG_SECRET=your-secret
# Goes straight to login, no setup wizard neededBoth methods run on port 5001. On first launch (without env vars), the setup wizard guides you through connecting to Kibana and configuring your workflow.
On first launch, Lurelit has no configuration and will guide you through an interactive setup wizard:
- Admin key displayed in terminal — On first startup, Lurelit generates a one-time admin key and prints it to the server console/Docker logs. Copy it.
- Navigate to
http://localhost:5001/setup— The app redirects here automatically when unconfigured. - Enter the admin key — Paste the key from the terminal to unlock the wizard.
- Enter Kibana URL + credentials — Provide your Kibana instance URL (e.g.,
http://localhost:5601) and a username/password with workflow execution privileges. - Validate connection & prerequisites — The wizard auto-checks: Kibana connectivity, version (9.4+), Workflows API, Agent Builder, and Security solution.
- Review connectors — The wizard scans for required HTTP connectors (Anthropic API, VirusTotal, urlscan.io) and optional ones (Slack). Create any missing connectors directly from the wizard by entering your API keys.
- Select AI models — Choose which inference endpoints to use for enrichment/hunting (primary) and report formatting (secondary) from your available connectors.
- Import or select workflow — If a matching workflow already exists, select it. Otherwise, import the bundled Lurelit workflow with your configured connectors.
- Launch! — Configuration is encrypted and saved. You're redirected to the login page.
- Login with Kibana credentials — Use the same username/password from step 4.
- Start analyzing screenshots — Upload a screenshot of a suspicious message and get an AI-powered verdict.
When environment variables (KIBANA_URL + WORKFLOW_ID) are set, the app goes straight to the login page — no setup wizard needed. See the "With Docker + env vars" command above. This is ideal for:
- Docker deployments with pre-configured environments
- CI/CD pipelines
- Automated provisioning
Open http://localhost:5001 and log in with your Kibana credentials.
| Component | Version | Notes |
|---|---|---|
| Elastic Stack | 9.4+ | Kibana with Security Workflows GA |
| Agent Builder | Accessible from left nav | Elastic AI Agent with capabilities enabled |
| Node.js | 20+ | For local development |
| Anthropic API | Claude Opus 4.7 | Vision-capable model for screenshot analysis |
| VirusTotal API | v3 | IOC enrichment (free tier works, premium recommended) |
| urlscan.io API | v1 | Domain/URL reputation |
Don't have an Elastic cluster yet? Start a free Elastic Cloud trial or use start-local for quick self-managed testing (a trial license is required for Workflows and Agent Builder features).
| Variable | Required | Description |
|---|---|---|
KIBANA_URL |
Yes | Full URL to your Kibana instance (no trailing slash) |
WORKFLOW_ID |
Yes | Auto-generated workflow ID from Kibana (see docs) |
CONFIG_SECRET |
No | Encryption secret for stored config (AES-256-GCM) |
If env vars aren't set, configure via the Settings modal in the navigation bar. Settings are encrypted and persisted to .smish-config.enc.
Lurelit runs on HTTP by default. For production deployments, TLS should be configured via a reverse proxy.
server {
listen 443 ssl;
server_name lurelit.yourdomain.com;
ssl_certificate /etc/ssl/certs/lurelit.crt;
ssl_certificate_key /etc/ssl/private/lurelit.key;
location / {
proxy_pass http://localhost:5001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}lurelit.yourdomain.com {
reverse_proxy localhost:5001
}
Caddy automatically provisions and renews certificates.
# docker-compose.yml with Caddy
services:
lurelit:
build: .
ports:
- "5001:5001"
environment:
- KIBANA_URL=https://your-kibana:5601
- WORKFLOW_ID=your-workflow-id
caddy:
image: caddy:alpine
ports:
- "443:443"
- "80:80"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
depends_on:
- lurelit- When running behind a proxy, session cookies are marked
secure: truein production (NODE_ENV=production) - Set
NODE_ENV=productionwhen deploying with TLS - The
X-Forwarded-Protoheader ensures Lurelit knows it's behind HTTPS - Native TLS support may be added in a future release
The workflow YAML is included at workflow/phishing-smishing-screenshot-analyzer.yaml.
- Navigate to Security → Workflows in Kibana
- Create a new workflow and switch to the YAML editor
- Paste the workflow YAML from this project
- Update all
connector-idreferences to match your own connectors - Save and enable the workflow
- Copy the auto-generated Workflow ID from the URL and paste it into Lurelit settings
Note: Connector IDs are auto-generated by Kibana. You must create connectors within the Workflows UI and update the YAML references. See the in-app documentation for detailed connector setup guides.
┌─────────────────────────────────────────────────────┐
│ Lurelit (Next.js 16 / React 19) │
│ │
│ Upload → Submit → Poll Status → Render Results │
└──────────────────────────┬──────────────────────────┘
│ REST API
▼
┌─────────────────────────────────────────────────────┐
│ Kibana Workflows Engine (9.4+) │
│ │
│ 1. AI Analysis (Anthropic Claude Opus 4.7) │
│ 2. Parse structured classification + IOCs │
│ 3. IOC Enrichment (VirusTotal + urlscan.io) │
│ 4. Summarize enrichment (AI Agent) │
│ 5. Environment threat hunt (AI Agent + ES|QL) │
│ 6. Final report + Slack notification │
└─────────────────────────────────────────────────────┘
- Next.js 16 — App Router with server-side API routes
- React 19 — Client components with hooks
- TypeScript — Strict mode throughout
- Tailwind CSS — Utility classes + custom CSS properties
- Elastic Workflows — Agentic execution engine
- Agent Builder — AI agent orchestration for threat hunting
| Method | Route | Description |
|---|---|---|
| POST | /api/auth/login |
Validate credentials, create session |
| POST | /api/auth/logout |
Destroy session cookie |
| GET | /api/auth/me |
Check authentication status |
| POST | /api/submit |
Submit screenshot for analysis |
| GET | /api/status/[id] |
Poll execution status & results |
| GET | /api/history |
List past executions |
| GET | /api/metrics |
Aggregate threat/safe counts |
| GET/POST | /api/settings |
Read/save configuration |
| GET | /api/settings/test |
Test Kibana connectivity |
Ready-to-use PNG screenshots are provided in examples/screenshots/ covering all analysis paths — benign messages, phishing/smishing threats, spam, and HITL trigger scenarios. Upload them directly to Lurelit to validate classification, enrichment, and threat hunting end-to-end.
Screenshots with real-ioc in the filename contain IOCs flagged by VirusTotal. Combine them with the seed data script (below) to produce both VT enrichment hits and environment hunt hits.
# Inject test documents matching IOCs from test screenshots
./scripts/seed-test-data.sh [ELASTICSEARCH_URL] [USERNAME] [PASSWORD]
# Defaults to localhost:9200 with elastic/changeme
./scripts/seed-test-data.shIf no Kibana URL or Workflow ID is configured, Lurelit enters demo mode with simulated workflow execution — useful for UI development without a live backend.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License — see LICENSE for details.
Built by James Spiteri · Powered by Elastic Workflows and Agent Builder















