Skip to main content
Back to all seeds
WebActive build2026

Sentinel Desk

Digital-protection incident-management platform on the Frappe/ERPNext framework. Record-level authorization enforced server-side, tamper-evident audit trails, SLA-driven workflows with idempotent escalations, and retry-safe background jobs — secure-by-default for sensitive casework. Runs on synthetic demo data only.

Frappe FrameworkERPNextPythonMariaDBRedis / RQJinjaPlaywrightBench

What it is

Sentinel Desk is an incident-management platform for digital-protection casework, built on the Frappe/ERPNext framework. Teams intake, triage, assign, and escalate sensitive incidents through auditable workflows, with access enforced at the record level on the server and every state change written to a tamper-evident trail. Built and demoed on synthetic data only — no real protection, identity, health, or location data ever touches it.

The problem

Sensitive casework has requirements generic ticketing tools quietly fail. Access has to be per-record, not per-page — hiding a row in the UI is not security. Every assignment, status change, and escalation has to be attributable and reproducible. And the background jobs that drive SLAs and notifications must survive retries and duplicate delivery without double-acting. Bolting that onto a generic tracker means re-implementing authorization, audit, and reliability the hard way.

What I built

Record-level authorization

Access is enforced server-side on every incident path via Frappe's permission model and DocType-level query conditions — the UI never decides what a user may see. `ignore_permissions` is banned except for a few narrowly documented internal operations, each of which ships with its own authorization tests.

Auditable, idempotent workflows

Workflow transitions, assignments, SLA changes, and escalations are modelled as auditable events — each attributable, ordered, and replay-safe. Re-running or retrying a transition can never double-escalate a case or corrupt its state.

Retry-safe background work

SLA timers, escalations, and notifications run as scheduled jobs / RQ tasks written to tolerate retries and duplicate delivery. Idempotency keys plus guard checks mean a redelivered job is a no-op, not a second alert or a second workflow jump.

Secure-by-default demo

The whole platform runs on synthetic content with no operationally realistic identities, secrets, or actionable detail. The point is to prove the engineering — authorization, audit, reliability — not to hold sensitive data.

Engineering decisions

Why Frappe / ERPNext

Frappe ships the parts this kind of tooling actually needs — a typed DocType model, a role-and-permission system, a workflow engine, and a background-job runner — as first-class primitives. That let the effort go into the invariants (record-level authz, audit, idempotency) instead of rebuilding a CRUD-and-permissions substrate from scratch.

Why server-side row-level authorization

UI hiding is a usability nicety, never a security boundary. Enforcing access in the query layer means an authorization bug is catchable by a permission test — not something that only surfaces when someone crafts a direct request.

Why idempotent jobs over fire-and-forget

Queues redeliver. If an escalation job runs twice, someone gets paged twice or a case double-jumps its workflow. Designing every job to be a no-op on redelivery makes the system correct under the failure modes queues actually have, not just the happy path.

What I'd do differently

Model the audit trail as an append-only event log from the first milestone rather than deriving history from document versions — reconstructing "who changed what, when, and why" after the fact is more work than emitting the events up front. And invest in permission-focused integration tests earlier: they are the cheapest place to catch an authorization regression, but only if they exist before the surface area grows.