Technical walkthrough
This page follows one piece of work from the moment your AI drafts it until it's in a signed export that someone outside your company can check. For each step we say where it runs, and we name the signing algorithm wherever something gets signed. It's written for the security architect who'll be asked to approve Kanonik.
1. Your AI connects over MCP, and its model runs on your own provider account
Your AI client connects to Kanonik over MCP, the protocol AI clients use to call outside tools. It works with MCP clients that support OAuth sign-in, such as Claude, ChatGPT and Cursor, and Kanonik is the MCP server. The client signs in with OAuth, using PKCE. You choose the model behind your client and it runs on your own provider account. Kanonik never calls that model, and it never sees or stores your keys. You can switch AI providers and keep your record.
Every call goes through Kanonik's MCP gateway, and every tool is registered through the same gateway checks. Before any tool runs, the gateway checks who's calling, which workspace they're in and what they're allowed to do, and it applies rate limits and retry protection. A call without the right permission gets an error. The gateway also records the call and the response in your record.
The gateway publishes OAuth protected-resource metadata (RFC 9728). Your client reads it and finds the authorization server on its own, so nobody has to paste settings into the client.
Example
{
"resource": "<gateway URL>",
"authorization_servers": ["<authorization server URL>"]
}2. Your AI loads Kanonik's skills when it connects
When your client connects, it loads Kanonik's skills. A skill is a set of plain-text instructions that tells a general-purpose model how to do compliance work in Kanonik. Our build rejects anything in a skill that isn't plain text. Loading a skill doesn't give the model any permission it didn't already have.
Kanonik records every skill load: which skill and version, a hash of the exact instructions it served, and whether its signature checked out. Anyone reading the record later can see which instructions were in play when a proposal was written. The Verifier's own prompts are kept separate from the skills, so no skill can influence how the Verifier grades work.
3. Your AI reads your systems with the access it already has
When you ask your AI to look at a repository, a cloud account or a contract, it uses the access you've already given it and sends Kanonik what it found. Reading doesn't change your compliance record. Nothing your AI found counts until it's proposed and approved.
Kanonik only gets the compliance material your AI drafts from what it found. Kanonik doesn't connect to your systems, and it doesn't hold any credentials for them.
4. Nothing your AI proposes goes into the record until someone approves it
Each kind of entry has its own typed tools, so there are separate tools for controls, evidence, risks, vendors, mappings, questionnaire answers and so on. Calling one of them creates a proposal, and the record doesn't change until someone approves it. Every commit tool supports a dry run. Every call that changes something carries an idempotency key, so a retry can't write the same thing twice.
Your AI can have a batch checked before anyone is asked to approve it, and fix what didn't pass. You only get an approval link once the batch is ready.
5. The Verifier checks every proposal before it's recorded
The Verifier runs on Kanonik's servers as part of the commit path. It isn't exposed as a tool, so the model can't call it for a second opinion and can't go around it.
It checks each proposal twice. The first check is fixed code. It rejects proposals that break a hard rule, and flags ones that look like a weak fit, without asking a model. The second check is a model review against your record. It returns a verdict and its reasons.
Kanonik combines both checks into one outcome: approved, rejected or sent to a person. The Verifier fails closed. If the model review is unsure or can't be completed, the proposal goes to a person and is never applied on its own. Approved only means the Verifier is satisfied. A person still has to approve it in the web app.
Every verdict records what it was based on, including the model and the version of our instructions, so a change to either means a fresh check. The Verifier's model runs on Kanonik's own account, not yours, and its cost is included in the plan price.
Example
outcome <APPROVED | REJECTED | HUMAN_REVIEW> model <model> prompt_hash <sha-256>
6. A person approves in the web app, using a signed token that only works once
A proposal that passes the Verifier waits for a named person to approve it in the Kanonik web app. The approval uses a token signed with ECDSA P-256 by a managed signing service, so the private key never leaves it. The token is bound to a SHA-256 hash of the proposal exactly as the approver saw it. It expires within an hour and can only be used once.
Your AI gets a short link and hands it to you. The link only works for someone signed in to Kanonik. The signed token behind it never shows up in a tool result or an error message, so the model never sees it. A test in the build checks every commit and finalize tool to make sure none of them returns the token. The reviewer can approve, or send the proposal back to your AI with a reason. Once it's sent back, the link can't approve that item anymore.
The token carries two names: who made the proposal, and who's allowed to approve it. When the link is used, Kanonik checks again that the person using it is allowed to approve.
7. How separation of duties works, including when you're the only approver
Whether a second person has to approve depends on two things: the kind of record, and how many people in the workspace can approve. When there's a second approver, someone other than the author has to approve governance records such as policies, controls, exceptions and risk acceptances. The author can approve ordinary records such as evidence, vendors and questionnaire answers. This is how Kanonik applies ISO/IEC 27001:2022 Annex A control 5.3, segregation of duties.
In a workspace with only one person who can approve, that person can approve any kind of record. The record then includes a self-approval exception that notes how many approvers there were and the person's role at the time. The app shows it as "No second reviewer on this workspace." So an auditor can see that there was nobody else in the workspace who could have approved it.
The export checker tests approvals against these rules too. A self-approval without a matching exception fails. One with a recorded exception passes, with a note.
8. Approved work is added to a hash chain, and the head of the chain is signed
Each approved item is added to the record as an event. Each event's hash is a SHA-256 over the event and the previous event's hash. That links every event in a workspace into one chain. The database blocks updates and deletes, so a correction goes in as a new event that points back to the old one. The database also refuses a second event with the same idempotency key in the same workspace.
The head of each chain is signed with ECDSA P-384 over SHA-384. The signing key is held in a managed secrets engine and never leaves it. Kanonik signs the chain head on a schedule, and again when an audit period is finalized. Each committed entry also stores the Verifier's verdict and the approval behind it.
Example
prev_hash <sha-256> event_hash <sha-256> signed_at <time> signature <ECDSA P-384 signature>
9. Every entry has two dates: when it took effect and when Kanonik recorded it
We call those two dates the valid time and the system time. The valid time is when the control, vendor or answer was in place. The system time is when Kanonik recorded it. That's what's usually called a bi-temporal record. You can run a read as of either date. "What did we have in place on 1 March?" and "What did our record say on 1 March?" are different questions, and auditors usually ask both. Your AI can ask them too, through read tools that take an as-of time.
If you correct something later, the correction is a new event with a new system time. A read as of the earlier system time still shows what the record said back then.
Example
# what was in place { "as_of_time": "2026-03-01T00:00:00Z" }
# what the record said { "system_as_of_time": "2026-03-01T00:00:00Z" }
10. Anyone you share an export with can verify it offline, without a Kanonik account
Proof Snapshots and Sealed Audit Packages are both exports. Both contain the events, the signed chain head and the export checker. The checker is a set of verification scripts that comes in Python, in JavaScript and as a single HTML page.
The checker runs on the recipient's own machine with no network connection. It recalculates every event hash and checks the chain against the signed head. It also checks that every approved item has a passing verdict from the Verifier and that nobody approved their own work without a recorded exception. Last, it compares each verdict's prompt hash with our list of released prompt hashes. The prompt text itself isn't published.
The check shows the export hasn't changed since it was signed. If the machine doesn't have the Python cryptography package installed, the signature check reports DEGRADED and says why.
Example
[ok ] hash_chain_integrity [ok ] chain_root_signature [ok ] verifier_verdict_presence [ok ] sod_separation_of_duties [ok ] skill_provenance [ok ] reproducibility_tuple_completeness [ok ] prompt_integrity [ok ] file_checksums Overall: PASS (pass=<n> fail=0 degraded=0) # status values: PASS, FAIL, DEGRADED
11. You can send a buyer the record for one answer instead of your whole export
When a buyer asks for the record behind a questionnaire answer, you don't need to send your whole export. You can send a single-record proof. That's just the one record, with its own signed checkpoint. It includes the entry, its two dates and both hashes, the Verifier's verdict, who approved it and on what basis, and whether it was still the latest version when you exported it. That last part tells the buyer whether the answer had already been replaced by a newer one.
The export checker has a single-record mode that shows the record hasn't changed since it was signed.
Example
kind <kind> canonical_id <id> # event valid_time <time> transaction_time <time> prev_hash <hash> event_hash <hash> # checkpoint signed_at <time> signing_key_id <key> signature <signature> # verdict outcome <outcome> confidence <confidence> model_id <model> prompt_hash <hash> # approval approved_by_subject <approver> approved_at <time> decision_basis <basis> # record is_latest_for_entity <true | false> exported_at <time> [ok ] record_event_hash [ok ] record_checkpoint_signature [ok ] record_verdict [ok ] record_approval [ok ] record_currency
Foresight: checking a planned vendor change against your promises
Your AI describes a vendor you plan to add or replace, with a go-live date, and Foresight compares the change with the promises and vendor facts you've already approved. Each promise comes back No conflict, Needs information, Conflict or Not applicable, with the facts it used and the answer sets that contain any promise in doubt. Foresight writes nothing to your approved record.
Example
- Conflict "We do not use customer data to train AI models"
- Promise made in: data processing agreement, section 3
What the change says: the vendor's terms allow training on conversations - Needs information "Customer data stays in the EU"
- What Kanonik needs: the region where the vendor processes data
12. Each workspace is kept separate, and the signing keys stay in a managed secrets engine
Every workspace's records carry a workspace id. Postgres row-level security is forced on the core record tables (events, entities and workspace settings), so it applies to the table owner too, not just to the application's database role. The application checks the workspace on every request, and some approval-workflow tables are isolated in application code only.
Every connection from the internet uses TLS 1.2 or 1.3, terminated at Cloudflare. Your data is encrypted at rest by our cloud provider (Oracle Cloud block storage, AES-256, Oracle-managed keys). Each workspace also has its own key in the managed secrets engine. Today it encrypts three fields: the workspace owner's email address, the addresses approval requests go to, and the proof-of-purchase reference on a framework license. The key never leaves the engine. Our services ask the engine to encrypt and decrypt. The record itself is protected by the provider's encryption and row-level security. Export your record any time before your subscription ends.
Behind the web app, Kanonik runs as a small set of services, each with its own database schema. They talk to each other over mutual TLS, and to the database over TLS. Calls to the secrets engine and the sign-in service stay on the private cluster network behind network policies but are not yet encrypted. The keys that sign approvals and the chain head stay inside the managed secrets engine, and the services ask it to sign.
Each framework is a versioned data package of requirements and controls. Kanonik works with SOC 2, ISO/IEC 27001, HIPAA, GDPR, NIST CSF 2.0, NIST SP 800-53 Rev. 5, NIST SP 800-171 Rev. 2, NIST SP 800-171 Rev. 3, FedRAMP Rev. 5 baselines, CCPA/CPRA, DORA, NIS2, NYDFS Part 500, EU AI Act, NIST AI RMF 1.0 and NIST SSDF. For ISO/IEC 27001:2022 and SOC 2, you bring a license for the standard's text, yours or your audit firm's. Adding a framework, or a new version of one, means adding a new data package.
Private or self-hosted deployment is available to enterprise customers. Kanonik is deployed as infrastructure as code, and we test the deployment with you. Talk to us about your requirements.
Glossary
- MCP
- the protocol your AI client uses to call Kanonik's tools. Kanonik is the MCP server. Step 1
- BYOM (bring your own model)
- you pick the model, and it runs on your own provider account with your own keys. Step 1
- Skill
- a bundle of plain-text instructions your client loads. Loading one doesn't give the model any new permissions, and every load is recorded. Step 2
- Proposal
- a typed tool call that doesn't write anything until someone approves it. Step 4
- Verifier
- the two checks (rules first, then a model review) that run on Kanonik's servers in the commit path. It isn't a tool, and it isn't the export checker. Step 5
- Approval token
- the signed token behind the approval link, signed with ECDSA P-256. Kanonik issues it when your AI submits a proposal, and a person's approval in the web app redeems it. It's tied to the exact proposal, expires within an hour and can only be used once. Step 6
- Separation of duties
- governance records need a second approver when the workspace has one (Annex A 5.3). Step 7
- Self-approval exception
- the sealed entry Kanonik records when the only person who can approve in a workspace approves their own AI's work. Step 7
- Event store
- the append-only store of events. Each workspace has one SHA-256 hash chain, and only the head of the chain is signed, with ECDSA P-384. Step 8
- Bi-temporal
- every entry has a valid time and a system time, and you can read the record as of either one. Step 9
- Export checker
- the scripts in every export that check its hashes and signatures offline. They come in Python, in JavaScript and as a single HTML page. Step 10
- Single-record proof
- one sealed record and its signed checkpoint, sent to a buyer who asked for it. Step 11
- No conflict / Needs information / Conflict / Not applicable
- the four answers Foresight gives for each promise. Foresight
- Tenant
- one workspace. Its records carry a workspace id, and row-level security on the core record tables keeps them apart from other workspaces. Step 12
- Framework package
- a versioned data package of a framework's requirements and controls. Step 12
Put Kanonik through your own architecture review
Connect the AI you already use and take one of its proposals all the way to a signed export in your own workspace.
Solo is $99 a month and starts with a 14-day trial.