mklang platform

Security

This platform holds other people's credentials and runs LLM-driven workflows over their business data. This page states what is guaranteed, what is not, and how to report a problem. It is the public form of the security document that ships in the repository, and it is kept narrower than that document on purpose: nothing here may claim more than the source it derives from.

Reviewed 2026-08-06. Phase 1 — one production host, no customer on it.

Invariants

Eight invariants are stated in the repository, and each is enforced by code and by named tests. An invariant with no test is an intention, and the distinction is drawn in the source document rather than smoothed over here.

Invariant What it means in practice
No credential is ever written unencrypted Envelope encryption with a per-tenant data key. If the key encryption key cannot be loaded, the service does not start — there is no fallback and no development mode that skips it.
No secret enters a model's context A step never receives a credential; the connector runtime resolves it at call time. What the language writes into a checkpoint is sealed before it reaches the column.
An unverified webhook starts nothing HMAC over the raw request body with the timestamp inside the signature, so a captured request stops working. A missing signature, a wrong one, an expired one and an unknown path are the same answer.
An absent credential is a denial No configuration makes authentication optional, and a test walks every registered route so a new endpoint cannot ship unprotected by omission.
Cross-tenant reads require two independent failures Application scoping and Postgres row-level security, forced. One of them being wrong is not enough.
Every connector response is external data Marked as a type rather than a label, before it can reach a judgement — so provenance and control-flow taint have something to act on.
Logging is allowlist-based A field a vendor adds tomorrow is redacted by default rather than logged by default, and the allowlist descends containers rather than blanking them.
An effect is claimed before the call and confirmed after An ambiguous claim stops the run. Durable execution is at-least-once, so this is what stands between a retry and a second email.

What is not defended against

Stated because a threat model without an out-of-scope list is a marketing document:

Where data sits

Class At rest
Credentials Encrypted under a per-tenant key
Step payloads and model context Encrypted under a key derived per tenant for the execution plane alone
Run metadata and audit events Database-level. Audit is append-only and kept longer than the rest

Hosting is in Germany. Every backup is verified before it is called good, restoring from it has been rehearsed on a throwaway host, and any copy that leaves the host is encrypted under a key the host does not hold.

Reporting a vulnerability

Report privately to info@gianlucamazza.it, with mklang platform security in the subject. Encrypted mail is welcome — ask in the clear first and a key comes back.

Please do not open a public issue, and please only test against something that is yours. There is a live host and it carries no customer; it is not an invitation.

The commitment, deliberately small enough to be true of a project this size rather than large enough to look reassuring.
Acknowledgement three business days
An assessment, with a severity and a decision ten business days
A fix, or a written statement of why not before any customer is exposed to the affected path
Credit if you want it

Reviewing us

A security review that asks to read the code is one of the two named triggers for publishing it. Ask, and that conversation starts rather than stalls.

Until then, one thing is worth knowing about the pages you are reading. Every factual statement on this site names a row in a register that ships beside the content, and each row names its evidence: a test that must still exist, a decision record, a phrase that must still appear in the security document this page derives from. The build fails when a statement outlives the thing it rested on, and it fails again when nobody has re-read a claim by the date on its row. Marketing prose rots quietly; this is the mechanism that stops these pages doing it between one review and the next.