Initial curated RAGcore source from c16667f0c9397e2bfc8dd0255b114fba23c8d05e
This commit is contained in:
commit
7ca726caf2
659 files changed
+98171
No files matched your search
@@ -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.
|
||||
Reference in new issue
Block a user