Provenance as a first-class tag
USER_INPUT, UNTRUSTED_CONTEXT and SYSTEM labels travel with the content, so a rule can treat an instruction from the user and one scraped from a web page as fundamentally different things.
THE CLOCKWORK CABINET
The Vault Gate · room 04 of 11
Your LLM can make decisions. It shouldn't get unrestricted access.
SentinelLLM is a defence-in-depth security gateway for LLM applications: content entering the runtime carries provenance tags, detection is probabilistic, and the actions that actually execute are governed by a deterministic, separately-auditable enforcement path.
It exists because an LLM that can make decisions should never also hold unrestricted keys — judgement and permission are different mechanisms, and this project gives each its own.
a request, gated — provenance in, audited action out
approved → SHA-256 digest matches, token unused → executes once
unapproved → gate blocks → audit trail records the attempt
In a typical LLM application, one component both decides and acts: the model's output flows straight into tools, databases and external calls. A single prompt injection, or one confident hallucination, therefore becomes an unauthorised action.
The hard requirement is separation without paralysis: content must carry provenance (who wrote it — user, untrusted context, or system), suspicious content must be detected probabilistically, but the decision to actually execute must be deterministic, permissioned and auditable after the fact.
Everything entering the runtime is stamped with provenance — USER_INPUT, UNTRUSTED_CONTEXT or SYSTEM — so downstream policy can reason about origin, not just content.
A probabilistic detection layer flags suspicious content, but it can never execute anything: policy decisions (PDP) and action enforcement (PEP) are decoupled, and enforcement is deterministic — an action runs only when policy says so.
Sensitive actions require cryptographically bound human approvals: SHA-256 argument digests and single-use tokens mean an approval applies to exactly one payload exactly once. PostgreSQL row-level locking prevents race conditions around that guarantee, and a full audit trail with credential redaction records what actually happened.
USER_INPUT, UNTRUSTED_CONTEXT and SYSTEM labels travel with the content, so a rule can treat an instruction from the user and one scraped from a web page as fundamentally different things.
A probabilistic classifier may be wrong; a policy gate must not be. Keeping them decoupled means a detection miss can never directly become an executed action.
SHA-256 argument digests plus single-use tokens make an approval unforgeable and unrepeatable — approving 'delete record X' cannot be replayed as 'delete record Y'.
Concurrent requests racing for the same approval or action are serialised at the database, so the guarantee holds under load, not just in a single-threaded demo.
every number here carries its source — my resume's figures and the synthetic-fixture results are marked for what they are