Knowledge - edmozley/freeitsm GitHub Wiki
Knowledge
Folder: knowledge/
๐ Articles can be published to customers. The self-service Help Centre shows articles marked Analysts and signed-in customers. Every article starts as analysts-only.
Colour: Purple #8764b8
Rich-text knowledge base with AI chat and vector search. Articles are written in TinyMCE, organised by tags, and searchable both with traditional full-text search and semantic similarity via embeddings.
Who can see an article
Two settings in the editor, next to Owner. They answer different questions, and you need both.
Who can see this โ the audience:
| Setting | Who reads it |
|---|---|
| Analysts only | Your team. The default for every article, including ones written before this setting existed. |
| Analysts and signed-in customers | Shown in the self-service portal's Knowledge section โ signed-in requesters can search, browse and read these articles; they also appear as popular articles on the portal dashboard and power ticket-deflection suggestions. Their documents can be downloaded there too, unless a document is set to Hidden (3.7.0 - see Documents on an article). |
| Anyone, including website chat | The web chat widget's AI can answer visitors from it. Only choose this for things you would happily show a stranger. |
Company (only appears if you have more than one) โ leave it shared with all companies for anything generic ("how to reset your password"), or pick one company and only that company sees it.
The two are independent on purpose: scoping an article to a company still hands it to that company's anonymous website visitors unless the audience says otherwise.
Why has my chat widget gone quiet? Because every article defaults to Analysts only, so after upgrading, the widget's AI has nothing it is allowed to use. Mark a few customer-facing articles public and it starts working again. The default is deliberate โ an upgrade must never start showing internal runbooks to the public.
Articles in the recycle bin are never used by the chat AI either, nor is anything unpublished. The LMS can only build lessons from shared articles, because a course has no company and is shown to every learner.
Folders
Articles are organised into folders, one folder per document, so there is always a single honest answer to "where is it?". Drag a document onto a folder to file it; Ctrl-drag to leave a shortcut instead. Folders can be nested, and dragging a folder takes everything inside it.
Home shows what is filed at the top level, plus the folders โ not every article you own, any more than opening a disk lists every file on it. Searching and tag filters still look everywhere, and say which folder each result came from.
The main pane offers four views โ List, Cards, Tree and Details โ remembered per analyst. Documents sort alphabetically with folders above them.
Several articles can be ticked and then moved into a folder or given a new audience in one go. A plain click always opens a document, so the tick box is the selection mechanism; Shift and a tick takes a range, and the arrow keys, Space, Ctrl+A and Escape all work.
โ Knowledge โ folders and security
Permissions
Beyond the audience above, a folder or an individual document can be restricted to named analysts, teams or portal users.
Every folder and every document is either Open โ the list is who is shut out โ or Restricted to chosen people, where the list is who is let in. The list means the opposite thing in each, which is the one thing to understand before using it. Because an object is only ever one or the other, an access list cannot contradict itself: there is no allow/deny precedence to learn.
By default a document inherits the same permissions as the folder above. Permission exceptions in the left panel lists everything that does not, because an exception you cannot see is one nobody will ever audit.
Whether restricting a folder protects what is inside it is an install-wide setting โ folders are containers (the default) or folders are filing โ under Knowledge โบ Settings โบ Permissions, with a preview of how many document readings the change would gain or lose.
The same rules apply to analysts, the self-service portal, the AI assistant, the website chat and the REST API. An administrator can always read anything, and every use of that floor is recorded separately from ordinary reads.
โ Knowledge โ folders and security ยท Developer Guide
Attached documents
Files and links can be attached to an article โ the manuals, procedures and PDFs an article refers to. The article lists them; adding and removing lives in the editor, because reading an article is not editing it.
Editing
- TinyMCE editor with the full toolbar (formatting, lists, tables, links)
- Full screen (button beside Save, desktop only) - just the editor, filling the whole window with nothing else on screen. Press Esc to come back, or use the full-screen button at the end of the toolbar
- Tag-based organisation โ assign multiple tags per article
- Article versioning โ save as a new version to archive the previous content with full version history
- Article archiving with a recycle bin (soft delete, restore, configurable auto-purge after N days)
Search
- Full-text search on title + body across all active articles
- Tag filtering in the sidebar
- Vector / semantic search โ articles are auto-embedded via the OpenAI Embeddings API on save; queries find conceptually related articles even when the words don't match
Ask AI
AI chat panel powered by your chosen provider โ Anthropic Claude, OpenAI, or any model via OpenRouter (see AI Providers). The user asks a question; the model searches the knowledge base via vector similarity, picks relevant articles, and answers grounded in those articles' content. Sources are cited so the user can verify and read deeper.
Also accessible from the Tickets reading pane via the Ask AI button โ useful when triaging an unfamiliar incident.
Assistant
Reads your closed tickets and reports what the knowledge base is missing โ "I read 340 closed tickets from the last 90 days. Your knowledge base is missing six things." Each finding is a question the desk has answered repeatedly with no article covering it ("Cannot open shared mailbox in Outlook โ asked 14 times"), with the tickets attached as evidence.
Draft writes the article, streaming as it goes โ and it is allowed to say no. A ticket recording only "reset password, asked user to log in again" is refused rather than padded out, because a knowledge base full of padding teaches people to stop searching it. When it refuses it asks two to four specific questions about that ticket; answer them and it writes the article from your answers.
Drafts always land unpublished โ nothing AI-written reaches the portal, the web chat or the AI answers until a human publishes it.
The same judgement is available from a solved ticket via the Write up button in the Tickets reading pane.
Finding the gaps works with no AI spend at all (it matches on wording rather than meaning); only drafting needs a model, and it reuses the Ask AI provider above.
โ Knowledge Assistant ยท Knowledge Assistant โ Developer Guide
Review Workflow
Articles can be flagged for periodic review (e.g. "check this once a year"). The Watchtower attention card surfaces articles whose review date has passed.
Email Sharing
Articles can be emailed externally via the configured mail provider โ handy for sharing a how-to with a user when closing a ticket.
Settings
- Email settings: SMTP / Graph configuration for outbound article emails
- AI settings: provider / model / key for Ask AI (Anthropic, OpenAI or OpenRouter โ see AI Providers), plus a separate OpenAI API key for embeddings (semantic search)
API keys are encrypted at rest and masked in API responses.
Help
Interactive guide at knowledge/help.php covering article creation, review workflow, Ask AI, search and navigation, sharing and export. Scroll-spy sidebar.
Key Tables
| Table | Purpose |
|---|---|
knowledge_articles |
Core article record โ including tenant_id (owning company; NULL = shared with all) and audience (internal / customer / public) |
knowledge_article_versions |
Version history with archived content |
knowledge_article_tags |
Many-to-many tags |
knowledge_tags |
Tag definitions |
knowledge_embeddings |
Vector embeddings for semantic search |
For developers
โ ๏ธ knowledge_articles.tenant_id IS NULL means "shared with EVERY company" โ the opposite of what NULL means for tickets, assets and changes, where it means "belongs to the Default company". Consequently Knowledge must never use the shared scoping helpers:
| Don't use | Use instead | Why |
|---|---|---|
activeTenantFilter() |
knowledgeTenantFilter() |
The generic one only shows NULL rows while Default is the active company โ every shared article would vanish for every other company. |
apiKeyTenantFilter() |
apiKeyKnowledgeFilter() |
Same trap on the REST side. Its docblock even says "for tickets, problems, and any future tenant-scoped module" โ Knowledge is the exception. |
The SQL looks nearly identical, the meaning does not, and getting it wrong fails silently: no error, tests green, an MSP's generic articles just quietly disappear for most clients. Both correct helpers carry loud docblocks.
Other notes:
audienceis an ordered ladder (internalโcustomerโpublic), not a flag per channel. A reader declares its own rung and sees everything at or above it. Values areAudience::constants (includes/knowledge/audience.php) for the same reason asCap::โ a typo that silently matches nothing is a disclosure, not a bug.- Why a ladder and not a flag per channel: the readers aren't peers โ they're degrees of trust, and a web chat visitor is anonymous (they typed a name and an email; neither is verified). Per-channel flags would allow eight combinations, most of them nonsense ("visible to web chat but not analysts"), and each new channel would mean another column plus a retroactive decision about every existing article. "Self-service yes, web chat no" is simply
customer. - Migration was free and fails safe:
tenant_idNULL = shared is exactly the pre-multi-tenancy behaviour, so nothing needed backfilling;audiencedefaults tointernal, so running Database Verify can never start disclosing existing articles โ authors opt in per article. Both filters are no-ops at N=1 and on installs that haven't migrated yet. - Reads are filtered in SQL before scoring (
includes/knowledge/kb_ai.php) โ the security boundary, and cheaper than decoding vectors you'd discard.kbRetrieveArticles()defaults to the most restrictive rung so a careless caller gets too little, never too much. - Embeddings encode
title + bodyonly, so ownership isn't baked in โ changing either column needs no regeneration. fk_knowledge_articles_tenantis deliberately notON DELETE SET NULL(unlikefk_assets_tenant): NULL means shared here, so SET NULL would promote a deleted company's private articles into everyone's.- The service layer unified writes, not reads โ one place to write these columns, ~20 hand-rolled SELECTs to filter. Adding a new reader? Add the filter, and a case to
tests/knowledge-visibility/. php tests/knowledge-visibility/run.phpโ 88 integration checks (dev installs only).- Folders and the access model have their own page: Knowledge โ folders and security: Developer Guide. The short version:
includes/knowledge/visibility.phpis the one choke point,knowledgeCanRead()is built on the same clause the list uses so the two cannot drift, andknowledge_aclhas no allow/deny column โ polarity lives on the object, which is what makes a contradictory list unstorable.
On a phone
The knowledge base is one of the modules built to work properly on a phone. Search sits in a bar across the top of the article list rather than behind a menu, the tag filters move into a panel of their own, and an article's content โ wide screenshots, tables, code blocks โ is contained so it can be read without the page falling apart. An article's own actions โ Share, Move, Permissions, Edit and Archive โ sit in a row of icons pinned to the bottom of the screen, where a thumb is. Nothing changes on the desktop. See Mobile: Knowledge.
Domains (3.0.0)
An article can be a runbook for one or more domains - how to move a domain's DNS, how it is renewed, who to call. Link them in the article's editor (with its documents); readers see the linked domains listed under the article, and nothing when there are none. The domain's own Connections tab lists its runbooks too. Shown only to analysts who can open Domains. See Domains โ Connections.