Architecture
Appilot is a multi-tenant platform composed of several services. Understanding the architecture helps you make better integration decisions.
System overview
┌─────────────────────────────────────────────────────────────┐
│ Clients │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Extension │ │ Widget │ │ Backoffice │ │
│ │ (Chrome) │ │ (Embedded) │ │ (Org Admin) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────────┘ │
└─────────┼─────────────────┼─────────────────┼───────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ Backend API (Express) │
│ │
│ ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────────┐ │
│ │ Auth │ │Knowledge │ │ RAG │ │ Conversations│ │
│ │ (JWT) │ │ CRUD │ │ Files │ │ + AI Engine │ │
│ └─────────┘ └──────────┘ └─────────┘ └──────────────┘ │
│ ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────────┐ │
│ │Activity │ │Analytics │ │Notific. │ │ Domains │ │
│ │Tracking │ │ Engine │ │ System │ │ + Harvest │ │
│ └─────────┘ └──────────┘ └─────────┘ └──────────────┘ │
└──────────────────────┬──────────────────────────────────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌────────────┐ ┌─────────┐ ┌──────────┐
│ PostgreSQL │ │ AI │ │ File │
│ (Data) │ │Provider │ │ Storage │
└────────────┘ └─────────┘ └──────────┘
Key components
Extension & Widget (Client Layer)
Both the Chrome Extension and the Embeddable Widget:
- Capture page context (DOM structure, forms, fields)
- Provide a conversational UI for the AI assistant
- Apply client-side PII masking before sending data
- Communicate with the backend via REST API + WebSocket
The key difference is how they're delivered and how they authenticate:
| Extension | Widget | |
|---|---|---|
| Delivered by | User installs from Chrome Web Store | Developer adds script tag |
| Authentication | JWT via user login (stored in chrome.storage) | Widget API key + optional user JWT |
| HTTP communication | Via background worker (chrome.runtime) | Direct fetch from page |
| DOM access | Content script (isolated world) | Web Component (light DOM access) |
| CSS isolation | Manual style injection | Shadow DOM (native) |
| Page scope | All pages the user visits | Only the page where embedded |
Backend API
A Node.js/Express server that handles:
- Authentication: JWT-based with organization context
- Knowledge management: CRUD for knowledge content scoped to domains/URLs
- RAG: File upload, embedding, and retrieval for document-grounded answers
- Conversations: AI-powered chat with context injection
- Activity tracking: Anonymized interaction signals for analytics
- Notifications: Real-time updates via WebSocket
Database
PostgreSQL with multi-tenant data isolation:
- Organization-scoped data with row-level filtering
- Knowledge content, requests, domains, user management
- Activity and analytics data
AI Provider
Configurable per organization:
- Default: Google Gemini
- Configurable model selection
- Tool use support for structured actions
- RAG integration for document-grounded responses
Data flow: User asks a question
Extension flow
1. User types question in Extension
2. Content script captures page context (forms, fields, URL)
3. PII masking filters sensitive data client-side
4. Message sent to background worker via chrome.runtime.sendMessage
5. Background worker sends POST /assistant/message with JWT
6. Backend resolves organization from JWT payload
7. Knowledge + RAG + AI provider generates response
8. Response returned to background worker → content script → UI
Widget flow
1. User types question in Widget
2. Widget scans host page DOM for context (forms, fields, URL)
3. PII masking filters sensitive data client-side
4. Widget sends POST /widget/message with API key + session
5. Backend resolves organization from API key (widget_api_keys table)
6. Backend validates Origin header against allowed domains
7. Knowledge + RAG + AI provider generates response
8. Response returned directly to widget
Multi-tenancy
Every API request carries an organization context:
- Extension/Backoffice: Organization resolved from JWT payload (
organization_id) - Widget: Organization resolved from Widget API key (
widget_api_keys.organization_id)
Data queries are scoped to the active organization. AI configuration, knowledge, domains, and users are all isolated per tenant.
See Multi-Tenancy for details.
Security model
Extension
- JWT authentication (user login required)
- Token stored in
chrome.storage.local - All API calls go through the background worker
Widget
- Widget API Key authenticates the integration (not the user)
- Keys are domain-bound: backend validates
Originheader against the key's allowed domains list - Every conversation is attributed to an identified user (no anonymous usage): via federation (the host app's signed handshake), the widget's built-in login, or enterprise SSO. The API key + ephemeral session identify the embed, not the person.
- Rate limiting per API key (configurable
rate_limit_per_minute) - PII masking runs client-side (same
@appilot/pii-detectionpackage as the extension)
API Rate Limiting
All API endpoints are protected by tiered rate limiting:
- Global: 300 requests per minute per IP
- AI endpoints: 20 requests per minute (cost protection)
- Auth endpoints: 20 requests per 15 minutes (brute-force protection)
Security headers are enforced via Helmet middleware.
Both
- HTTPS enforced in production
- Backend PII sanitization middleware as second defense layer
- Multi-tenant data isolation via organization scoping
Declarative Site Adapters
Site Adapters extend Appilot's compatibility to any web framework by providing per-domain configuration:
Admin configures adapter (Backoffice)
→ Stored in database (domains.adapter_config)
→ Fetched by extension on page load
→ Applied to Shadow DOM traversal, page detection, interactions
This architecture decouples framework-specific behavior from code — new framework support requires only a JSON configuration, not code changes.