BranchPilot

Security

Authorization stays server-side even when the UI hides controls.

The design assumes browser fields, ticket text, uploaded documents and AI output are untrusted until validated by the owning service.

Tenant and branch isolation

JWT claims are refreshed from current memberships on each authenticated request. Ticket reads return 404 when the actor lacks scope, reducing resource-enumeration leakage. Support/admin access is organization-scoped; branch users require an exact organization + branch match.

Private files

Ticket and knowledge files live on private volumes. Browser downloads go through authenticated NestJS routes; FastAPI can fetch only approved relative internal attachment paths using service authentication.

Internal services

n8n, FastAPI and internal NestJS endpoints are not routed by Nginx. Service calls require a shared internal token and the token is never shipped to browser JavaScript.

AI boundaries

Ticket text and retrieved documents are treated as evidence, not model instructions. Draft citations are whitelisted against approved procedure versions. AI cannot resolve tickets, modify points or execute refunds.

Audit

State-changing and security-relevant actions write append-only audit records. Audit JSON intentionally avoids attachment contents and secrets.