# adreaskar/securedrop architecture

> Architecture diagram of the GitHub repository adreaskar/securedrop, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/adreaskar/securedrop
- Repository: https://github.com/adreaskar/securedrop

## Overview

SecureDrop provides authenticated file transfer with quarantine, antivirus scanning, status tracking, and approved-file delivery. The documented main flow runs from the web app through the API into MinIO and PostgreSQL, then through an event-driven scanner and workflow automation before recipients can download approved files. The README documents RabbitMQ and Node-RED in that scan workflow; their wiring and source are not present in the supplied tree, so those relationships are shown only as documented integrations.

Main entry points: [`stateless-scanner/src/index.js`](https://github.com/adreaskar/securedrop/blob/master/stateless-scanner/src/index.js) (Scanner service), [`api/src/index.js`](https://github.com/adreaskar/securedrop/blob/master/api/src/index.js) (API server), [`webapp/src/App.tsx`](https://github.com/adreaskar/securedrop/blob/master/webapp/src/App.tsx) (SecureDrop UI), [`api/src/routes/files.js`](https://github.com/adreaskar/securedrop/blob/master/api/src/routes/files.js) (File routes)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Web app"]
  node_web["SecureDrop UI<br/>[App.tsx]"]
  node_authui["Auth session<br/>[useAuth.tsx]"]
  node_filesui["File views<br/>[FileUpload.tsx]"]
  node_dashboard["Sent files<br/>[Dashboard.tsx]"]
  node_inbox["Received files<br/>[Inbox.tsx]"]
end

subgraph group_identity["Identity"]
  node_keycloak["Keycloak"]
end

subgraph group_backend["Transfer API"]
  node_api["API server<br/>[index.js]"]
  node_routes["File routes<br/>[files.js]"]
  node_authmw["JWT verification<br/>[auth.js]"]
  node_miniosvc["Object storage service<br/>[minio.js]"]
  node_objects[("MinIO buckets")]
  node_dbsvc["Transfer records<br/>[database.js]"]
  node_postgres[("PostgreSQL")]
end

subgraph group_scan["Scanning workflow"]
  node_scanner["Scanner service<br/>[index.js]"]
  node_rabbit["RabbitMQ"]
  node_clamav["ClamAV"]
  node_nodered["Bucket workflow"]
  node_thingsboard[("ThingsBoard telemetry")]
end

node_sender(("Sender"))
node_recipient(("Recipient"))

node_sender -->|"uses"| node_web
node_web -->|"initializes"| node_authui
node_authui -->|"authenticates"| node_keycloak
node_web -->|"calls file API"| node_api
node_api -->|"dispatches"| node_routes
node_routes -->|"verifies JWT"| node_authmw
node_authmw -->|"gets signing keys"| node_keycloak
node_routes -->|"stores and streams"| node_miniosvc
node_miniosvc -->|"reads and writes"| node_objects
node_routes -->|"manages transfers"| node_dbsvc
node_dbsvc -->|"reads and writes"| node_postgres
node_routes -.->|"storage event"| node_rabbit
node_rabbit -.->|"dispatches event"| node_scanner
node_scanner -->|"reads object"| node_miniosvc
node_scanner -->|"scans stream"| node_clamav
node_scanner -->|"moves object"| node_objects
node_scanner -->|"posts scan status"| node_api
node_scanner -.->|"status workflow"| node_nodered
node_scanner -.->|"telemetry"| node_thingsboard
node_web -->|"renders"| node_dashboard
node_web -->|"renders"| node_inbox
node_dashboard -->|"polls sent files"| node_api
node_inbox -->|"polls received files"| node_api
node_recipient -->|"uses"| node_web
node_inbox -->|"requests download"| node_api
node_api -->|"streams approved file"| node_recipient

click node_web "https://github.com/adreaskar/securedrop/blob/master/webapp/src/App.tsx"
click node_authui "https://github.com/adreaskar/securedrop/blob/master/webapp/src/hooks/useAuth.tsx"
click node_filesui "https://github.com/adreaskar/securedrop/blob/master/webapp/src/components/FileUpload.tsx"
click node_dashboard "https://github.com/adreaskar/securedrop/blob/master/webapp/src/pages/Dashboard.tsx"
click node_inbox "https://github.com/adreaskar/securedrop/blob/master/webapp/src/pages/Inbox.tsx"
click node_api "https://github.com/adreaskar/securedrop/blob/master/api/src/index.js"
click node_routes "https://github.com/adreaskar/securedrop/blob/master/api/src/routes/files.js"
click node_authmw "https://github.com/adreaskar/securedrop/blob/master/api/src/middleware/auth.js"
click node_miniosvc "https://github.com/adreaskar/securedrop/blob/master/api/src/services/minio.js"
click node_dbsvc "https://github.com/adreaskar/securedrop/blob/master/api/src/services/database.js"
click node_scanner "https://github.com/adreaskar/securedrop/blob/master/stateless-scanner/src/index.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_web,node_authui,node_filesui,node_dashboard,node_inbox toneBlue
class node_keycloak toneAmber
class node_api,node_routes,node_authmw,node_miniosvc,node_objects,node_dbsvc,node_postgres toneMint
class node_scanner,node_rabbit,node_clamav,node_nodered,node_thingsboard toneRose
class node_sender,node_recipient toneIndigo
```

## Components

### Web app

- [SecureDrop UI](https://github.com/adreaskar/securedrop/blob/master/webapp/src/App.tsx): `webapp/src/App.tsx`
- [Auth session](https://github.com/adreaskar/securedrop/blob/master/webapp/src/hooks/useAuth.tsx): `webapp/src/hooks/useAuth.tsx`
- [File views](https://github.com/adreaskar/securedrop/blob/master/webapp/src/components/FileUpload.tsx): `webapp/src/components/FileUpload.tsx`
- [Sent files](https://github.com/adreaskar/securedrop/blob/master/webapp/src/pages/Dashboard.tsx): `webapp/src/pages/Dashboard.tsx`
- [Received files](https://github.com/adreaskar/securedrop/blob/master/webapp/src/pages/Inbox.tsx): `webapp/src/pages/Inbox.tsx`

### Identity

- **Keycloak**

### Transfer API

- [API server](https://github.com/adreaskar/securedrop/blob/master/api/src/index.js): `api/src/index.js`
- [File routes](https://github.com/adreaskar/securedrop/blob/master/api/src/routes/files.js): `api/src/routes/files.js`
- [JWT verification](https://github.com/adreaskar/securedrop/blob/master/api/src/middleware/auth.js): `api/src/middleware/auth.js`
- [Object storage service](https://github.com/adreaskar/securedrop/blob/master/api/src/services/minio.js): `api/src/services/minio.js`
- **MinIO buckets**
- [Transfer records](https://github.com/adreaskar/securedrop/blob/master/api/src/services/database.js): `api/src/services/database.js`
- **PostgreSQL**

### Scanning workflow

- [Scanner service](https://github.com/adreaskar/securedrop/blob/master/stateless-scanner/src/index.js): `stateless-scanner/src/index.js`
- **RabbitMQ**
- **ClamAV**
- **Bucket workflow**
- **ThingsBoard telemetry**

### Other components

- **Sender**
- **Recipient**

## Connections

- Sender → SecureDrop UI: uses
- SecureDrop UI → Auth session: initializes
- Auth session → Keycloak: authenticates
- SecureDrop UI → API server: calls file API
- API server → File routes: dispatches
- File routes → JWT verification: verifies JWT
- JWT verification → Keycloak: gets signing keys
- File routes → Object storage service: stores and streams
- Object storage service → MinIO buckets: reads and writes
- File routes → Transfer records: manages transfers
- Transfer records → PostgreSQL: reads and writes
- File routes → RabbitMQ: storage event
- RabbitMQ → Scanner service: dispatches event
- Scanner service → Object storage service: reads object
- Scanner service → ClamAV: scans stream
- Scanner service → MinIO buckets: moves object
- Scanner service → API server: posts scan status
- Scanner service → Bucket workflow: status workflow
- Scanner service → ThingsBoard telemetry: telemetry
- SecureDrop UI → Sent files: renders
- SecureDrop UI → Received files: renders
- Sent files → API server: polls sent files
- Received files → API server: polls received files
- Recipient → SecureDrop UI: uses
- Received files → API server: requests download
- API server → Recipient: streams approved file
