Hosted
Security and data
What the hosted hub can and cannot see, how checks are isolated, and how to export or delete your data.
Design summary
- The agent is outbound-only. It dials the hub over a WebSocket at
/v1/agent/connect. There are no inbound ports to open and no SSH access for us. - Your source code never leaves your server. The agent clones the repository itself and sends the hub only results, annotations, and logs.
- Each job runs as an unprivileged user with resource limits and, by default, a restricted network.
- Anything you list in
redactis scrubbed from logs before upload.
Outbound-only connection
The agent opens one connection to https://ci.webuno.io on port 443 and keeps it open. Jobs arrive over that connection. If the hub is unreachable, the agent retries and nothing on your side listens for traffic. Firewall rules need only allow outbound 443. See How it works.
Source code stays on your server
When a push or pull request arrives, the hub routes a job to your agent. The agent clones the repository using a short-lived GitHub installation token, runs the checks, and sends back:
- job states and durations
- annotations (file, line, message), at most 500 per job
- logs, capped at 10 MiB per job
The hub does not receive file contents, diffs, or the working tree.
Isolation of checks
Every job runs as the unprivileged user hookci-run inside a transient systemd unit under hookci.slice, with CPU, memory, task, and time limits from checks.limits. Each job gets its own network namespace. Details and the --isolation none escape hatch are in Isolation and egress.
Egress allowlist
Job traffic goes through an egress proxy that allows only the hostnames you list in egress, on port 443. Everything else is refused. Add the registries your dependencies need, for example registry.npmjs.org.
Redaction
Values or variable names listed under redact in .hookci.yml are replaced in logs before they are uploaded.
redact: [MY_SECRET, DEPLOY_KEY]
Redaction is a safety net. Do not print secrets on purpose.
Fork pull requests
Untrusted code is the main risk of any CI. HookCI gates it:
checks.trust: collaboratorsruns pull requests from repo collaborators only.checks.trust: approvewaits for someone to click Approve run.checks.forks: gatedrequires approval for fork PRs.neverignores them.trust: allruns everything and is not recommended for public repositories.
See Trust and forks.
Token handling
- Pair tokens (
hc_pair_...) are single use and valid for 15 minutes. - The agent stores its credential in
agent.json(mode 600) inside its state directory under/var/lib/hookci, which has mode 0700. - GitHub installation tokens given to the agent are short lived.
- Revoking an agent in Slack App Home makes a running agent exit with code 3, and its unit does not restart.
The GitHub App asks for read access to contents, metadata, pull requests, and members, and write access to checks. It does not write commit statuses.
Data we store
| Data | Where |
|---|---|
| Run records, agent and repo metadata, workspace settings | Cloudflare D1 |
| Job logs | Cloudflare R2 |
| Slack and GitHub installation tokens | Stored encrypted by the hub |
Storage uses the EU jurisdiction where Cloudflare offers it. Retention depends on your plan: see pricing. Log uploads are capped at 10 MiB per job.
Signed log links
Logs are not public. Links posted to Slack or the hub open logs through signed URLs that expire after 15 minutes. Open the run again to get a fresh link.
Export and delete
In Slack:
/hookci export
/hookci delete-my-data
export returns the data held about you. delete-my-data removes it. Both are described in Slack.
Uninstall and purge
Uninstalling the GitHub App purges the installation’s data within 30 days. To fully leave, also revoke each agent in Slack App Home and remove the agent from your servers: see Upgrade and uninstall.
Contact and disclosure
- Security reports: see
https://ci.webuno.io/.well-known/security.txt. - Privacy requests: privacy@webuno.io.
- Support: support@webuno.io.
If you prefer to keep everything under your control, self-host the hub.