Initial curated RAGcore source from c16667f0c9397e2bfc8dd0255b114fba23c8d05e

This commit is contained in:
Public Source Publisher committed 2026-10-01 01:34:21 +02:00
commit 7ca726caf2
659 files changed
+98171

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
# Prompt Injection Defense
## Hoofdregel
Retrieved content is **onbetrouwbare evidence** en nooit een instructiebron. Tekst als “ignore previous instructions” heeft geen hogere status dan andere documenttekst.
## Promptstructuur
1. System policy
2. Application contract
3. User question
4. Delimited untrusted evidence with citation IDs
5. Required output schema
De systempolicy verbiedt instructies uit evidence, externe navigatie, toolcalls en secret disclosure.
## Controls
- Trust level en source provenance in retrieval.
- Hidden/obfuscated text en suspicious instruction patterns als signals, niet als enige blocker.
- Geen tools in normale generation context.
- Geen automatic execution of modeloutput.
- Answerclaim/citationvalidation.
- Adversarial fixture corpus met direct, indirect, encoded en multilingual injections.
- Quarantine of lower trust voor poisoned source updates.
## Limiet
Promptfilters alleen zijn onvoldoende. De primaire beveiliging is scheiding van bevoegdheden, geen tools, minimale context, databeleid en menselijke/policy approval voor acties buiten RAGCore.
+22
View File
@@ -0,0 +1,22 @@
# Secrets and Network
## Secrets
- `.env` alleen lokaal en nooit committen.
- Productie gebruikt Unraid secrets/files of een passende secret store.
- Service tokens: random 256-bit minimum, prefix voor identificatie, Argon2id/HMAC-hash met pepper, one-time display.
- Provider/API keys worden geredact uit logs, traces en errors.
- Rotatie ondersteunt overlap met maximaal twee actieve credentials per service account.
## Network matrix
| From | To | Doel |
|---|---|---|
| reverse proxy | app:8080 | UI/API |
| app | postgres:5432 | control/authorization |
| app | qdrant:6333 | retrieval |
| app | approved model endpoint | generation/embedding waar nodig |
| worker | postgres/qdrant/blob paths | jobs/ingestion |
| worker | allowlisted source endpoints | connector acquisition |
Geen andere standaardflows. Productie egress wordt waar praktisch op domains/IP-ranges beperkt.
+94
View File
@@ -0,0 +1,94 @@
# Security Controls
## Identity
OIDC voor mensen; gehashte, roteerbare service tokens met scopes en expiry voor applications. Tokens worden slechts eenmaal getoond.
## Authorization
Deny by default, explicit grants, effective-space intersection, use-case policies, database scoping, verplichte Qdrantfilters en resource reauthorization voor citations/downloads.
## Operations isolation
Iedere workspace-scoped job draagt expliciete ownership: `jobs.jobs.workspace_id`
is een echte kolom (migratie 0018), geen veld in `payload`. Elke lijst, teller,
detailpagina en mutatie filtert daarop in de query zelf --- nooit op rijen die al
opgehaald zijn.
- `PLATFORM_ADMIN` krijgt de expliciete globale scope (`workspace_id=None`) en
ziet dat ook op het scherm staan (`Scope: All workspaces`).
- `WORKSPACE_ADMIN` en `AUDITOR` zijn gebonden aan `principal.workspace_id`, voor
lijst, statustellers, filters, source-namen, detail en retry. `AUDITOR` is
read-only: retry vereist een rol uit `_RETRY_ROLES`.
- Een job zonder ownership (`workspace_id IS NULL`, alleen mogelijk voor rijen van
vóór 0018 waarvan de eigenaar niet betrouwbaar vast te stellen was) faalt
gesloten: onzichtbaar en onmuteerbaar voor iedere workspace-scoped principal,
uitsluitend inspecteerbaar door een platform admin. Er is nergens een
`payload.get("workspace_id") or principal.workspace_id`-fallback; die kende een
ownerloze job toe aan wie er toevallig naar keek.
- Tellers zijn ook tenantdata. Dashboard- en System Health-queuecijfers gebruiken
dezelfde scope als de Jobs-lijst.
- Ook de operatorfilters (status, type) en de paginering zijn predicaten van
diezelfde query (`JobListFilter` --- migratie 0019 voegt de bijbehorende index
toe). Er wordt dus geen bredere set opgehaald dan getoond wordt: elke rij die
dit proces binnenkomt is er één die deze principal mag zien. De vijf tellers
boven de tabel blijven bewust een scope-brede samenvatting van de wachtrij en
het scherm zegt dat er ook bij.
- Retry dwingt ownership af in het `UPDATE` zelf, niet in een voorafgaande read:
een cross-tenant mutatie die alleen onder concurrency lukt is nog steeds een
cross-tenant mutatie. Een geweigerde toegang of retry wordt vastgelegd als
`SECURITY_FAILURE` met actor, workspace, actie, doel en reden --- zonder payload.
Nieuwe jobs kunnen niet ownerloos ontstaan: `JobService.enqueue` eist
`workspace_id` en `PostgresJobRepository.enqueue` weigert een `Job` zonder.
## Filesystem-backed sources
Een Folder-source, en de lokale checkout root van een Git-source, geven de worker
een leesprimitief op de host: alles onder dat pad wordt vindbare content. Dat is
iets anders dan content beheren, dus het vereist `FILESYSTEM_SOURCE_MANAGE`
*bovenop* `SOURCE_MANAGE`, bij zowel aanmaken als bewerken (bewerken is precies
hoe een goedgekeurde source op een andere directory gericht wordt).
Gekozen model: **alleen `PLATFORM_ADMIN`**. `RAGCORE_SOURCE_ROOTS` is één
deployment-brede lijst zonder per-workspace mapping, dus een pad binnen de
allowlist kan prima het corpus van een andere tenant zijn; een workspace admin met
dit recht zou workspace B kunnen lezen door er een source op te richten. Zolang
roots niet per workspace geconfigureerd zijn, is het kiezen van een serverpad een
deploymentbeslissing en hoort die bij de rol die de deployment bezit. Per-workspace
roots (het sterkere self-service model) blijven mogelijk als self-service
filesystem sources later echt nodig blijken.
Alleen de gevoelige kinds zijn beperkt: `SOURCE_MANAGE` blijft ongewijzigd voor
Editors en Space Managers, en upload-sources worden er niet moeilijker door.
Autorisatie en sandbox zijn twee onafhankelijke poorten, allebei altijd vereist:
- `RAGCORE_SOURCE_ROOTS` blijft lexicaal afgedwongen bij opslaan, en volledig
geresolved (symlinks gevolgd) in worker en connector vlak voor iedere read. Een
pad buiten elke root wordt geweigerd --- ook voor een platform admin. Zonder
geconfigureerde roots kan geen enkele filesystem-source bestaan.
- De source mounts horen read-only te zijn. Dat is een security-invariant, niet
alleen een aanbeveling: het is wat het resterende TOCTOU-venster tussen
padvalidatie, `stat` en `open` onschadelijk maakt. Zijn de directories muteerbaar
door niet-vertrouwde actoren, dan is die aanname geschonden.
## Network
Alleen app achter reverse proxy. PostgreSQL/Qdrant/worker op internal network. Geen debug/adminpoorten publiek. Egress voor connector/modelworkers zo beperkt mogelijk.
## Content
MIME sniffing, allowlists, size/time/depth limits, archive-bombdetectie, quarantine, sandboxing waar haalbaar, geen macro/scriptuitvoering en read-only source mounts.
## Secrets
Environment/secrets mount, geen plaintext in database/logs/evidence, redaction processor, onafhankelijke token pepper en rotatieprocedure.
## Abuse prevention
Rate limits per principal/application, request/body/token/context limits, bounded concurrency, job quotas en circuit breakers.
## Audit
Append-only events voor auth, grants, source changes, publication, modelroute, adminacties en security failures. Querycontentlogbeleid is per space configureerbaar.
+37
View File
@@ -0,0 +1,37 @@
# Threat Model
## ModelForge M6 boundary
The ModelForge credential is a mode-0600 read-only mounted file, not environment content. Adapter
requests contain transient text but logs/metrics contain only provider name, correlation and timing.
The adapter rejects cloud hosts and has no cloud fallback. Public retrieval cannot select the
shadow collection; only the operator command may target it.
## Assets
Documentbytes, parsed content, embeddings, queries, answers, credentials, grants, modelroutes, auditlogs en hersteldata.
## Trust boundaries
Internet/LAN client -> reverse proxy -> RAGCore app -> internal services; source connector -> ingestion; RAGCore -> modelprovider; operator -> backupmedia.
## Belangrijkste dreigingen
1. Cross-workspace/space data leakage, inclusief operationele metadata: joblijsten,
statustellers, source-namen en foreign job retry (zie Operations isolation in
`SECURITY_CONTROLS.md`).
2. Gestolen service token of sessie.
3. Prompt injection in documenten.
4. Data poisoning of kwaadaardige bronupdates.
5. Path traversal, SSRF, archive bomb en parser exploit.
6. Onbedoeld versturen van local-only data naar cloudprovider.
7. Qdrant/DB exposure of filterbypass.
8. Citation IDOR en historical-content leakage.
9. Job duplication/race die halfgepubliceerde index veroorzaakt.
10. Backup met secrets of onverifieerbare restore.
11. Resource exhaustion via uploads, queries of modelcalls.
12. Supply-chain of model-update regressie.
## Security acceptance
Voor ieder bedreigingsscenario bestaan preventieve controls, detectie, negatieve tests en een herstel/runbook. Critical/high bevindingen blokkeren milestone release.