OttoBot Security
| Document status | Public documentation |
| Target audience | Enterprise security & compliance teams |
| Last updated | 2026-10-01 |
This page describes how per-org OttoBot — the conversational assistant available to your organization inside HG Insights — is deployed, how data moves through it, how requests are authenticated and bound to your organization, and which controls keep one customer's activity separated from another's.
It is written for a security reviewer performing an assessment. For the broader HG Insights platform, see AI Governance; for the technical detail of input handling, redaction, and adversarial testing, see Security Guardrails.
Scope of this document
This document provides a technical and architectural overview of the per-org OttoBot integration. It describes current system design and operational practices.
This document is not:
- A contractual agreement (see your HG Insights MSA for binding terms)
- A substitute for HG Insights Corporate InfoSec documentation (SOC 2, penetration testing, etc.)
- A guarantee of specific SLAs (see service agreement)
Specific contractual commitments, audit rights, and liability terms are negotiated separately in customer agreements.
Not covered here: embedding OttoBot in your own application via iframe. That surface has a separate authentication model and will be documented separately.
1. Integration architecture
Per-org OttoBot is a chat surface inside the HG Insights web application. It is not a separate product you log into, and it is not reachable from the public internet as a standalone service.
A conversation turn moves through three components:
┌──────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ Browser │────▶│ HG Insights app │────▶│ OttoBot service │
│ (your user) │ │ (chat route) │ │ (in-cluster) │
└──────────────┘ └─────────────────┘ └──────────────────┘
▲ │
│ HG MCP Server, as the │
└────────────────────────┘
end user
- Browser → HG Insights. Your user is authenticated to HG Insights by an ordinary session. The chat request goes to an HG Insights API route scoped to your organization.
- HG Insights → OttoBot. HG Insights authorizes the request (§3), mints a short-lived credential bound to that user and organization, and proxies the turn to the OttoBot service over in-cluster networking. The OttoBot service has no public hostname and is not reachable from outside the cluster.
- OttoBot → HG Insights. To answer, OttoBot calls HG Insights' MCP data interface under the end user's identity, using a second short-lived credential. It cannot see data that the signed-in user could not already retrieve in HG Insights directly.
1.1 Shared multi-tenant deployment
Per-org OttoBot runs on a shared multi-tenant service. One process serves many customer organizations. Your organization does not receive a dedicated instance, and we do not currently offer a dedicated-instance tier.
Separation between organizations is logical and enforced per request: every turn resolves its own organization context from a validated credential, and the controls in §4 are applied on that per-request basis rather than being fixed when the service starts. §4.3 states the residual characteristic of this model honestly.
| Component | Provider | Region |
|---|---|---|
| HG Insights webapp | HG Insights (AWS EKS) | US |
| OttoBot service | HG Insights (AWS EKS) | US |
| Database | NeonDB (PostgreSQL) | US |
| Artifact & trace storage | AWS S3 | US |
| Model inference | OpenRouter by default, restricted to providers that do not store the data or train on it; or your organization's own provider account, if your administrators connect one | Varies by provider |
2. Data flow and handling
2.1 What crosses each boundary
| Boundary | What crosses it |
|---|---|
| Browser → HG Insights | The user's message; optionally a client-held transcript of the current conversation (§2.2); the session cookie |
| HG Insights → OttoBot | The message and transcript; a short-lived credential identifying the user and organization |
| OttoBot → HG MCP Server | Data queries issued as the end user, authenticated by a separate short-lived credential |
| OttoBot → Salesforce | Only for a user who has connected their own Salesforce account. Queries run as that user, with a short-lived access token issued for that request (§4.1) |
| OttoBot → model provider | The prompt, the persona/instructions for your organization, and tool results needed to answer |
2.2 Conversation context between turns
The OttoBot service does not hold web-chat history between turns. Conversation context is instead supplied by the browser with each request, and is treated as untrusted input. It is validated against a strict schema that:
- rejects any unexpected field, at the top level or nested within a history entry;
- caps history at 50 messages per request;
- caps each individual message at 8,000 characters;
- rejects the request rather than silently truncating a malformed payload.
Because history is client-supplied, it is treated as conversational context, not as an authoritative record — and never as a source of authorization. What a user may retrieve is determined by their HG Insights identity (§3), not by anything asserted in the transcript.
In Slack and Teams, the service keeps a conversation's working context in memory for 30 minutes after the last message so it can follow the thread, then discards it.
This working context is separate from the conversation record that HG Insights keeps for audit and administrator review, described in §2.3.
2.3 What is persisted
| Data | Where | Retention |
|---|---|---|
| Conversation records (traces). Messages, answers, tool inputs and results (including Salesforce records OttoBot read to answer a question), and the exact request sent to the model | AWS S3 (US), encrypted at rest (AES-256), under a per-organization prefix (§4.1) | 90 days, then deleted automatically |
| Conversation history for administrator review. Messages and answers, copied from the conversation records for the conversation view in HG Insights | HG Insights database, in your organization's own schema | Kept while your organization uses OttoBot; deleted when your organization is deleted |
| Tool data in that copy. Tool inputs and results (including Salesforce records) and the model's intermediate reasoning | HG Insights database, in your organization's own schema | 90 days. We are rolling out the automatic removal. |
| Memory. Preferences and facts a user explicitly asked OttoBot to remember | OttoBot memory store, encrypted at rest | Kept while your organization uses OttoBot. Users can view and remove items from what OttoBot recalls; facts not used for 90 days stop being recalled. |
| Generated files | AWS S3 (US), encrypted at rest | Kept while your organization uses OttoBot |
| Connector tokens (Salesforce) | HG Insights database, encrypted with AES-256-GCM | Until the user disconnects. Disconnecting revokes the tokens at the provider and clears them. |
| Operational logs | HG Insights logging (US) | 90 days. We are rolling this limit out to every log store. Logs record operational metadata, such as which tool ran, its result size, and error messages. They do not record message content or tool results. |
| Answers posted in Slack or Teams | Your Slack or Teams workspace | Your organization's own workspace retention settings |
OttoBot does not sync or bulk-import CRM data. It reads Salesforce live, as the connected user, only to answer that user's question; the connector itself keeps no copy of the records. The records OttoBot read are kept only as tool data (90 days). An answer that summarizes or quotes Salesforce information is part of the conversation history and is kept with it.
Traces are written through a credential-redaction step that scrubs recognised secret formats — API keys, bearer and basic authorization headers, and credential-bearing connection strings — before anything is persisted. This is pattern-based redaction applied on the write path, not a guarantee that every possible secret shape is caught. For the platform-wide redaction behaviour applied to sensitive values, see Security Guardrails §2. Redaction targets credentials; it does not remove message content or personal data from conversation records.
2.4 Who can read conversation records
| Who | Access |
|---|---|
| Your organization's owners and administrators | Your own organization's conversation history, in HG Insights |
| HG Insights platform administrators (a restricted set of HG staff) | Conversation records, to investigate issues |
| HG Insights engineers running quality evaluations | Samples of conversations, drawn to measure answer quality. Every sampling run is recorded in an audit log before any conversation is released: who ran it, which organizations were sampled, how many conversations, and the date window. Audit entries are kept for one year. Sampled copies expire after 7 days. |
HG Insights does not use conversation data to train AI models. Requests through OpenRouter go only to providers that neither store the data nor train on it. If your organization connects its own provider account, that provider's terms apply.
3. Authentication and authorization
3.1 Credential chain
A request is authorized in three stages, each narrower than the last:
- HG Insights session. The user authenticates to HG Insights normally. No OttoBot surface accepts anonymous traffic.
- Short-lived chat credential. HG Insights mints an opaque bearer token, scoped exactly to OttoBot chat, bound to the resolved user and organization, with a five-minute lifetime. It is minted server-side and forwarded to the OttoBot service; it is never used by the browser to call anything else.
- Short-lived data credential. When OttoBot needs to query HG Insights data, the chat credential is exchanged for a second, independently revocable token scoped to data access only, likewise bound to that user and organization.
The two credentials are not interchangeable in either direction: the chat credential is rejected by the data interface, and the data credential is rejected by the chat route. A token minted for one purpose cannot be replayed against the other surface, and neither carries a mixed or broadened scope — scope sets are matched exactly, not by prefix or subset.
3.2 Enforcement on the chat route
When your users chat with OttoBot inside HG Insights, every request passes the following checks before any turn begins. Each failure is terminal, and each is evaluated server-side on the request itself — none is inferred from the client.
| Check | Failure |
|---|---|
| Caller holds a valid HG Insights session | 401 |
| Caller is not a read-only administrator acting on behalf of the organization | 403 |
| Caller is a member of the organization named in the request path | 403 |
| The organization has OttoBot enabled, with a stored upstream that passes the egress allowlist (§3.3) | 404 / 422 |
Only after all of these pass does HG Insights mint the short-lived chat credential (§3.1) for that user and organization and begin the turn. Credential minting happens after authorization, not before it, so an unauthorized request never causes a credential to be issued.
Membership is checked on every request through HG Insights' authorization service. That service maintains a short-lived cache of membership results, so a membership change propagates within the cache lifetime rather than instantaneously.
The separate credential-bearing entry point used for embedded deployments applies additional checks — exact scope matching, organization binding on the credential, and revalidation of the underlying API key against the key registry. That surface is out of scope for this page (see Not covered here above).
3.3 Egress restrictions
HG Insights will only forward an OttoBot turn to an address that passes an allowlist check at the moment the route is configured:
- The OttoBot service address must be in-cluster service DNS, with one exception: a single hardcoded, non-routable hostname reserved for automated testing. Arbitrary public hostnames,
localhost, raw IP addresses, and embedded credentials are rejected. This prevents a misconfigured or maliciously edited route from redirecting a customer's conversation to an external endpoint. - The configuration store address must be either in-cluster service DNS or an HG-operated managed cache endpoint in our production region. The check is a naming-pattern match rather than an account-ownership proof, so it rejects a third party's endpoint in the same region on the strength of the hostname shape. Embedded credentials are likewise rejected.
Both checks are applied at write time, so an invalid destination cannot be stored in the first place.
4. Security controls
4.1 Per-request tenant controls
The following controls are live in production and applied per request, each deriving its behaviour from the validated credential's organization rather than from fixed start-up configuration. Each fails closed: an unrecognised organization is rejected rather than served a default.
| Control | What it enforces |
|---|---|
| Per-request persona selection | The instructions and workspace serving a turn are selected from the validated organization, behind an allowlist with path containment. An unknown organization is refused, not given a fallback persona. |
| Per-user connector credentials | No organization-wide third-party credential is loaded on the shared service. A connector such as Salesforce works only for a user who connected their own account. HG Insights keeps the encrypted refresh token and issues the OttoBot service a short-lived access token for that user's request; the refresh token never leaves HG Insights, and the service does not store the access token. |
| Organization-scoped data session keying | The organization is part of the key identifying a pooled connection to HG Insights, so connections for two organizations cannot collide even if user, conversation, and thread identifiers were identical. Pooled connections are additionally torn down when the credential changes or expires. |
| Per-request trace and artifact prefixing | Trace paths, artifact paths, and observability tags are derived per request from the organization. Two organizations' traces and artifacts land under distinct prefixes and carry distinct tags. |
The browser chat surface accepts only these authenticated, organization-bound requests. There is no unauthenticated path into it, so there is no code path on which a turn could execute without a resolved organization.
4.2 Limits we do not overstate
- Spend caps are enforced at model provisioning, not in-process. The in-process budget guard operates per turn: it stops a single runaway conversation. It is not a cumulative per-organization quota. Caps therefore bound spend; they are not a concurrency control, and we do not claim otherwise.
- The model-facing protections for OttoBot are prompt-level. They live in the persona and instruction layer. Per-org OttoBot chat does not run a pre-model classifier or input-scanning filter in front of the model. The input sanitization described in Security Guardrails §1 applies to the HG Insights agent product, not to this path. The redaction (§2), output guardrails (§3), and adversarial testing programme (§4) described there are platform-wide.
- Authorization is not delegated to the model. What a user can retrieve is fixed by the credential chain in §3 before the model is invoked. Prompt content — including client-supplied history — cannot widen it, because the data credential is bound to the validated user and organization at mint time and cannot be swapped by anything the model emits.
4.3 Residual risk of a shared service
A shared service means one process memory space. Organizations served concurrently by the same process are separated by the per-request controls above rather than by an operating-system or hardware boundary. A sufficiently severe defect in the runtime — one permitting arbitrary code execution or out-of-bounds memory disclosure — is the class of issue those controls narrow but do not categorically eliminate.
We state this plainly because it is the honest characterization of the deployment model, and because we do not currently offer a dedicated-instance alternative. The controls in §4.1 exist to minimize what is resident per turn: credentials are short-lived and per-request, connector credentials are issued per user and per request rather than loaded for the whole service, and the service holds a conversation's working context in memory only while the conversation is active (§2.2).
Organizations whose requirements do not permit a shared process should raise this with their HG Insights representative before enabling OttoBot.
5. Certifications and attestations
The platform is operated by HG Insights and is covered by HG Insights' corporate security programme.
For SOC 2 reports, penetration-testing summaries, and other formal attestations, contact HG Insights Corporate InfoSec through your HG Insights representative. Those artifacts are issued and maintained at the corporate level.
This page makes no independent certification claim on behalf of the OttoBot integration. It describes architecture and controls; it is not itself an attestation, and it does not assert that this integration has been separately certified.
| Question | Where to go |
|---|---|
| SOC 2, penetration tests, formal attestations | HG Insights Corporate InfoSec |
| Contractual terms, audit rights, liability | Your HG Insights MSA |
| Data-residency requirements beyond US | Your HG Insights representative |
| Technical questions about this page | Your HG Insights representative |
Document control
| Version | Date | Author | Changes |
|---|---|---|---|
| 0.1 | 2026-08-21 | HG Insights Team | Initial publication — per-org OttoBot architecture, data flow, authentication, tenant-isolation controls, and residual-risk disclosure for the shared multi-tenant deployment |
| 0.2 | 2026-10-01 | HG Insights Team | Corrected data persistence: conversation records are retained (90 days for tool data; messages and answers for administrator review while the organization uses OttoBot); added retention per store, who can read conversation records, and per-user Salesforce connector handling; model inference defaults to OpenRouter |