Skip to content
Back to the overview

Architecture

How Khidmitak works

For architects, engineers and security teams evaluating Khidmitak: where it sits, how it reaches your systems, and the controls that hold when an agent acts. Everything here describes the product as it is today.

Where Khidmitak sits

Khidmitak is one service with its own PostgreSQL database for platform state. It sits between the people and agents that ask and the systems that answer. Your business data stays in your systems and is reached live, through adapters.

People

AI applications

Agents

Khidmitak
  • Agent runtime
  • Tool registry & policy
  • Context & semantics
  • Identity & roles
  • Proposals & approvals
  • Activity & audit

Database adapters

MCP client

Model providers

Your systems

CRM · ERP · Finance · Internal databases · Line-of-business applications

Language models

How a request flows

  1. A person asks

    In their own words, in English or Arabic.

  2. Khidmitak resolves who is asking

    Their workspace, their role, and the tools that role allows.

  3. The agent reads

    Through adapters, read-only, with parsed queries, timeouts and row caps.

  4. Changes become proposals

    Stored with a hash and an expiry, waiting for approval. Nothing has changed yet.

  5. Approved actions run once

    Preconditions are re-checked, the change is applied, and everything is recorded.

Why this is hard

Connecting a model to a database takes an afternoon. These are the problems that appear once software acts inside real systems, on behalf of real people.

  1. Identity

    Whose authority is the agent using? It should be the person's own, scoped to their role, never a shared superuser.

  2. Permissions

    Reading is not writing. Every tool needs its own risk level and its own rules.

  3. Context

    Models need to know what the data means: which fields are sensitive, which tables matter, what “active customer” means here.

  4. Approvals

    Consequential changes need a person to see exactly what will happen, before it happens.

  5. Protocols

    PostgreSQL, REST, MCP, the ERP from 2009. Agents need one governed way in.

  6. Discovery

    New tools appear constantly. None should be callable just because it exists.

  7. Observability

    When something goes wrong, you need every step: which tool, which source, which parameters.

  8. Lifecycle

    Schemas and tools change. Decisions made against yesterday's version shouldn't silently carry over.

Connecting systems

A workspace can connect several systems. Each is reached through a database adapter, an MCP server or a model provider, and every connection passes through the same controls.

Database adapters
PostgreSQL today, through an adapter that uses separate least-privilege reader and writer credentials. Adapters are registered by kind, so new kinds of systems plug in behind the same contract.
Schema introspection
Khidmitak reads a source's structure (tables, columns, keys and relationships) into a versioned catalog with a fingerprint. Changes are executed only against the catalog version they were planned on.
Semantic layer
Teams add labels, descriptions and aliases to tables and fields, and mark which fields may be written.
Field classification
Each field can be public, internal, PII, sensitive or secret, and can be hidden from the model entirely.
MCP servers
Connected through the official MCP SDK. Tool lists come from an explicit discovery step, never from a network call on every question. Discovered tools start unclassified and blocked. Server hints such as readOnlyHint are never trusted, and a change to a tool's schema revokes its classification.
Model providers
Any OpenAI-compatible endpoint: a commercial API, a regional provider or a self-hosted model. Every call goes through the outbound network guard.

Tools and policy

The agent never calls a system directly. It calls tools, and every tool declares a risk level. Policy is evaluated on the server, fail-closed, on every single call.

Risk levelExampleWhat happens
ReadLook up accounts, describe a table, run a queryRuns immediately
WriteCreate a task, update a deal stageBecomes a proposal a person must approve
External side effectAn MCP tool that sends or triggers somethingBecomes a proposal a person must approve
DestructiveDelete anythingNever available to the agent
UnclassifiedA newly discovered MCP toolDenied until an administrator classifies it
Role defaults
Read tools are open to every role. Tools that change data are open to members and above, never to viewers. Each workspace can disable a tool or narrow its roles.
Tool families
For each connected source: describe, query, propose an insert, propose an update. Purpose-built tools for the CRM vertical (nine that read, five that change data). Classified MCP tools. Built-in utilities for arithmetic, date differences and currency conversion.

Reading data

Reads are defended in layers, so no single mistake can turn a read into a write.

