DocsCI executes user-supplied code. This page documents how we isolate that execution, how access control is enforced at the database layer, and what limits apply to every run.
Sandbox architecture: Every code snippet runs inside an ephemeral sandbox that is torn down immediately after execution. We use two sandbox strategies:
JavaScript / TypeScript
vm2 / isolated-vm
Python
Pyodide (WebAssembly)
⚠️ Secret scanning before execution
Every snippet is scanned for credentials (AWS keys, API tokens, private keys, connection strings) using 40+ regex patterns before it enters the sandbox. Snippets containing secrets are flagged as findings and not executed.
Three roles exist at the organization level. Roles are stored in docsci_org_members.role and enforced both in the API layer and at the database via RLS.
| Permission | 👁 Viewer | ✏️ Editor | 👑 Owner |
|---|---|---|---|
| Trigger CI runs | ❌ | ✓ | ✓ |
| View findings & run history | ✓ | ✓ | ✓ |
| Manage projects | ❌ | ✓ | ✓ |
| Invite members | ❌ | ✓ | ✓ |
| Change member roles | ❌ | ✗ | ✓ |
| Remove members | ❌ | ✗ | ✓ |
| Delete organization | ❌ | ✗ | ✓ |
| Change billing | ❌ | ✗ | ✓ |
| Create owner invites | ❌ | ✗ | ✓ |
The last owner of an organization cannot be demoted or removed. Attempting to do so returns HTTP 409.
All tables use Postgres Row-Level Security. Even if the API layer is bypassed, data is inaccessible unless the authenticated user has a matching membership record.
docsci_orgs
docsci_org_members
docsci_projects
docsci_runs
docsci_invite_tokens
Every sandbox run enforces hard limits. These cannot be overridden by docsci.yml beyond the stated maximums.
| Cap | Default | Note |
|---|---|---|
| Snippet execution timeout | 20 s | Max 60 s via docsci.yml |
| JS/TS memory per isolate | 64 MB | Hard limit — OOM kills the isolate |
| Python memory (Pyodide) | 128 MB | WASM linear memory limit |
| Run total timeout | 5 min | All snippets in a run |
| Snippets per run | 500 | Additional snippets skipped with warning |
| Docs files per run | 1 000 | glob expansion cap |
| Doc file size | 1 MB | Files larger than 1 MB are skipped |
| OpenAPI spec size | 2 MB | Larger specs rejected at API |
| Secret scan patterns | 40+ | Runs before execution, not configurable off |
| Network allowlist entries | 20 | Per org, owner-configurable |
By default, snippet sandboxes have no outbound network access. Private RFC-1918 ranges are always blocked (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). Outbound calls will silently fail or time out.
To allow specific domains (e.g. your staging API), configure an allowlist in docsci.yml:
security:
network_isolated: false # default
allowlist:
- api.example.com
- "*.stripe.com"Set network_isolated: true to enforce a total network block — useful for regulated environments.
The allowlist is enforced at the sandbox level, not the DNS level. Wildcard patterns (*.example.com) match one subdomain level only.
DocsCI does not store any customer secrets or API keys. Each run uses an ephemeral credential scoped to the specific Supabase project for the duration of the run.
What we do store:
If you find a security vulnerability in DocsCI, please report it responsibly. We aim to acknowledge reports within 48 hours and release a fix within 14 days for critical issues.
How to report
[SECURITY]We do not currently offer a paid bug bounty program but will credit responsible reporters in our changelog and security advisory.
Need a security questionnaire, SOC 2 report, or pen test results? Contact us and we'll send our security package within one business day.
Request security package →