All blog posts Blog

Our engineering principles

The decisions we want engineers to make when the specification is incomplete, the system is under pressure, or a safe shortcut does not exist.

Koreshield Engineering2026-10-318 min read

Principles are decision tools

Koreshield sits between untrusted text and systems that can expose data, contact customers, or change an account. That position makes ordinary engineering choices consequential. A convenient default can become an authorization bypass; a vague metric can become a false security claim; an unreadable failure can keep an operator guessing during an incident.

These principles describe how we make decisions when a ticket or design document cannot cover every case. They are not a finished rulebook. We expect to revise them when production evidence proves that one is incomplete or wrong.

Protect the request, not the demo

A convincing model response is not the unit we secure. The unit is the protected request: the input, retrieved context, proposed action, model output, policy decision, and evidence that connect one customer interaction to one outcome.

This keeps us focused on the real path through a system. A detector that performs well in a notebook but is skipped on one tool path does not protect that path. A dashboard that records an event after money moved did not prevent the movement. We design from the trust boundary and work outward to the interface, API, evidence, and operating procedure around it.

Treat text as untrusted at every boundary

Customer messages are untrusted. So are support tickets, CRM notes, retrieved documents, web pages, transcripts, model output, and tool arguments assembled from any of them. Internal provenance can help an investigation, but it does not turn text into trusted instruction.

We inspect content while the application can still decline, narrow, redact, exclude, or escalate it. The later a control runs, the fewer useful choices remain. Logging an unsafe action after execution is evidence of a failure, not an enforcement boundary.

Models propose; deterministic systems authorize

A model may propose an operation. It must not decide who the user is, which tenant owns a resource, whether consent exists, whether an amount is within a limit, or whether an approval was granted. Those facts come from authenticated server-side state and ordinary application code.

Koreshield adds a security decision about manipulation and unsafe context. It does not replace identity, tenant isolation, business rules, approval, idempotency, or execution controls. Keeping those responsibilities separate makes each decision explainable and prevents fluent text from manufacturing authority.

Evidence is part of the product

A decision without a reason is difficult to review, tune, appeal, or defend. Every protected request should leave enough structured evidence to answer what was checked, which mode and engine made the decision, what indicators mattered, how long it took, and which request the application should correlate with its own trace.

More evidence does not mean storing every conversation twice. We minimise persisted content, keep raw keys out of storage, scope access, and make request IDs the bridge between systems. Evidence must help the person investigating without creating a second archive of customer data.

Detect before enforce

We prefer staged enforcement over a dramatic launch. A new boundary starts in detect or shadow mode, runs against representative benign and adversarial traffic, and records what it would have changed. The team reviews misses, false positives, latency, evidence quality, and the fallback customers will experience.

Enforcement begins only when the integration is proven and the fallback is operable. Returning a boundary to detect mode is a normal rollback, not an admission that the control failed. It lets evidence collection continue while the policy is corrected.

Measure on data that cannot flatter us

Security metrics are easy to improve accidentally: test on training examples, count detections as blocks, omit ordinary support traffic, or tune a threshold on the same rows later reported as evidence. We design evaluations so those shortcuts are difficult.

Held-out and external data, frozen splits, pinned datasets, confidence intervals, false-positive measurements, latency percentiles, and explicit degraded states matter more than one large headline number. We publish limits because an operator needs to know where a control is weak before choosing what it may enforce.

Prefer small, reversible changes

Small changes are easier to understand, review, test, deploy, and reverse. We separate migrations, runtime behaviour, interfaces, and policy changes when that separation reduces the blast radius. We preserve rollback paths before changing production state, not after an incident begins.

Reversibility does not mean avoiding hard decisions. It means spending more care on one-way doors such as destructive migrations, public contracts, cryptographic formats, and irreversible data handling, while allowing reversible decisions to move at the speed of evidence.

Build for the person holding the incident

The clearest test of a design is whether someone unfamiliar with the change can understand it under pressure. Names should describe the domain. Logs should identify a request without exposing its content. Errors should say which layer failed and what can be tried safely. Runbooks should contain commands that match the deployed system.

Complexity has an operating cost. We accept it only when it buys a capability the product actually needs, and we document why it exists. Clever code that saves lines but hides the failure mode is usually a poor trade.

A merge is not a deployment

Passing tests and a merged commit are necessary evidence, not proof that customers received the change. Production work is complete only when we can identify the deployed revision, confirm configuration and migrations, exercise the affected public or authenticated journey, and inspect the relevant runtime evidence.

We use precise words for state: local, committed, pushed, merged, deployed, and live-verified. Collapsing those states into "done" creates false confidence exactly when a release needs clarity.

Run less technology

Every service, framework, model, queue, database, and vendor becomes something the team must understand during a failure. We first ask whether the capability can be built safely with the system already operating. New technology must earn its maintenance, security, deployment, observability, and recovery costs.

We reserve novelty for product problems where it creates a real advantage. Around those problems, mature and boring components often give us more room to reason clearly and move quickly.

Ownership follows the customer journey

An engineer owns more than the lines changed. Ownership includes the loading state before a request, the error a customer sees, the email they receive, the evidence an operator reviews, the documentation an integrator follows, and the recovery path when a dependency fails.

When something goes wrong, we examine the system that allowed it: missing tests, ambiguous ownership, weak review, unsafe defaults, stale documentation, or absent monitoring. The goal is not to find a person to blame. It is to make the next failure less likely and easier to contain.

Keep the principles alive

A principle that never changes can become ceremony. We want these statements challenged with incidents, customer evidence, evaluation results, and better designs. When practice and principle diverge, we should either fix the practice or explain why the principle no longer serves the product.

The standard is simple: protect the real request, preserve the reason for every decision, and be exact about what we have proved.

Sources and further reading

Koreshield integration guideMeasuring prompt-injection detection honestlySecurity evidence without a second archiveDetect first: rolling out AI security without breaking support