A real PostgreSQL parser
Model-written SQL is parsed by libpg-query, PostgreSQL's own parser compiled to WebAssembly, so it is validated exactly as the database will interpret it.
Fail-closed rules
Exactly one plain SELECT. No data-modifying CTEs, no SELECT … INTO, no locking clauses. Functions must be on an allowlist of side-effect-free built-ins. Every table must belong to the source's catalog, which also blocks probing pg_catalog and information_schema.
Bounded execution
Every read runs in a REPEATABLE READ, READ ONLY transaction with a statement timeout (10 seconds by default) and a cursor-enforced row cap (500 rows by default), and is always rolled back.
A separate reader credential
Reads use their own credential. We recommend, and the demo uses, a database role that is read-only at the database level.

Changing data

Tools that change data can only propose. Execution is a separate step, triggered by a person.

Proposals, not actions
A side-effecting tool drafts the change (operation, record, fields and values), and Khidmitak stores it together with the current values of the fields it touches. Drafting changes nothing.
Integrity and expiry
Each proposal is sealed with an HMAC over its canonical content and expires (after 15 minutes by default). Approval must present the proposal's ID and the hash the person was shown.
Who can approve
Members can approve their own proposals; managers and above can approve anyone's. The agent has no way to approve.
Exactly once
Approval claims the proposal with a conditional pending → executing update, so concurrent or repeated approvals can't run it twice.
Re-checked at execution
Inside a transaction, the target row is locked and compared with the values recorded at proposal time. If anything changed, or the source's schema changed, execution stops. Each change must affect exactly one row.
Atomic batches
A multi-record proposal (up to 200 changes) runs in one transaction: all or nothing.
No delete
There is no delete operation anywhere in the agent's path. Records are updated or archived, and the writer credential needs no DELETE or TRUNCATE privilege.

What the model sees, and what it costs

The model works through tools, so it only sees what a question needs. The same design keeps usage small and predictable.

No data in the prompt
The system prompt holds the workspace name, the date, the user's role, the list of connected sources and the rules. No customer records.
Filtered tool results
Before a result reaches the model, hidden and secret fields are removed, PII and sensitive fields are masked unless the workspace allows them, and anything credential-shaped is redacted. Results carry their source.
Hard limits per question
At most six model calls per question, each tool result capped at 12,000 characters, and the last 30 messages of a conversation as context. Earlier tool outputs aren't replayed.
No retrieval layer, no background agents
Khidmitak has no embeddings or vector store, and no agent runs between questions. Workspace insights are computed by rules, not by a model.

Identity and access

Sign-in
Email and password (at least 12 characters) through Better Auth. Sessions last seven days and revocation takes effect immediately.
Browser sessions
HttpOnly, Secure, SameSite=Lax cookies. No tokens in browser storage.
Roles per workspace
Owner, admin, manager, member and viewer, checked on the server for every request. There is no global role and no automatic promotion.
Workspace isolation
Every query on workspace data is filtered by workspace. Another workspace's records are indistinguishable from missing ones.
Request forgery
Requests that change state must come from a trusted origin and carry a JSON body.
Rate limits
Sign-in attempts and public forms are limited per client IP; chat messages and approvals per user.

Credentials and outbound connections

Encrypted credentials
Database passwords, API keys and MCP tokens are encrypted with AES-256-GCM. Configuration rows hold only a reference.
Write-only
Credentials can be set through the API but never read back, and they never reach a model, a log or the audit trail.
Outbound network guard
Every connection to a configurable endpoint (model provider, MCP server or database host) is checked: HTTPS only for web endpoints, and a host that resolves to a private, loopback, link-local or cloud-metadata address is refused unless an operator explicitly allowlists that host.
No DNS rebinding
The validated address is the one actually connected to. Redirects are re-validated (three at most), and responses are capped at 2 MB and 30 seconds.
Egress allowlist
Outbound connections can optionally be restricted to an explicit list of hosts.

Audit and observability

Append-only audit trail
Proposals, approvals, executions, rejections, and membership and configuration changes are recorded in an audit table that a database trigger keeps append-only. Entries hold identifiers and field names, never full records or secrets.
Agent run trace
Every answer records each step: the tool, the policy decision, the duration, the arguments, and the source the data came from.
Activity feed
One timeline for human edits, agent runs, approvals and system events.
Source health
Connection tests record each source's health and last error.

Deployment

Two planes
Khidmitak's own state (workspaces, users, policies, proposals, audit) lives in its PostgreSQL database. Your business data stays in your systems and is queried in place, never bulk-copied. Conversation history keeps the answers that were shown.
A standard container
One API container plus PostgreSQL, with no dependency on a specific cloud, so it can run where your policies require.
Explicit migrations
Schema migrations are a release step, never run at startup.
Your model
Point it at the model provider of your choice, including a self-hosted one.