Skip to content
Edavid246Public

About

Defence Gateway AI MVP — classified-document assistant: authorization before retrieval, cited answers, hash-chained audit trail. Fictitious demo data.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Defence Gateway AI — MVP

Demo build. Every person, unit, document and record in this repository is fictitious demo data. The MVP is not security-accredited, and the dev profile is not sovereign — development calls a hosted model (Google Gemini) through the AI gateway. See AGENTS.md for what the product is and what is real, stubbed or cut.

A classified-document assistant for defence staff: ask a question in natural language, get an answer grounded in the documents you are cleared to see — cited down to the page — while every retrieval, answer, and access decision is written to a hash-chained, append-only audit trail.

Principle Zero: the AI layer is never the authorization boundary. Access is decided before retrieval, so the model only ever receives data the caller is cleared for — never user → LLM → database with "don't reveal" instructions.

What the MVP does

Area Behaviour
Classification & compartments Secret/Confidential/Restricted/Unclassified plus compartment sets (UAS-OPS, FORENSICS) on every document, record and chunk. Derived answers inherit the union of their inputs.
Authorization Policy decision first, then a parameterized row filter inside the SQL together with Postgres row-level security. Restricted detail reads answer 404, never 403.
Knowledge pathway Question → local embedding → hybrid retrieval (vector + full-text, reciprocal rank fusion) filtered inside the query → cited answer. Answers report found (did the evidence exist?) and degraded (did the vector channel run?).
Citations Inline citations resolve to the exact passage via GET /api/v1/documents/{ref}/chunks/{chunk_id}, through the same authorization path.
Audit trail Every query, retrieval, answer and decision is hash-chained with a checkpoint file and a git ledger; GET /api/v1/audit/verify reports valid, checked_count, first_bad_event_id and both external tips.
AI gateway LLMProvider/EmbeddingProvider interfaces. Dev uses a hosted model with a response-cache fallback; embeddings are always local. Production swaps in on-prem inference behind the same interface.
Group home Login lands on a card per business the caller can see; each opens a dashboard of audited typed-tool sections (maintenance, deliveries, QC holds, fleet, detections, forensic cases with chain of custody). A group Compliance page covers certifications and maintenance across all of them.
Reports Any business can be prepared as a DRAFT FOR HUMAN REVIEW report and exported to PDF or DOCX. Built from the same typed-tool rows (no model), marked with the derived classification on every page, and each export is audited.
Defences Requests to ignore permissions are refused with access unchanged and flagged as notable events; answers citing outside the evidence set are blocked.

Stack

Python 3.12 · FastAPI · SQLAlchemy 2 · Alembic · PostgreSQL 16 + pgvector · Docker Compose · Next.js + TypeScript + Tailwind (MapLibre lands later) · uv for dependency management.

Quick start

# 1. Postgres (pgvector/pg16) on localhost:5434
docker compose -f infra/compose.yaml up -d db

# 2. Install dependencies
uv sync

# 3. Schema + demo corpus (idempotent)
cd backend && uv run alembic upgrade head && cd ..
uv run python -m app.seed   # one account: owner
uv run python scripts/ingest_documents.py   # parses DOC-201..204, embeds locally (first run downloads the model)

# 4. Run the API (http://localhost:8001, docs at /docs)
uv run uvicorn app.main:app --reload --port 8001

Or run the database and the API container together:

docker compose -f infra/compose.yaml up -d --build   # db on :5434, api on :8001

AI key (optional): set GEMINI_API_KEY (or HOSTED_API_KEY) in .env for live answers — copy .env.example to .env first. Without it the assistant answers 503 (a missing key is never masked). To run the demo from the prefilled response cache instead, set LLM_CACHE_ONLY=1; record that cache with scripts/prefill_cache.py. Never commit .env.

Start the UI

