Loading...
Loading...
Before writing a single security feature, I focused on something many teams skip: the foundation. Observability, auditability, and trust start with the architecture, not the features.
Field Note #2 — Sentinel Series
---
Before writing a single security feature, I focused on something many teams skip: the foundation.
As AI becomes more integrated into financial systems, security can no longer be an afterthought. AI agents, APIs, and automated workflows are expanding the attack surface — making observability, auditability, and trust more important than ever.
For Phase 1, I deliberately didn't build features. Instead, I built the architecture they'll depend on.
---
Security infrastructure added after the fact always has gaps. It works around the existing system instead of being part of it. Audit logs become optional. Risk signals get attached to the outside of a pipeline instead of embedded in it. The seams show — and seams are where attackers and compliance failures live.
Sentinel is designed the other way around. Every piece of functionality that gets built in Phase 2 and beyond will inherit the security properties of the foundation laid here. That's only possible if the foundation is right from the start.
---
The project is structured as a Django + Next.js monorepo — backend and frontend in a single repository with shared tooling, consistent conventions, and a single CI/CD pipeline.
This matters because security infrastructure can't be split across teams with different deployment cadences. The audit ledger, the risk engine, and the dashboard that surfaces alerts all need to move together. A monorepo makes that coordination explicit rather than accidental.
Every environment — local development, CI, staging, production — runs in Docker. There is no "works on my machine" gap between what a developer tests and what gets deployed.
For a security product this is non-negotiable. A vulnerability that only reproduces in production is a vulnerability you'll never catch in review.
PostgreSQL handles the audit ledger and all persistent state. Redis handles caching, session management, and the task queue that powers async risk scoring and alert delivery.
Both are provisioned via Docker Compose for local development and configured to match production constraints — same Postgres version, same Redis configuration, same connection pool settings. No surprises when code that worked locally hits a real environment.
From day one, every request through Sentinel emits structured traces via OpenTelemetry. This means that when something goes wrong — a risk score takes too long to compute, an alert delivery fails, an audit event gets dropped — there is an observable record of what happened and where.
Distributed tracing is how you debug production systems you can't reproduce locally. For a platform that needs to be trusted, the platform itself needs to be observable.
Metrics are exposed via Prometheus and visualized in Grafana. Key metrics instrumented from Phase 1:
These aren't nice-to-haves. They're the operational baseline that tells you when Sentinel itself is behaving outside its normal parameters — the same standard Sentinel will hold AI agents to.
Every push to the repository runs a full CI pipeline: linting, type checking, unit tests, integration tests against a real database. No code merges without passing every check.
For a security product, a broken CI pipeline is a security event. Code that doesn't go through review and testing doesn't ship.
Every significant architectural decision in Sentinel is documented in an Architecture Decision Record (ADR) — a short document that captures what was decided, why, what alternatives were considered, and what tradeoffs were accepted.
This is the practice that makes a codebase auditable by humans, not just by machines. When a compliance auditor asks "why does the audit ledger work this way," the answer isn't buried in a commit message from eighteen months ago — it's in ADR-003, with the full reasoning written at the time the decision was made.
ADRs also enforce discipline. Writing down "we considered X and rejected it because Y" before you start building X forces you to actually think through why you're doing what you're doing. That discipline shows up in the code.
Every Phase 1 component has documentation written before the implementation was finalized. API contracts documented before endpoints were built. Data models documented before migrations were written. Service interfaces documented before services were coded.
This is the practice that surfaces ambiguity early — when changing direction is cheap — instead of late, when it costs days of rework.
---
---
The architectural decisions made in Phase 1 aren't about Phase 1. They're about what Phase 1 makes possible.
The service/repository pattern established here means that when Phase 3 adds risk scoring, the scorer can read from the audit ledger without coupling to the database schema. The abstracted task interfaces mean that when Phase 5 replaces Celery with Kafka, nothing upstream changes. The cursor-based pagination design means that when the audit ledger has ten million rows, queries don't time out.
None of this is visible in Phase 1. That's the point. Good foundations are invisible until you need them — and then they're the only thing that matters.
---
Sentinel is open source. GitHub: [github.com/Gwerdonatus/Sentinel](https://github.com/Gwerdonatus/Sentinel)
Next: Building Sentinel Phase 2 — Authentication & Immutable Audit Ledger