AI-drafted fixes. Human-shipped.
The literal "user reports → AI ships fix" loop is unsafe — anonymous user content becomes potential prompt injection if it touches an action-taking AI. Scaffolds is built on the premise that AI never ships autonomously. The team member's approval is the security boundary.
The loop, in plain English
- An end-user, client, or teammate reports a problem with rich context attached.
- The ticket lands in your CMS inbox — anonymous and client tickets are flagged.
- A team member reviews and explicitly promotes the ticket to "run AI."
- AI proposes a scoped fix as a draft pull request.
- A second AI checker pass scans the proposal for compromise patterns.
- A human reviews the diff and clicks merge.
Defense layers (no single point of trust)
If any one layer fails, the others still hold. We assume every user-supplied byte may be hostile.
1. Trust tiers
End-user (anonymous) and client tickets cannot trigger AI runs. Only authenticated team members can promote a ticket to "run AI."
2. Structured prompts
User content goes into clearly-marked data fields (<user_content>), never as instructions. The AI's task is fixed by us, not by the reporter.
3. Input scrubbing
Known injection patterns ("ignore previous", "system:", role-redefinitions) are stripped before any AI call. Applied to user text, DOM-text, OCR'd image text, and integration messages. Imperfect — but it raises the bar.
4. Output sandbox
The AI can only emit changes within tight file scope — specific CSS/HTML files identified by the ticket's selector. Forbidden paths: .env*, CI configs (.github/workflows, .gitlab-ci.yml), package.json deps, build scripts, anything in secrets/, anything outside the repo's src/ or public/. Enforced post-AI by a deterministic validator — never by trusting the AI.
5. Read-only AI by default
AI's GitHub App permissions: read repo, propose draft PR. Cannot merge. Cannot deploy. Cannot access secrets. Cannot trigger workflows.
6. Checker pass
A separate AI run reviews each proposed fix: does this look like a compromise attempt? Does it match the original ticket's scope? Two-AI veto before any human ever sees it.
7. Mandatory human review
Every AI-proposed change shows a diff. A team member clicks approve. No silent edits, ever.
8. Sandboxed runtime
AI runs in an ephemeral container with no production credentials. Runtime tokens are short-lived (15 min), scoped to one repo and one branch.
9. Audit log
Every AI run is captured: prompt, output, checker verdict, who approved, what shipped. Tenant-scoped. Exportable on Team and Enterprise.
10. Per-tenant kill switch
One toggle disables all AI runs for a workspace if anything looks off. Set automatically on N suspicious checker verdicts.
11. Multi-modal injection guard
Screenshots and DOM captures are processed as data, not instructions. OCR'd text from images is sandboxed before reaching the prompt.
Tenant isolation
Multi-tenancy is enforced from the schema up. Every table holding tenant data has a tenant_id. Row-level isolation is enforced in the query layer. Storage paths are namespaced by tenant. Logs and audit logs are namespaced. Tenants never see each other's data.
Privacy and compliance
Per-tenant scrubbing rules let you redact PII from screenshots, DOM, and console captures before storage. Healthcare, legal, and fintech tenants can self-host on their own infrastructure — same code, no data leaves the VPC.
Reporting a vulnerability
Email security@qadra.studio. We do not currently run a paid bounty program, but we credit researchers and fix promptly.