The browser only calls same-origin /api/*; Next.js rewrites it to the API (API_URL, default http://localhost:8001). No CORS, no CDN, no telemetry.

cd web && npm ci && npm run dev      # http://localhost:3000 (API on :8001)
# or, with everything in containers:
docker compose -f infra/compose.yaml up -d --build   # adds web on :3000
npm run gen:api                       # regenerate src/lib/api-types.ts from the backend code (no server needed)

Sign in as any demo user below. The JWT is held in memory and sessionStorage only; logout clears it in the browser (the token stays valid until expiry, see docs/PRODUCTION_DEBT.md).

Hosted demo

The demo can run on one DigitalOcean Droplet with infra/compose.prod.yaml behind Caddy (HTTPS, same-origin CSP). Setup, secrets, the nightly reseed and updates are in docs/DEPLOY.md. It is still the dev profile: not sovereign, hosted model.

Run the checks

./scripts/check.sh   # ruff lint + format, pytest, web eslint + tsc, air-gap scan

The suite includes the authorization layers (RLS-only and filter-only against a hand-authored oracle), API tests, adversarial/audit tests and tamper-evidence tests for the hash chain.

Demo users

All names, units and documents are fictitious.

User Role Unit Clearance Compartments
Group Owner (owner) Owner EIB Group Government-sensitive UAS-OPS, FORENSICS, CLIENT-A..D

The product has one account and one role: owner. Five restricted accounts (logistics.head, coo, briech.lead, group.it, group.audit) and their roles exist only as test fixtures in tests/support/accounts.py, so the authorization tests can prove that a less-cleared user is filtered. To bring one into the product, add its entry to USERS in backend/app/seed/identity.py and its role to ROLE_PERMISSIONS in backend/app/authz/context.py, then reseed.

Shared demo password: Demo!Gateway2026 (dev seed only; the hosted demo refuses it and uses the owner's own password).

API surface

All routes are mounted under /api/v1 (system health check at /healthz):

Method Path Purpose
POST /api/v1/auth/login Token for a seeded demo user
GET /api/v1/me Identity: display name, unit breadcrumb, permissions
GET /api/v1/documents Documents visible to the caller
GET /api/v1/documents/{ref} Document detail (404 when not visible)
GET /api/v1/documents/{ref}/chunks/{chunk_id} Cited-passage viewer
GET /api/v1/records Canonical records visible to the caller
POST /api/v1/assistant/query Cited question answering (found, degraded, refused); record-style requests return a result_table from a typed data tool
GET /api/v1/assistant/conversations The caller's own threads
GET /api/v1/assistant/conversations/{id} Turns with resolved citations
GET /api/v1/audit Audit events (filter by event_id)
GET /api/v1/audit/verify Chain, checkpoint and ledger verification

Repository layout

backend/          FastAPI app: api/ authz/ audit/ knowledge/ ai_gateway/ connectors/
  alembic/        Schema migrations (RLS policies included)
data/             Fictitious demo corpus, seed inputs, demo questions
docs/             DECISIONS (the why behind big decisions), PRODUCTION_DEBT
web/              Next.js UI: login, assistant chat, audit viewer
infra/            Docker Compose, Postgres init, RLS guards
scripts/          check.sh, seeding, document generation, gateway smoke test
tests/            authz (RLS-only/filter-only oracles), api, audit, knowledge

Documentation

  • AGENTS.md — what the product is, the invariants (including Principle Zero), what is real, stubbed or cut, and the build rules
  • docs/DECISIONS.md — the why behind big product, security and architecture decisions
  • docs/PRODUCTION_DEBT.md — accepted demo shortcuts and what production requires
  • docs/DEPLOY.md — the hosted demo: server layout, setup, updates

Air-gap rules

No external CDNs, fonts, map tiles or telemetry. The API serves same-origin only (no CORS middleware). Embeddings run locally; the hosted model is reachable only through the AI gateway and can be disabled by configuration. scripts/check.sh scans for external resource references on every run.

License

All rights reserved. No license file is provided — this is client demo work.

About

Defence Gateway AI MVP — classified-document assistant: authorization before retrieval, cited answers, hash-chained audit trail. Fictitious demo data.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages