Security and compliance
Thulpar’s own security, the GR-* control catalogue, evidence packs, the regulatory crosswalk, red team, retention and deletion, vulnerability disclosure.
Updated: October 2026The product’s own security
Thulpar stands in front of the organisation’s most sensitive traffic, so its own security posture is part of the product: where it connects, what it stores, how it proves who it is and the defaults it ships with.
- Zero egress
- No telemetry, licence ping, remote generation or crash report. The one outbound connection is model download, only when the host explicitly allows it, an administrator picks a model in the panel, and only to allow-listed hosts. The no-egress gate in CI verifies on every PR that the product source carries no telemetry SDK or model-vendor host.
- Supply chain
- Every image is built on native runners for amd64 and arm64, published to GHCR by digest, carries an SBOM per architecture and is signed keyless with cosign. Third-party images come from the vendor’s mirror with byte-identical digests. Every checksum file is signed; the kit verifies its own signature.
- Licence
- An Ed25519-signed document; the verification keys compiled into the image; signing in a single reviewer-gated workflow. Clock rollback is refused; transaction metering is chained into the ledger; the document may bind to the installation id.
- Identity
- The organisation’s OIDC provider for people; local accounts + TOTP as break-glass. Tenant-bound keys for callers, authenticated from the headers before the body is read. SPIFFE SVIDs for workloads; optional mTLS api → detectors; XFCC only from named proxies.
- Safe defaults
- Production-safe templates, every secret generated, a one-time bootstrap token, no session before the first administrator. Security rails closed; the sector templates’ critical rails locked. Tenant isolation on every table; a foreign row is 404.
- Isolation
- File analysis in a separate child process per file with memory and time limits; YARA’s format modules only there; Semgrep in its own process group without network; the detector sidecar optionally under gVisor. Containers with a read-only root, non-root, capabilities dropped.
- Logs and data
- No raw content in logs: pino redacts; the ledger stores hashes instead of content; the redacted sample is at most 2 KB and deleted at the end of retention. Unless a tenant pack opts in, no prompt is written to disk in plain text.
The GR-* control catalogue
The catalogue has 26 controls in 19 families (injection, tool calls, information flow, exfiltration, personal data, system prompt, output, execution, identity, tenant isolation, memory, agent to agent, resource limits, content, transparency, logging, red team, incident, governance). It is generated from the product’s own code: the same table the evidence packs are written from.
- Every control carries the rails and built-in features that implement it (ledger, approvals, signing, export, red team), its OWASP LLM / Agentic / MCP and MITRE ATLAS counterparts and seven regulation columns.
- Every finding carries a control id; the console and the evidence pack lead from the finding to the control and from the control to the article.
| Status | How it is judged |
|---|---|
| implemented | The control’s rails are in enforce in the effective pack and were served by a detector throughout the period (or the built-in feature is configured and used) |
| partial | Rails in shadow, some off, or not served for part of the period; skipped rails are listed with their posture |
| not_configured | The pack has no rail or feature for the control; the evidence pack says so explicitly |
Evidence packs
An evidence pack is a signed ZIP per tenant, period and profile that answers the auditor’s question: which policy version, which detector, which decision. It is requested from the console or the API, written to a local volume or an S3-compatible store, and can be scheduled. The auditor verifies it with the installation’s public key, without internet.
| Profile | Basis |
|---|---|
| kvkk | 6698 Art. 4, 6, 9, 12; the Generative AI, AI at Work and Agentic AI guides |
| bddk | Information Systems Regulation Art. 13, 25, 27; Banking Law Art. 73; audit-trail section |
| seddk | Insurance and Private Pension Internal Systems Regulation |
| public-tr | Circular 2019/12; the Information and Communication Security Guide; classification; 5-year retention |
| eu-ai-act | Art. 9, 12, 14, 15, 50, 72–73; Annex IV technical documentation section |
| iso-42001 | Annex A control evidence; the 42005 impact-assessment context |
| dora | Art. 9 ICT risk; Art. 17–20 incident classification section; TLPT-aligned red-team report |
| File | Content |
|---|---|
| manifest.json / manifest.sig | The pack’s identity: format, tenant, profile, period, policy and detector versions, anchors, the chain verification result, every file’s SHA-256; Ed25519 signature |
| controls.md / controls.json | The catalogue’s profile column: every control’s status, its rails (mode, locked, served, findings, skips) and features |
| summary.md / summary.json | Counts by kind, stage, decision, category and rail; rails skipped; shadow decisions; approvals |
| decisions.jsonl | Every event of the period in the contract’s shape, with its hash and the redacted sample while retained; never raw content |
| chain-verify.txt | Event count, head hash, the period’s first and last hashes, anchors |
| approvals.jsonl | The period’s approvals: who, when, four eyes, SLA, expiry |
| policy-versions/ | The pack documents in force: content hash, signer, signature |
Regulatory crosswalk
| Framework | What Thulpar addresses |
|---|---|
| KVKK 6698 | Art. 6 special categories (the health rail flags them separately), Art. 9 cross-border transfer (egress and sink labels), Art. 12 security and the 72-hour notice; the Generative, At-Work and Agentic AI guides. |
| BDDK | Information Systems Regulation Art. 13 audit trail (the ledger), Art. 25 locality and system security (on-prem, no egress), Art. 27 outsourcing; Banking Law Art. 73 customer secrecy (the PII and sink rails). |
| SEDDK | The Insurance and Private Pension Internal Systems Regulation: information systems security, authorisation, segregation of duties (four eyes), incident management. |
| Public sector · 2019/12 | Circular 2019/12 and the Information and Communication Security Guide: data locality, application security, policy management, the 5-year retention floor; the air-gapped install. |
| EU AI Act | Art. 9 risk management (signed packs), Art. 12 automatic logging (the ledger), Art. 14 human oversight (hold and approval), Art. 15 accuracy and robustness (detectors, red team), Art. 50 transparency (the AI notice); Annex IV technical documentation. |
| ISO/IEC 42001 | Annex A control evidence: policies and procedures, data management, human oversight, logging; context for the 42005 impact assessment. |
| DORA | Art. 9 ICT protection and prevention, Art. 17–20 incident classification and reporting, ICT third-party risk; a TLPT-aligned red-team report. |
Red team
Nine suites run with the Turkish pack, promptfoo, PyRIT and garak against the check API (every stage), the gateway or a customer endpoint; they measure the attack success rate per category and the over-refusal rate on benign samples. Results are written to the ledger as benchmark events bound to a policy version; the console shows drift. The nightly run executes and publishes every suite.
| Suite | Stage | What it measures |
|---|---|---|
| tr-injection | input | Direct Turkish injection and jailbreak ASR |
| tr-benign | input | Over-refusal FPR per language (the TR banking benign set, the NotInject control) |
| indirect | retrieval, tool_result | Indirect injection ASR; FPR on clean documents |
| jailbreak-tr | input | Jailbreak ASR (XL-SafetyBench Türkiye) |
| exfil | output | Markdown image, link and tracking-pixel exfiltration patterns |
| tool-abuse | tool_call | Abuse derived from the banking pack’s tool groups: payments over the limit, PII to messaging, exports, shell, metadata addresses |
| promptfoo-redteam | input | promptfoo’s static and generated attacks |
| pyrit-xpia | retrieval | PyRIT’s cross-prompt injection workflow over the Turkish indirect documents |
| garak-nightly | input (gateway) | garak probes against the gateway |
- Gates: GR-RT-01 direct ASR at most 5 %, indirect at most 10 %, tool abuse and exfiltration 0 %; GR-INJ-03 over-refusal at most 3 % Turkish, 5 % English; error rate at most 5 %.
- The activation block: a pack that sets policy.requireBenchmark cannot activate without a published run whose gates passed. Publishing needs a redteam-scoped key only a SUPER_ADMIN mints.
- A detector that blocks benign Turkish text counts as a regression; the over-refusal rate is a CI gate.
Retention and deletion
The hash chain stays; the content goes. Redacted samples are deleted at the end of the effective pack’s retention without touching the chain and a purge event is written; events, hashes and sample references stay and the chain verifies unchanged. Retention is set in the tenant pack and cannot fall below an installation-wide floor: KVKK Art. 7 requirements together with the sector floors (BDDK and public sector 5 years, defence 10 years).
- Tenant offboarding is one command and cannot be undone: the tenant disabled, API keys revoked, every redacted sample and approval note erased at once whatever the retention says, a purge event and an anchor right after it, the whole chain verified.
- The output is a certificate of deletion signed with the installation’s signer key: installation and tenant id, when and by whom, the actions taken, the hashes of the purge event and the anchor, what remains (content-free events, earlier evidence packs and backups); a statement in Turkish and English.
- The final export first: evidence packs for the tenant’s whole period and the raw event list, handed over with the signer key’s public half through separate channels.
thulpar-admin offboard tnt_acme --confirm tnt_acme > deletion-tnt_acme.json
# tenant disabled · 4 keys revoked · 12 840 samples and 37 approval notes erased
# purge evt_01J… · anchor anc_01J… (root 9f3c…) · chain verified · certificate signed Vulnerability disclosure and disclaimer
If you find a vulnerability, write to security@thulpar.com; ask for an encrypted channel when the report is sensitive. We answer within 72 hours and support coordinated disclosure. Include the version, the install profile and method, what an attacker needs, the steps and the impact; never send real personal data or a customer’s content. A bypass of a control the product promises (a closed rail letting content through, a licence or tenant boundary crossed, the chain altered undetected, egress at run time) is at least high severity.