Customer-Hosted Runner
Run the DocsCI execution engine entirely inside your own infrastructure. No documentation leaves your network. Designed for enterprise security reviews, air-gapped environments, and teams with data residency requirements. Available as a GitHub Actions composite action and a curl-deployable Docker image.
Why customer-hosted
InfoSec requires that documentation containing internal architecture details never leaves the corporate network.
Customer-hosted runner processes all docs locally. Only a summary report (finding counts, metadata) is sent to the DocsCI dashboard — and that can be disabled too.
CI pipelines have no outbound internet access. Can't POST to snippetci.com/api/runs/queue.
The Docker image runs on your internal network. Results are posted back to your GitLab/GitHub instance via the internal API — no external network calls.
Documentation data must stay in a specific region or jurisdiction.
Customer-hosted runner ensures zero data egress. All processing happens inside the boundary.
Option A: GitHub Actions composite action
Use the docsci/runner-action composite action. It runs the DocsCI Docker image as a step in your GitHub Actions workflow on your self-hosted runner. Zero external network calls — all execution happens in your runner environment.
# .github/workflows/docsci.yml (customer-hosted runner)
name: DocsCI
on: [pull_request]
jobs:
docs-ci:
runs-on: self-hosted # your runner — no outbound internet needed
steps:
- uses: actions/checkout@v4
- name: Run DocsCI (customer-hosted)
uses: docsci/runner-action@v1
with:
# Required
docs_path: "docs/"
token: ${{ secrets.DOCSCI_LICENSE_KEY }}
# Optional: OpenAPI drift detection
openapi_url: "http://internal-staging.corp/api/openapi.json"
# Optional: post findings back to GitHub PR
github_token: ${{ secrets.GITHUB_TOKEN }}
post_pr_comments: true
# Optional: disable telemetry to DocsCI dashboard entirely
telemetry: falseOption B: Docker image (curl-deployable)
For non-GitHub CI systems (GitLab, Jenkins, Buildkite, CircleCI) or one-off audits. Pull the image, mount your docs directory, and run. Output is a JSON report file.
# Pull the runner image (from your internal registry or Docker Hub)
docker pull docsci/runner:latest
# Run against a local docs directory
docker run --rm \
-v "$(pwd)/docs:/workspace/docs:ro" \
-v "$(pwd)/reports:/workspace/reports" \
-e DOCSCI_LICENSE_KEY=$DOCSCI_LICENSE_KEY \
-e OPENAPI_URL="http://staging:8080/openapi.json" \
docsci/runner:latest \
--docs /workspace/docs \
--report /workspace/reports/docsci-report.json \
--exit-on-critical
# Output: reports/docsci-report.json
# Exit code: 0 (pass), 1 (critical findings), 2 (error)
# For GitLab CI (.gitlab-ci.yml):
docs:verify:
stage: docs
image: docsci/runner:latest
script:
- docsci-runner --docs docs/ --report docsci-report.json --exit-on-critical
artifacts:
paths: [docsci-report.json]
expire_in: 1 weekSecurity model
Execution isolation: The runner uses the same hermetic V8 isolate and Pyodide WASM execution as the hosted service. Each snippet runs in a fresh isolate with memory limits, timeouts, and network restrictions — even in customer-hosted mode.
No outbound calls in air-gap mode: When telemetry: false, the runner makes zero external network calls. License validation happens at startup against a local key file — no internet required after initial activation.
Image signing: All runner Docker images are signed with cosign. Verify the signature before deploying to a production environment.
Network allowlist enforcement: The runner enforces the same network allowlist as the hosted service — snippets can only contact hosts you explicitly permit, plus always-blocked private IP ranges.
Timeline
Get early access to the runner
Joining the Docker image beta in May 2025 — tell us about your air-gap requirements.