PageSourceSearch

https://orbisid.com/docs/assets/js/40acebdf.fad1a5bd.js

js orbisid.com collected 2026-09-25 18:38:43 UTC 43,429 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkorbisid_docs=globalThis.webpackChunkorbisid_docs||[]).push([[9420],{1430(e,n,t){t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"user-guide/ai-assistant","title":"AI Assistant (OrbisAI)","description":"OrbisID\'s AI/Intelligence Layer adds ten optional, AI-assisted features across the product: a conversational setup assistant, a natural-language Access Graph query, AI-assisted identity-link suggestions, AI-assisted PAM inventory linking, AI-assisted Account Type and Identity Type classification, AI-assisted Privilege Detection and Service Privilege Detection, narrative risk summaries, and Threat Detection clustering.","source":"@site/docs/user-guide/ai-assistant.md","sourceDirName":"user-guide","slug":"/user-guide/ai-assistant","permalink":"/docs/user-guide/ai-assistant","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":12,"frontMatter":{"sidebar_position":12,"title":"AI Assistant (OrbisAI)"},"sidebar":"mainSidebar","previous":{"title":"Endpoint Sensors","permalink":"/docs/user-guide/monitor-agents"},"next":{"title":"Administration","permalink":"/docs/user-guide/administration"}}');var s=t(4848),a=t(8453);const r={sidebar_position:12,title:"AI Assistant (OrbisAI)"},o="AI Assistant (OrbisAI)",l={},c=[{value:"Enabling the AI Layer",id:"enabling-the-ai-layer",level:2},{value:"1. Start Ollama",id:"1-start-ollama",level:3},{value:"2. Configure and enable in Administration > Settings",id:"2-configure-and-enable-in-administration--settings",level:3},{value:"3. What each switch enables",id:"3-what-each-switch-enables",level:3},{value:"The Chat Assistant (OrbisAI)",id:"the-chat-assistant-orbisai",level:2},{value:"Onboarding Assistant",id:"onboarding-assistant",level:3},{value:"General Help",id:"general-help",level:3},{value:"Natural-Language Access Graph Query",id:"natural-language-access-graph-query",level:3},{value:"AI-Assisted Identity Linking",id:"ai-assisted-identity-linking",level:2},{value:"Auto-Linking via a Policy Rule (Pro+/Enterprise)",id:"auto-linking-via-a-policy-rule-proenterprise",level:3},{value:"AI-Assisted PAM Inventory Linking",id:"ai-assisted-pam-inventory-linking",level:2},{value:"AI-Assisted Account Type / Identity Type Classification",id:"ai-assisted-account-type--identity-type-classification",level:2},{value:"AI-Assisted NHI Subtype Classification",id:"ai-assisted-nhi-subtype-classification",level:2},{value:"AI-Assisted Privilege Detection / Service Privilege Detection",id:"ai-assisted-privilege-detection--service-privilege-detection",level:2},{value:"Narrative Risk Summarisation",id:"narrative-risk-summarisation",level:2},{value:"Threat Detection Clustering",id:"threat-detection-clustering",level:2},{value:"Audit Trail",id:"audit-trail",level:2},{value:"Data Sent to the Model",id:"data-sent-to-the-model",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"ai-assistant-orbisai",children:"AI Assistant (OrbisAI)"})}),"\n",(0,s.jsx)(n.p,{children:"OrbisID's AI/Intelligence Layer adds ten optional, AI-assisted features across the product: a conversational setup assistant, a natural-language Access Graph query, AI-assisted identity-link suggestions, AI-assisted PAM inventory linking, AI-assisted Account Type and Identity Type classification, AI-assisted Privilege Detection and Service Privilege Detection, narrative risk summaries, and Threat Detection clustering."}),"\n",(0,s.jsxs)(n.p,{children:["Two independent switches in ",(0,s.jsx)(n.strong,{children:"Administration > Settings > OrbisAI"})," control all of it:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"AI LLM"})," \u2014 the master switch for everything that calls the local Ollama language model: the OrbisAI chat assistant (Onboarding Assistant, General Help, Natural-Language Access Graph Query), narrative risk summaries, Threat Detection clustering, and the ambiguous-case second opinion inside identity/PAM linking and Account Type/Identity Type/Privilege Detection classification."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Smart Matching & Suggestions"})," \u2014 the deterministic, non-AI fuzzy-matching engine behind identity-link suggestions, PAM inventory link suggestions, and Account Type/Identity Type/Privilege Detection classification suggestions. Runs entirely locally using text similarity, with no Ollama connection \u2014 it works even with AI LLM switched off."]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{title:"Requires Pro or Enterprise",type:"info",children:(0,s.jsxs)(n.p,{children:["The AI/Intelligence Layer is not available on Community edition \u2014 see ",(0,s.jsx)(n.a,{href:"../licensing#aiintelligence-layer",children:"Licensing"}),". Both switches described below only have any effect on Pro or Enterprise; on Community they are hidden/disabled in Administration > Settings > OrbisAI regardless of setting."]})}),"\n",(0,s.jsx)(n.admonition,{title:"On by default, local-only",type:"info",children:(0,s.jsxs)(n.p,{children:["On editions where it's available, both 
1switches are ",(0,s.jsx)(n.strong,{children:"on by default"})," \u2014 the first administrator to log in is asked to confirm this (or turn either off) in the same one-time ",(0,s.jsx)(n.strong,{children:"Initial Setup"})," prompt used for Check for Updates / Usage Statistics, and it can be changed at any time afterwards in Administration > Settings. AI LLM talks only to a ",(0,s.jsxs)(n.strong,{children:["locally hosted ",(0,s.jsx)(n.a,{href:"https://ollama.com",children:"Ollama"})," instance running inside your own network"]})," \u2014 no data ever leaves your network, and no external AI provider is used. Even with AI LLM on, every LLM-backed surface stays hidden (not shown-but-erroring) until an Ollama instance is actually reachable \u2014 see below."]})}),"\n",(0,s.jsx)(n.h2,{id:"enabling-the-ai-layer",children:"Enabling the AI Layer"}),"\n",(0,s.jsx)(n.p,{children:"If you accepted the defaults during Initial Setup, both switches in step 2 below are already on \u2014 you only need step 1 (an actual Ollama instance for AI LLM to talk to; Smart Matching & Suggestions needs nothing further). If you turned either off at that prompt, or are configuring an existing install, do all three steps."}),"\n",(0,s.jsx)(n.h3,{id:"1-start-ollama",children:"1. Start Ollama"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"There's nothing to do here"})," \u2014 the release package (all-in-one or external-db) defines an ",(0,s.jsx)(n.code,{children:"ollama"})," container that starts automatically with the rest of the stack, pulling its own image plus the default models (",(0,s.jsx)(n.code,{children:"qwen2.5:1.5b-instruct"}),", ",(0,s.jsx)(n.code,{children:"nomic-embed-text"}),") from the internet on first start via a one-shot ",(0,s.jsx)(n.code,{children:"ollama-init"})," container. Give it a few minutes on first start for those downloads, then skip to step 2. See ",(0,s.jsx)(n.a,{href:"../installation/deployment#ai-runtime-ollama",children:"Deployment \u2014 AI Runtime (Ollama)"})," for how that's packaged and how to disable it if you don't want it running."]}),"\n",(0,s.jsx)(n.p,{children:"If you already run Ollama elsewhere on your network, you don't need the bundled container \u2014 just point OrbisID at it (see below)."}),"\n",(0,s.jsx)(n.h3,{id:"2-configure-and-enable-in-administration--settings",children:"2. Configure and enable in Administration > Settings"}),"\n",(0,s.jsxs)(n.p,{children:["Navigate to ",(0,s.jsx)(n.strong,{children:"Administration > Settings > OrbisAI"})," and set:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Field"}),(0,s.jsx)(n.th,{children:"Default"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AI LLM"}),(0,s.jsx)(n.td,{children:"Off"}),(0,s.jsx)(n.td,{children:"Master switch for everything Ollama-backed. Nothing that calls the model has any effect while this is off."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Smart Matching & Suggestions"}),(0,s.jsx)(n.td,{children:"On"}),(0,s.jsx)(n.td,{children:"The deterministic fuzzy-matching engine. Independent of AI LLM \u2014 works with or without it."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Ollama Base URL"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"http://ollama:11434"})}),(0,s.jsxs)(n.td,{children:["The Ollama endpoint. Use ",(0,s.jsx)(n.code,{children:"http://localhost:11434"})," if you're running the local dev loop (",(0,s.jsx)(n.code,{children:"dev.sh"}),") \u2014 the backend runs on the host there, not inside the Docker network, so the ",(0,s.jsx)(n.code,{children:"ollama"})," hostname doesn't resolve."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Chat Model"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"qwen2.5:1.5b-instruct"})}),(0,s.jsx)(n.td,{children:"Model used for chat/instruction completions"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Embedding Model"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"nomic-embed-text"})}),(0,s.jsx)(n.td,{children:"Model used for retrieval-augmented grounding (Onboarding Assistant)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Request Timeout (seconds)"}),(0,s.jsx)(n.td,{children:"300"}),(0,s.jsx)(n.td,{children:'How long to wait for a response. CPU-only Ollama (no GPU/Metal passthrough, common in Docker Desktop, or a small/burstable cloud instance) is much slower than GPU-accelerated \u2014 increase this further if you see "taking too long to respond" errors, particularly for connector-scoped Onboarding Assistant questions, which send a larger prompt than general help and can run 2-3x longer.'})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["Click ",(0,s.jsx)(n.strong,{children:"Test Connection"})," to confirm OrbisID can reach Ollama before relying on AI LLM. Note this only checks that the Ollama server itself responds \u2014 it does not confirm the configured Chat Model has actually been pulled; if chat still fails afterwards, check that the model is present (",(0,s.jsx)(n.code,{children:"docker exec <ollama-container> ollama list"}),")."]}),"\n",(0,s.jsx)(n.h3,{id:"3-what-each-switch-enables",children:"3. What each switch enables"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Feature"}),(0,s.jsx)(n.th,{children:"Switch"}),(0,s.jsx)(n.th,{children:"Requires"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Onboarding & Help Assistant"}),(0,s.jsx)(n.td,{children:"AI LLM"}),(0,s.jsx)(n.td,{children:"Pro or Enterprise"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Risk Narrative Summarisation"}),(0,s.jsx)(n.td,{children:"AI LLM"}),(0,s.jsx)(n.td,{children:"Pro or Enterprise"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Access Graph Natural-Language Query"}),(0,s.jsx)(n.td,{children:"AI LLM"}),(0,s.jsxs)(n.td,{children:["Pro or Enterprise (Access Graph itself is ",(0,s.jsx)(n.a,{href:"./access-graph",children:"available on Community"}),", but the AI query layer on top of it is not)"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AI-Assisted Identity Linking"}),(0,s.jsx)(n.td,{children:"Smart Matching & Suggestions (deterministic) + AI LLM (amb
1iguous-case escalation)"}),(0,s.jsx)(n.td,{children:"Pro or Enterprise"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AI-Assisted PAM Inventory Linking"}),(0,s.jsx)(n.td,{children:"Smart Matching & Suggestions (deterministic) + AI LLM (ambiguous-case escalation)"}),(0,s.jsx)(n.td,{children:"Pro or Enterprise"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AI-Assisted Account Type Classification"}),(0,s.jsx)(n.td,{children:"Smart Matching & Suggestions (deterministic) + AI LLM (ambiguous-case escalation)"}),(0,s.jsx)(n.td,{children:"Pro or Enterprise"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AI-Assisted Identity Type Classification"}),(0,s.jsx)(n.td,{children:"Smart Matching & Suggestions (deterministic) + AI LLM (ambiguous-case escalation)"}),(0,s.jsx)(n.td,{children:"Pro or Enterprise"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AI-Assisted Privilege Detection"}),(0,s.jsx)(n.td,{children:"Smart Matching & Suggestions (deterministic) + AI LLM (ambiguous-case escalation)"}),(0,s.jsx)(n.td,{children:"Pro or Enterprise"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"AI-Assisted Service Privilege Detection"}),(0,s.jsx)(n.td,{children:"Smart Matching & Suggestions (deterministic) + AI LLM (ambiguous-case escalation)"}),(0,s.jsx)(n.td,{children:"Pro or Enterprise"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Threat Detection Clustering"}),(0,s.jsx)(n.td,{children:"AI LLM"}),(0,s.jsxs)(n.td,{children:["Enterprise (same as ",(0,s.jsx)(n.a,{href:"./alerts",children:"Threat Detections"}),")"]})]})]})]}),"\n",(0,s.jsx)(n.p,{children:"For the six matching/classification features, the deterministic scorer always runs when Smart Matching & Suggestions is on \u2014 AI LLM only adds a second opinion for genuinely ambiguous cases, and each still works (just without that second opinion) if AI LLM is off."}),"\n",(0,s.jsxs)(n.p,{children:["A separate ",(0,s.jsx)(n.strong,{children:'"LLM Escalation (Ambiguous Cases)"'})," section on the same Settings tab gives each of those six features its own on/off toggle for just the LLM-escalation piece \u2014 Identity Linking, PAM Inventory Linking, Account Type Classification, Identity Type Classification, Privilege Detection, Service Privilege Detection. All are ",(0,s.jsx)(n.strong,{children:"on by default"}),". Turning one off stops that specific feature from ever calling the model, while leaving AI LLM on for everything else (chat, narrative summaries, natural-language graph query, threat clustering, and the other five escalation toggles) and leaving that feature's own deterministic scoring completely unaffected. These toggles only matter \u2014 and are only shown as enabled \u2014 while AI LLM itself is on; with AI LLM off, none of the six ever escalate anyway."]}),"\n",(0,s.jsx)(n.h2,{id:"the-chat-assistant-orbisai",children:"The Chat Assistant (OrbisAI)"}),"\n",(0,s.jsxs)(n.p,{children:["A persistent chat icon appears in the ",(0,s.jsx)(n.strong,{children:"bottom-left corner"}),' of every page once at least one chat-based feature is enabled. It\'s a single conversation, not a set of per-page modes \u2014 a connector-setup question and an Access Graph question can both be asked back to back, regardless of which page happens to be open: ask about adding a CyberArk connector from the Dashboard, or ask what an account can reach while the Systems "Add System" dialog is still up. By default, which capability answers a given message is decided automatically from the message itself (and, as a fallback, from whatever connector is currently in view, e.g. the "Add System" dialog, or from what the previous message in the conversation was about) \u2014 you never ',(0,s.jsx)(n.em,{children:"have"})," to pick anything."]}),"\n",(0,s.jsxs)(n.p,{children:["An ",(0,s.jsx)(n.strong,{children:'"Ask about"'})," dropdown at the top of the chat lets you pick a capability explicitly instead \u2014 ",(0,s.jsx)(n.strong,{children:"OrbisID Help"}),", ",(0,s.jsx)(n.strong,{children:"Account / Access Question"})," (the Access Graph), or ",(0,s.jsx)(n.strong,{children:"Connector Configuration"})," \u2014 when you already know what kind of question you're asking. This skips the automatic guess entirely, so it's both faster (no wasted attempt at the wrong capability) and useful when a question's phrasing is ambiguous enough that auto-detection might get it wrong. Leave it on ",(0,s.jsx)(n.strong,{children:"Auto"})," (the default) for everyday use."]}),"\n",(0,s.jsxs)(n.p,{children:["Follow-up questions work within a conversation \u2014 asking ",(0,s.jsx)(n.em,{children:'"are you sure that\'s correct?"'})," or ",(0,s.jsx)(n.em,{children:'"what about for a non-admin user?"'})," right after an answer carries the last couple of exchanges along as context, so the assistant can actually address what was just said rather than treating every message as a brand-new, unrelated question. This is scoped to the current conversation only: nothing is stored once you close the browser tab or start ",(0,s.jsx)(n.strong,{children:"New Chat"}),", and it does not affect ",(0,s.jsx)(n.a,{href:"./administration#audit-logs",children:"Audit Logs"}),", which still only ever record a hash of each request, never full text."]}),"\n",(0,s.jsxs)(n.p,{children:["The chat window stays open across pages until you close it with the ",(0,s.jsx)(n.strong,{children:"\xd7"})," \u2014 it doesn't auto-dismiss if you click elsewhere. ",(0,s.jsx)(n.strong,{children:"New Chat"})," clears the conversation; reopening the launcher otherwise continues where you left off."]}),"\n",(0,s.jsx)(n.h3,{id:"onboarding-assistant",children:"Onboarding Assistant"}),"\n",(0,s.jsxs)(n.p,{children:["Ask about a connector by name from anywhere \u2014 e.g. ",(0,s.jsx)(n.em,{children:'"How do I configure CyberArk?"'})," \u2014 or open its setup dialog on the ",(0,s.jsx)(n.a,{href:"./systems#adding-systems",children:"Systems"})," page and ask a question without naming it (e.g. ",(0,s.jsx)(n.em,{children:'"What permissions does the scan account need?"'}),"), which uses whichever connector is currently selected there. If a ",(0,s.jsx)(n.strong,{children:"Test Connection"})," attempt fails, the ",(0,s.jsx)(n.strong,{children:"Need help with this error?"})," link next to the failure pre-seeds the chat with the exact error for you."]}),"\n",(0,s.jsxs)(n.p,{children:["Answers cite the section of OrbisID's own documentation they came from. The assistant ",(0,s.jsx)(n.strong,{children:"never asks for, displays, or accepts a credential value"})," \u2014 it will always direct you to the separate Credential fields instead."]}),"\n",(0,s.jsx)(n.h3,{id:"general-help",children:"General Help"}),"\n",(0,s.jsx)(n.p,{children:'Ask general "how do I" or "what is" questions about OrbisID itself, from anywhere \u2014 for example:'}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.em,{children:'"What is a KRI?"'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.em,{children:'"How do I export a report to CSV?"'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.em,{children:'"What\'s the difference between the Pro and Enterprise editions?"'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.em,{children:'"How does PAM reconciliation work?"'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["This shares the same toggle and grounding approach as the Onboarding Assistant, just retrieving from OrbisID's whole user guide instead of one connector's page \u2014 answers still cite the section(s) they came from, and the assistant says plainly when a question isn't covered rather than guessing. If ",(0,s.jsx)(n.a,{href:"#natural-language-access-graph-query",children:"Access Graph Natural-Language Query"}),' is also enabled, a question is tried against the graph first (since many "who/what" questions are graph questions);
1 if the graph decides it\'s genuinely not a graph question, general help answers instead, so you rarely need to think about which one will respond.']}),"\n",(0,s.jsx)(n.h3,{id:"natural-language-access-graph-query",children:"Natural-Language Access Graph Query"}),"\n",(0,s.jsx)(n.p,{children:"Ask a graph question from any page, for example:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.em,{children:'"What can svc-backup reach?"'})," \u2192 blast radius from that account"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.em,{children:'"Who owns the prod-db-01 server?"'})," \u2192 ownership chain"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.em,{children:'"How is jsmith connected to Domain Admins?"'})," \u2192 shortest path"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.em,{children:'"Show me unvaulted privileged accounts"'})," \u2192 runs the matching pre-built query"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The chat response always shows the ",(0,s.jsx)(n.strong,{children:"interpreted query in plain English"})," before any results, so you can confirm it understood correctly \u2014 this text is generated from the actual query that ran, not the model's own description of it, so it can't misdescribe what happened. If your question names something that matches more than one entity, you'll be offered the specific matches to pick from rather than a guess. Click ",(0,s.jsx)(n.strong,{children:"Open in graph"})," to load the result onto the ",(0,s.jsx)(n.a,{href:"./access-graph",children:"Access Graph"})," canvas \u2014 if that page isn't already open, this navigates there for you."]}),"\n",(0,s.jsx)(n.p,{children:"Read-only: no natural-language question can create, modify, or delete anything, and results are limited to whatever your role and licence could already see directly in Access Graph."}),"\n",(0,s.jsx)(n.h2,{id:"ai-assisted-identity-linking",children:"AI-Assisted Identity Linking"}),"\n",(0,s.jsxs)(n.p,{children:["When you open the ",(0,s.jsx)(n.strong,{children:"link identity"})," dialog for an unlinked account on the ",(0,s.jsx)(n.a,{href:"./accounts#linking-accounts-to-identities",children:"Accounts"})," page, a ",(0,s.jsx)(n.strong,{children:"Suggested Matches"}),' list appears above the identity search box \u2014 ranked candidates with a confidence percentage and the reason for the match (e.g. "Account email matches the identity\'s email", "Account name matches the identity\'s initial and surname").']}),"\n",(0,s.jsxs)(n.p,{children:["This works ",(0,s.jsx)(n.strong,{children:"even with the AI layer completely off"})," \u2014 the base matching is a deterministic name/email comparison, not an AI feature. When AI ",(0,s.jsx)(n.em,{children:"is"})," enabled, genuinely ambiguous matches (neither clearly right nor clearly wrong) get a second look from the model, shown as method ",(0,s.jsx)(n.strong,{children:"LLM"})," instead of ",(0,s.jsx)(n.strong,{children:"RULE"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Clicking a suggestion fills in the identity selection \u2014 on this page, nothing is ever linked automatically. If the account's PAM Risk Level is ",(0,s.jsx)(n.strong,{children:"High"})," or ",(0,s.jsx)(n.strong,{children:"Critical"}),", you'll always be asked for an extra explicit confirmation before the link is saved, regardless of how confident the suggestion is."]}),"\n",(0,s.jsx)(n.h3,{id:"auto-linking-via-a-policy-rule-proenterprise",children:"Auto-Linking via a Policy Rule (Pro+/Enterprise)"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["Requires the ",(0,s.jsx)(n.code,{children:"IDENTITY_LINKING_AUTO"})," licence feature (Pro or Enterprise) in addition to AI-Assisted Identity Linking above."]})}),"\n",(0,s.jsxs)(n.p,{children:["For a hands-off alternative, create an ",(0,s.jsx)(n.strong,{children:"Identity Linking (AI Auto-Link)"})," rule on the ",(0,s.jsx)(n.a,{href:"./scanning#policy-rules",children:"Policy Rules"})," editor (Configuration page) with a ",(0,s.jsx)(n.strong,{children:"Confidence Threshold"})," (0.51\u20131.00). Once enabled and attached to a Scan Policy, any unlinked account whose best AI-assisted match meets or exceeds that threshold is linked automatically during the scan \u2014 no manual click required. Use ",(0,s.jsx)(n.strong,{children:"Test Rule"})," first to see which accounts would link (and at what confidence) without actually linking anything, then ",(0,s.jsx)(n.strong,{children:"Apply Rule"})," to link them immediately, or just let it run on the next scheduled scan."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"High/Critical PAM risk exception above is absolute here too"})," \u2014 it is not configurable and cannot be raised by the rule's threshold. An account on a High or Critical risk system is always left for manual review on the Accounts page, however confident the match. Every auto-link this rule makes is recorded in ",(0,s.jsx)(n.a,{href:"./administration#audit-logs",children:"Audit Logs"})," the same way a manually-confirmed suggestion is, with the matching method and confidence."]}),"\n",(0,s.jsx)(n.h2,{id:"ai-assisted-pam-inventory-linking",children:"AI-Assisted PAM Inventory Linking"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["Requires the ",(0,s.jsx)(n.code,{children:"PAM_INVENTORY_LINKING_AUTO"})," licence feature (Pro or Enterprise)."]})}),"\n",(0,s.jsxs)(n.p,{children:["Unlike identity linking, privileged account names repeat constantly across an estate (",(0,s.jsx)(n.code,{children:"root"}),", ",(0,s.jsx)(n.code,{children:"Administrator"}),", ",(0,s.jsx)(n.code,{children:"svc-backup"})," on dozens of different servers), so name similarity alone can't reliably tell one PAM vault record from another. The matcher instead anchors on the vaulted credential's reported ",(0,s.jsx)(n.strong,{children:"address"})," (hostname or IP) against the account's own system \u2014 a candidate whose address doesn't plausibly correspond to the account's system is never scored highly on name similarity alone. This deterministic address/name matching runs ",(0,s.jsx)(n.strong,{children:"even with the AI layer completely off"}),"; when AI ",(0,s.jsx)(n.em,{children:"is"})," enabled, genuinely ambiguous matches get a second look from the model, shown as method ",(0,s.jsx)(n.strong,{children:"LLM"})," instead of ",(0,s.jsx)(n.strong,{children:"RULE"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Create a ",(0,s.jsx)(n.strong,{children:"PAM Inventory Linking (AI Auto-Match)"})," rule on the ",(0,s.jsx)(n.a,{href:"./scanning#policy-rules",children:"Policy Rules"})," editor (Configuration page) with a ",(0,s.jsx)(n.strong,{children:"Confidence Threshold"}
1)," (0.51\u20131.00). Once attached to a Scan Policy, any privileged account not yet linked to a PAM inventory record whose best match meets or exceeds that threshold is linked automatically during the scan. Use ",(0,s.jsx)(n.strong,{children:"Test Rule"})," first to see which accounts would link (and at what confidence) without actually linking anything, then ",(0,s.jsx)(n.strong,{children:"Apply Rule"})," to link them immediately, or let it run on the next scheduled scan."]}),"\n",(0,s.jsxs)(n.p,{children:["The same ",(0,s.jsx)(n.strong,{children:"High/Critical PAM risk exception"})," applies here, non-negotiable: an account on a High or Critical risk system is always left for manual review on the ",(0,s.jsx)(n.a,{href:"./pam-inventory",children:"PAM Reconciliation"}),' page, however confident the match \u2014 a false "this dangerous account is vaulted" signal on the highest-risk accounts is exactly the failure this exists to prevent. Every auto-link this rule makes is recorded in ',(0,s.jsx)(n.a,{href:"./administration#audit-logs",children:"Audit Logs"})," with the matching method and confidence."]}),"\n",(0,s.jsx)(n.h2,{id:"ai-assisted-account-type--identity-type-classification",children:"AI-Assisted Account Type / Identity Type Classification"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["Requires the ",(0,s.jsx)(n.code,{children:"CATEGORISATION_AI_AUTO"})," / ",(0,s.jsx)(n.code,{children:"IDENTITY_CLASSIFICATION_AI_AUTO"})," licence feature (Pro or Enterprise) respectively."]})}),"\n",(0,s.jsxs)(n.p,{children:["Account Type and Identity Type rules classify discovered accounts and identities as Human or Non-Human. The built-in rule catalogue covers common naming conventions (",(0,s.jsx)(n.code,{children:"svc-"}),", ",(0,s.jsx)(n.code,{children:"service-"}),", low Linux UIDs, missing employee ID, and similar), but any account or identity that doesn't match one of those patterns is left unclassified. The AI classifiers exist specifically to cover that gap \u2014 they only ever run on accounts/identities ",(0,s.jsx)(n.strong,{children:"no existing rule has classified"}),", never on ones a rule-based match already decided. A deterministic keyword/pattern scorer (broader than the built-in catalogue) always runs first; when AI is enabled, a genuinely ambiguous score gets a second look from the model, shown as method ",(0,s.jsx)(n.strong,{children:"LLM"})," instead of ",(0,s.jsx)(n.strong,{children:"RULE"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Create an ",(0,s.jsx)(n.strong,{children:"Account Type (AI Auto-Classify)"})," or ",(0,s.jsx)(n.strong,{children:"Identity Type (AI Auto-Classify)"})," rule on the ",(0,s.jsx)(n.a,{href:"./scanning#policy-rules",children:"Policy Rules"})," editor with a ",(0,s.jsx)(n.strong,{children:"Confidence Threshold"})," (0.51\u20131.00). Once attached to a Scan Policy, unclassified accounts/identities whose best AI-assisted classification meets or exceeds that threshold are classified automatically during the scan. Use ",(0,s.jsx)(n.strong,{children:"Test Rule"})," first to preview what would be classified (and at what confidence), then ",(0,s.jsx)(n.strong,{children:"Apply Rule"})," to classify immediately, or let it run on the next scheduled scan."]}),"\n",(0,s.jsxs)(n.p,{children:["Unlike privilege detection, this classification is ",(0,s.jsx)(n.strong,{children:"bidirectional"})," \u2014 the confidence threshold alone decides between Human and Non-Human, with no asymmetric safety rail (mislabelling in either direction is a data-quality issue here, not a security gap). A rule-based classification always takes precedence: if you later add or enable a SpEL Account Type / Identity Type rule that matches an AI-classified item, the rule-based result wins on the next scan."]}),"\n",(0,s.jsx)(n.h2,{id:"ai-assisted-nhi-subtype-classification",children:"AI-Assisted NHI Subtype Classification"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["Requires the ",(0,s.jsx)(n.code,{children:"AI_NHI_SUBTYPE_CLASSIFICATION"})," licence feature (Pro or Enterprise)."]})}),"\n",(0,s.jsxs)(n.p,{children:["NHI Subtype Classification assigns a finer-grained subtype (API Key, Service Account, Cloud Role, Managed Identity, Application, Scheduled Task, Bot, Certificate, Machine Account, Other) to Non-Human accounts, on top of the base Human/Non-Human Account Type above. Many connectors (see ",(0,s.jsx)(n.a,{href:"./systems",children:"Systems"}
1),") assert this directly from an unambiguous source-system signal at scan time \u2014 an AWS IAM access key, an Azure AD service principal's certificate, a CyberArk platform ID, and similar \u2014 no rule or AI involved. For everything else, the built-in NHI Subtype rule catalogue covers common naming conventions, and the AI classifier covers what's left: it only ever runs on Non-Human accounts ",(0,s.jsx)(n.strong,{children:"no connector signal or existing rule has already classified"}),", never on ones a connector hint or rule-based match already decided. A deterministic keyword/pattern scorer always runs first; when AI is enabled, a genuinely ambiguous score gets a second look from the model, shown as method ",(0,s.jsx)(n.strong,{children:"LLM"})," instead of ",(0,s.jsx)(n.strong,{children:"RULE"}),"."]}),"\n",(0,s.jsx)(n.admonition,{title:"Not yet available in the Policy Rules editor",type:"note",children:(0,s.jsxs)(n.p,{children:["Unlike the other AI Auto-Classify rule types on this page, NHI Subtype Classification (AI Auto-Classify) rules can currently only be created and run via the Policy Rule API (test/run endpoints) \u2014 there is no Configuration page UI for this rule type yet. The base, non-AI ",(0,s.jsx)(n.strong,{children:"NHI Subtype"})," SpEL rule type is available in the ",(0,s.jsx)(n.a,{href:"./scanning#policy-rules",children:"Policy Rules"})," editor today."]})}),"\n",(0,s.jsxs)(n.p,{children:["Once created via the API with a ",(0,s.jsx)(n.strong,{children:"Confidence Threshold"})," (0.51\u20131.00) and attached to a Scan Policy, matching Non-Human accounts are classified automatically during the scan \u2014 the same test-first, apply-or-schedule workflow as the other AI Auto-Classify rule types."]}),"\n",(0,s.jsxs)(n.p,{children:["This classification is ",(0,s.jsx)(n.strong,{children:"bidirectional"})," in the same sense as Account Type / Identity Type \u2014 there's no asymmetric safety rail, since assigning the wrong subtype is a data-quality issue, not a security gap. A connector signal or rule-based classification always takes precedence: if a later scan's connector hint or a SpEL NHI Subtype rule matches an AI-classified account, the higher-tier result wins."]}),"\n",(0,s.jsx)(n.h2,{id:"ai-assisted-privilege-detection--service-privilege-detection",children:"AI-Assisted Privilege Detection / Service Privilege Detection"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["Requires the ",(0,s.jsx)(n.code,{children:"PRIVILEGE_DETECTION_AI_AUTO"})," / ",(0,s.jsx)(n.code,{children:"SERVICE_PRIVILEGE_DETECTION_AI_AUTO"})," licence feature (Pro or Enterprise) respectively."]})}),"\n",(0,s.jsxs)(n.p,{children:["Privilege Detection and Service Privilege Detection rules flag discovered entitlements and services as Privileged. The built-in rule catalogue matches specific, literal group/user names (",(0,s.jsx)(n.code,{children:"Domain Admins"}),", ",(0,s.jsx)(n.code,{children:"sudo"}),", ",(0,s.jsx)(n.code,{children:"root"}),', and similar) \u2014 any custom or organisation-specific privileged group ("DBA-Team", "IT-Support-L3") or non-root-run privileged service won\'t match. The AI classifiers exist specifically to cover that gap \u2014 they only ever run on entitlements/services ',(0,s.jsx)(n.strong,{children:"no existing rule has already flagged as Privileged"}),". A deterministic keyword/pattern scorer (broader than the built-in catalogue \u2014 for example it also recognises individual sudo privilege entries the catalogue's group-name matching misses entirely) always runs first; when AI is enabled, a genuinely ambiguous score gets a second look from the model, shown as method ",(0,s.jsx)(n.strong,{children:"LLM"})," instead of ",(0,s.jsx)(n.strong,{children:"RULE"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Create a ",(0,s.jsx)(n.strong,{children:"Privilege Detection (AI Auto-Classify)"})," or ",(0,s.jsx)(n.strong,{children:"Service Privilege Detection (AI Auto-Classify)"})," rule on the ",(0,s.jsx)(n.a,{href:"./scanning#policy-rules",children:"Policy Rules"})," editor with a ",(0,s.jsx)(n.strong,{children:"Confidence Threshold"}
1)," (0.51\u20131.00). Once attached to a Scan Policy, not-yet-privileged entitlements/services whose best AI-assisted classification meets or exceeds that threshold are flagged Privileged automatically during the scan. Use ",(0,s.jsx)(n.strong,{children:"Test Rule"})," first to preview what would be flagged (and at what confidence), then ",(0,s.jsx)(n.strong,{children:"Apply Rule"})," to flag immediately, or let it run on the next scheduled scan."]}),"\n",(0,s.jsx)(n.p,{children:"Two safety properties apply here, both non-negotiable:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"One-directional."})," These rules can only ever ",(0,s.jsx)(n.em,{children:"add"})," Privileged status \u2014 never remove or downgrade an entitlement/service a rule, a manual override, or a previous AI classification already marked Privileged. Under-flagging a privileged entitlement (a missed audit finding) is a worse failure than over-flagging one (review noise), so there's no symmetric \"AI thinks this isn't privileged\" action."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Shared per-scan escalation cap."})," Because a single system can have thousands of entitlements, the LLM second opinion is capped per scan (combined across entitlements and services, admin-configurable, default 20) \u2014 the deterministic scorer still evaluates everything, but only a bounded number of genuinely ambiguous items get a model call in any one scan. Anything beyond the cap is simply reconsidered on the next scan, never treated as decisively non-privileged."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"narrative-risk-summarisation",children:"Narrative Risk Summarisation"}),"\n",(0,s.jsx)(n.p,{children:"A short, plain-English summary appears in two places once enabled:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.a,{href:"./dashboard#ai-risk-summary",children:"Dashboard"})})," \u2014 a collapsible panel directly above Threat Detection Alerts, broken into three columns (Current State, Progress Since Last Month, Recommended Next Steps) summarising the latest scan's KRI values and how they've changed since the previous scan. There's no regenerate control here \u2014 it refreshes automatically as a side effect of each scan; an administrator can also trigger it on demand with ",(0,s.jsx)(n.strong,{children:"Generate Risk Summary Now"})," in Administration > Settings > OrbisAI (the only way to produce it before your first scan)."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsxs)(n.strong,{children:[(0,s.jsx)(n.a,{href:"./gap-analysis#downloading-the-pdf-report",children:"Gap Analysis"})," PDF report"]}),' \u2014 an "AI-Generated Risk Summary" section, generated when the assessment is completed and regenerable from the assessment page before your next download.']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Both summaries are generated only from already-computed values (KRI numbers, gap-analysis finding counts) \u2014 never from account-level or identity data \u2014 and are cached, so historical reports stay reproducible even if you later change the AI model or prompt. Regenerating updates the cached copy but does not rewrite past PDF exports you've already downloaded."}),"\n",(0,s.jsx)(n.h2,{id:"threat-detection-clustering",children:"Threat Detection Clustering"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["Requires Enterprise edition (same as ",(0,s.jsx)(n.a,{href:"./alerts",children:"Threat Detections"})," itself)."]})}),"\n",(0,s.jsxs)(n.p,{children:["On the ",(0,s.jsx)(n.a,{href:"./alerts",children:"Threat Detections"})," page, a ",(0,s.jsx)(n.strong,{children:"Clusters | All Alerts"}
1)," toggle appears once enabled. Clusters group related alerts for the same account within a configurable time window into a single incident card, showing the systems and detection rules involved, the highest confidence score, and a short AI narrative explaining the pattern. Expand a cluster to see (and action) the individual constituent alerts exactly as before."]}),"\n",(0,s.jsxs)(n.p,{children:["Clustering itself is a deterministic grouping, not an AI feature, so clusters still form correctly if the AI layer is briefly unreachable \u2014 only the narrative text is missing in that case. Clustering never changes the underlying Threat Detection engine or its confidence scoring; it only changes how related alerts are presented. All Threat Detections surfaces, clustered or not, retain their ",(0,s.jsx)(n.strong,{children:"Beta"})," labelling."]}),"\n",(0,s.jsx)(n.h2,{id:"audit-trail",children:"Audit Trail"}),"\n",(0,s.jsxs)(n.p,{children:["Every AI call is recorded in ",(0,s.jsx)(n.a,{href:"./administration#audit-logs",children:"Audit Logs"})," \u2014 which feature made the call, which model, timing, and a ",(0,s.jsx)(n.strong,{children:"hash of the prompt, never its full content"}),". The one exception is the Access Graph natural-language query, where the brief requires the actual question text and interpreted query to be logged in full (still alongside a separate hash-only entry for the underlying model call) so query interpretation itself is fully auditable."]}),"\n",(0,s.jsx)(n.h2,{id:"data-sent-to-the-model",children:"Data Sent to the Model"}),"\n",(0,s.jsx)(n.p,{children:"Because the runtime is local-only Ollama, nothing here ever leaves your network \u2014 but each feature is still deliberately scoped to send the minimum it needs:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Feature"}),(0,s.jsx)(n.th,{children:"Sent to the model"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Onboarding Assistant"}),(0,s.jsx)(n.td,{children:"Your question, the selected connector type, and matching sections of OrbisID's own documentation. Credential-shaped text is stripped before sending."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"General Help"}),(0,s.jsx)(n.td,{children:"Your question and matching sections of OrbisID's own user guide. Credential-shaped text is stripped before sending."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Access Graph query"}),(0,s.jsx)(n.td,{children:"Your question text only. Entity names are resolved to database records separately, after the model responds."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Identity linking"}),(0,s.jsx)(n.td,{children:"The account name and the shortlisted identities' display names \u2014 never raw account attributes or credentials."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"PAM inventory linking"}),(0,s.jsx)(n.td,{children:"The account name, its system's hostname/IP, and the shortlisted PAM records' account name/safe name/address \u2014 never credentials."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Account Type classification"}),(0,s.jsx)(n.td,{children:"The account name only."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Identity Type classification"}),(0,s.jsx)(n.td,{children:"The identity's full name, email, and whether it has an employee ID (not the ID value itself)."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Privilege Detection"}),(0,s.jsx)(n.td,{children:"The entitlement's name and type only."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Service Privilege Detection"}),(0,s.jsx)(n.td,{children:"The service's name, type, run-as account, command, and description."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Risk narrative"}),(0,s.jsx)(n.td,{children:"Computed KRI values/deltas and gap-analysis finding counts \u2014 never account-level or identity data."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Threat clustering"}),(0,s.jsx)(n.td,{children:"Detection rule names, system names, alert counts, and confidence scores \u2014 never raw event data."})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453(e,n,t){t.d(n,{R:()=>r,x:()=>o});var i=t(6540);const s={},a=i.createContext(s);function r(e){const n=i.useContext(a);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.