forked from efforting.tech/gitea.efforting.tech
Clarify network policy and worktree scoping in architecture docs
This commit is contained in:
@@ -32,7 +32,7 @@ The worktree is prepared in two distinct container runs:
|
||||
|
||||
1. **Checkout container** — mounts the base worktree volume as writable. User credentials are injected here. Runs `git clone` / `git checkout` for the target revision, then exits. Keeps git operations and credential handling sandboxed away from the host.
|
||||
|
||||
2. **Task container** — mounts base worktree read-only (overlayfs lower) and mutations volume writable (overlayfs upper). Runs the actual CI job. No credentials present.
|
||||
2. **Task container** — mounts base worktree read-only (overlayfs lower) and mutations volume writable (overlayfs upper). Runs the actual CI job. Secrets are mounted only if explicitly declared in the task configuration.
|
||||
|
||||
The base worktree volume is writable only during step 1. For all subsequent runs it is mounted `:ro` — the kernel enforces this. Any writes from the task container go to the mutations volume via overlayfs and cannot affect the base worktree.
|
||||
|
||||
@@ -92,11 +92,9 @@ The private key is mounted into the checkout container for the duration of the c
|
||||
|
||||
---
|
||||
|
||||
#### Access control and worktree scoping
|
||||
#### Worktree scoping
|
||||
|
||||
Base worktrees are scoped to `(owner, repo, revision)` — not just `(repo, revision)`. Sharing across owners would allow one user's job to read a repo checked out under another user's credentials. Even for public repos this special case is not worth the complexity.
|
||||
|
||||
Checkout is performed using credentials of the job owner (or a member of their org). If access is revoked, the owner's base worktree cache is invalidated and future runs re-checkout with fresh credential verification. Runs already in progress are unaffected — mid-run revocation is accepted as a limitation.
|
||||
Base worktree volumes are scoped per owner. Access control is handled entirely by Gitea via SSH deploy keys — the checkout container only has the key for the specific repo it is cloning, so Gitea enforces what it can and cannot access. The per-owner scoping is about cache ownership and lifecycle: each owner manages and cleans up their own volumes independently.
|
||||
|
||||
#### Cleanup
|
||||
|
||||
@@ -207,14 +205,13 @@ Individual tools may need additional flags (e.g. `--color=always` for git, cargo
|
||||
|
||||
### Network isolation
|
||||
|
||||
Runners need outbound WAN access (to fetch dependencies) but must not be able to reach internal LAN or host-local services. Two approaches under consideration:
|
||||
WAN access is both expected and fine for most tasks — containers need to fetch dependencies, push to registries, etc. The specific concern is containers reaching the host's localhost, which could expose internal services as an unintended back channel.
|
||||
|
||||
1. **Subnet filtering** — firewall rules block RFC-1918 ranges for container network namespaces while allowing WAN.
|
||||
2. **Custom egress VPS** — route all runner traffic through a separate VPS with egress filtering, reusable across services.
|
||||
The default network policy is therefore: WAN allowed, host localhost blocked. Network policy is configurable per task — tasks that need no network at all (e.g. the rsync publish experiment) can use `network_mode: none`.
|
||||
|
||||
For tasks that only operate on local mounts (e.g. the rsync publish experiment), `network_mode: none` is used — no network at all.
|
||||
How to enforce the host localhost restriction is still open — likely a firewall rule on the Docker bridge interface blocking access to `127.0.0.1` from container network namespaces.
|
||||
|
||||
**Status: open. Approach 2 is preferred for reusability but adds infrastructure complexity.**
|
||||
**Status: default policy decided. Enforcement mechanism is open.**
|
||||
|
||||
---
|
||||
|
||||
@@ -239,6 +236,6 @@ Builds targeting non-Linux platforms (Windows, macOS) would require QEMU or sepa
|
||||
| Layered caches | Whether caches can use the same overlay approach as worktrees |
|
||||
| Deployment permissions | Which tasks are allowed to write which bind-mounted targets |
|
||||
| SSH key registration | Automate public key registration via Gitea API (`POST /repos/{owner}/{repo}/keys`) — requires a Gitea user token with repo admin permissions, which is a separate credential. Only worth pursuing if the CI system already holds a user token for other reasons (status checks, repo metadata etc.). |
|
||||
| Network isolation | Subnet filtering vs egress VPS |
|
||||
| Network isolation | How to block host localhost from container network namespaces |
|
||||
| Progress reporting | In-container callback channel (socket/HTTP) for async mid-run status |
|
||||
| Multi-stage output passing | Exact format/protocol for stage-to-stage data handoff |
|
||||
|
||||
Reference in New Issue
Block a user