secure-minimal-agent
A small, public, provider-agnostic reference agent that shows security and correctness disciplines in as little code as possible, with its safety claims pinned down by tests.
Problem
Business-automation agents are often built as open-ended loops that trust model output, let tool results act as instructions, do arithmetic in the model's head and emit answers nobody has checked. That is how prompt injection, invented numbers and silent failures reach production.
Goal
A minimal, production-structured reference agent that shows the security and correctness disciplines in as little code as possible, and stays independent of any one model provider.
My role
Sole author: design, implementation, tests and documentation.
Solution
A four-phase loop (plan, execute, answer, self-validate) in which every boundary is a typed schema, tools are reached only through a deny-by-default registry, all numbers come from deterministic tools, and a critic pass with a bounded revision loop must accept the answer before it is emitted. If it does not, the output is flagged loudly as not validated.
How it works
The planner breaks the task into at most ten schema-validated steps, using only tools from a catalogue generated from the registry.
For each tool step, an executor binds the tool's input against the evidence gathered so far, so a later step can reuse an earlier value.
Every call goes through one choke point that resolves the tool name in code the model cannot influence, validates the input against the tool's schema, refuses side-effecting tools unless writes are explicitly enabled for the run, and wraps success or failure in a uniform result envelope. A tool error is data, not a crash.
Task text and tool results always travel inside labelled data fences that the system prompts treat as data, so an instruction hidden in a task or a tool result stays inert.
The answer stage may only copy numbers from tool results, and must list caveats instead of computing.
A critic checks the draft against the evidence and may demand a revision only for demonstrable defects. After two revisions it stops and appends a clear "did not pass validation" caveat.
Every phase is appended to a JSON-lines audit log that never contains secrets.
Arithmetic uses a calculator that parses expressions into a syntax tree and evaluates only allowlisted node types, with no eval, and the one network tool can reach a single pinned host.
Technical challenges
Making prompt injection structurally harmless rather than filtered.
Keeping the model out of money math entirely.
Tuning the critic to reject real defects without looping on style.
Binding multi-step tool inputs to earlier evidence.
Schema retries that feed the validation error back to the model.
Keeping the core independent of any vendor SDK.
Capabilities
- Task decomposition into validated steps
- Allowlisted, schema-validated tool calls
- Read-only by default, with an explicit write gate
- Exact arithmetic tool
- Live exchange-rate lookup against one pinned host
- Self-validation with bounded revision
- JSON output with a fixed structure
- Append-only audit trail
- Switchable model providers
Technology
Impact
A public, readable reference for secure agent structure whose safety claims are pinned by tests anyone can run: unknown tools, writes without an explicit opt-in and malformed inputs are refused; a failing tool comes back as data instead of crashing the run; the calculator rejects names, imports and oversized expressions; and plans, currency codes and validation verdicts are held to closed schemas. It doubles as a code sample and a teaching example of injection-resistant, auditable agent design.
Skills demonstrated
- LLM application security
- Agent architecture
- Typed interfaces and validation
- Safe expression evaluation
- Audit trails
- Provider abstraction
- Clean, well-commented Python