Zum Hauptinhalt springen

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:

ExtensionWidget
Delivered byUser installs from Chrome Web StoreDeveloper adds script tag
AuthenticationJWT via user login (stored in chrome.storage)Widget API key + optional user JWT
HTTP communicationVia background worker (chrome.runtime)Direct fetch from page
DOM accessContent script (isolated world)Web Component (light DOM access)
CSS isolationManual style injectionShadow DOM (native)
Page scopeAll pages the user visitsOnly 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 Origin header 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-detection package 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.