{"claims":{"runsOnYourInfrastructure":{"held":false,"detail":"This deployment sends some AI traffic to a third party. See `egress` for exactly which components."},"answersAreTraceable":{"held":true,"detail":"Every answer returns the sources it was grounded in, and the widget renders them as links. Retrieved documents are fenced as untrusted data in the system prompt. Answers below the confidence threshold decline rather than improvise."}},"egress":{"noEgressMode":false,"sealed":false,"components":{"chat":{"endpoint":"the configured provider for each tenant","external":true},"embeddings":{"endpoint":"https://api.openai.com","model":"text-embedding-3-small","external":true},"rerank":{"provider":null,"external":false},"email":{"relay":"mail.digitalcloud.com.np:465","external":true}},"findings":[{"component":"chat","detail":"No self-hosted inference endpoint is configured. Set LOCAL_LLM_BASE_URL to an Ollama, vLLM or LM Studio address, and set every tenant provider to \"local\"."},{"component":"embeddings","detail":"Embeddings are sent to https://api.openai.com. Every visitor question is embedded, so this is the highest-volume egress in the product. Set EMBEDDING_BASE_URL to a local embedding server."},{"component":"email","detail":"Verification email is relayed through mail.digitalcloud.com.np:465, which is outside the network. Point SMTP_HOST at a mail server you run, or unset it -- in which case the process refuses to start in production rather than silently logging codes instead of sending them."}]},"dataAtRest":{"database":"PostgreSQL, including the vector index. No external vector store.","providerCredentials":"AES-256-GCM. Never logged, never returned by any API, never rendered.","embedKeys":"Stored in clear deliberately: an embed key is published inside a script tag on the customer’s own site, so it is not a secret. Its properties come from being unguessable, from a per-key domain allowlist, and from per-key rate limits.","passwords":"bcrypt with a per-user salt.","analytics":"Event names and low-cardinality properties. Credential-shaped and personal keys are stripped before write."},"tenantIsolation":{"rule":"Every query is tenant-scoped in the query itself, never by a filter applied afterwards.","tenantOwnedModels":["AnalyticsEvent","ApiKey","AuditLog","Conversation","CrawlJob","DataSource","DocumentChunk","LeadSubmission","PlanUpgradeRequest","ProviderKey","Subscription","SubscriptionEvent","User","WidgetConfig"]},"rights":{"export":"GET /api/v1/dashboard/compliance?action=export returns every conversation and lead.","erase":"DELETE /api/v1/dashboard/compliance erases a tenant and everything belonging to it.","retention":"Configurable per tenant. Analytics are month-partitioned so expiry drops a partition rather than deleting rows one at a time.","audit":"AuditLog records who did what, to which tenant, from which address."},"outboundRequests":{"rule":"Every fetch built from a URL a tenant supplied goes through the SSRF guard: scheme allowlist, DNS resolution with private-range rejection, re-validation after every redirect, plus time and size caps.","crawler":"Obeys robots.txt, treating an unreachable robots.txt as a full disallow. One request per second per host. Page and depth limits come from the plan."}}