Files
headquarter/openspec/changes/archive/2026-05-22-repo-clone-mode-with-ssh/design.md
T
Fusion 063a839790 feat: implement repository clone mode with SSH key support
- Add clone_mode and branch fields to tool_instances
- Add ssh_key_id to git_repositories for per-repo SSH key assignment
- Implement host-side git cloning with branch selection (default: main)
- Mount SSH keys into containers for git operations in clone mode
- Add dirty state check on clone-mode instance deletion with confirmation
- Update SessionsPage with mount/clone selector, branch input, SSH key display
- Add SSH key selector to repository creation form
- Add dirty delete confirmation modal with changed files list
- Update API schemas and endpoints for new fields
- Sync delta specs to main specs (git-repo, tool-instances, repo-clone-mode)
- Archive completed OpenSpec change: repo-clone-mode-with-ssh
- Document git requirement for custom tool types

Quality gates: Frontend typecheck and build passed
OpenSpec: repo-clone-mode-with-ssh archived with all tasks complete
2026-05-22 22:56:35 +02:00

4.3 KiB

Context

Currently, all tool instances bind-mount the host repository path via {{REPO_PATH}} substitution in compose templates. The repository model (GitRepository) has no SSH key association. The instance model (ToolInstance) has no concept of repository access mode.

Users want two modes:

  1. Mount (current): Live sync with working copy on host
  2. Clone (new): Fresh isolated copy with full git history inside the container

The SSH key system already exists with encrypted private keys in the database. Keys can be project-scoped or user-scoped.

Goals / Non-Goals

Goals:

  • Allow per-instance choice between mount and clone mode
  • Support branch selection for clone mode (default: main)
  • Enable git operations inside containers via SSH key mounting
  • Protect against accidental data loss with dirty check on clone deletion
  • Allow SSH key assignment at repository creation and later modification

Non-Goals:

  • Modifying existing tool type compose templates
  • Installing git in containers (assumes tool images have git or install it)
  • Multiple SSH keys per container
  • Automatic push/pull/sync between host and container
  • Shallow clones (full history only)

Decisions

1. Host-Side Clone (not in-container)

Decision: Clone happens on the host before container start, not inside the container.

Rationale:

  • No changes to compose templates required
  • Works with all existing tool types immediately
  • No need for git/SSH inside every container image
  • Host has direct filesystem access to the clone
  • Easier error handling and rollback

Alternative considered: In-container clone via command override. Rejected because it requires git in every image, SSH auth setup inside containers, and makes error handling fragile.

2. SSH Key Mounting via _modify_compose_file

Decision: Inject SSH key volume dynamically at container start time using the existing _modify_compose_file helper.

Rationale:

  • Zero changes to tool type definitions
  • Consistent with how other runtime overrides work (port, command, working_dir, extra_volumes)
  • Mounts the .ssh/ directory with key + config into container

Implementation:

instance_dir/.ssh/
  id_ed25519      (decrypted private key, mode 600)
  id_ed25519.pub  (public key)
  config          (StrictHostKeyChecking no)

Mounted as: instance_dir/.ssh:/root/.ssh:ro (or appropriate home dir)

3. Single SSH Key per Repository

Decision: The SSH key is stored on GitRepository and used for both clone and container access.

Rationale:

  • Natural association: a repository's clone URL determines which SSH key is needed
  • Simpler UX: one key per repo, not per session
  • Session creation can override (future enhancement) but defaults to repo key

4. Dirty Check via git status --short

Decision: Check for uncommitted changes using git status --short before allowing deletion of clone-mode instances.

Rationale:

  • Simple and reliable
  • Catches staged, unstaged, and untracked files
  • Fast (local filesystem operation)

Risks / Trade-offs

[Risk] Disk space usage → Each clone-mode instance duplicates the full repository. Mitigation: Instance deletion removes the clone directory.

[Risk] Clone time for large repos → Synchronous clone during instance creation may timeout. Mitigation: No timeout on clone operation; consider async clone in future.

[Risk] SSH key permissions in containers → Some containers run as non-root users. The .ssh directory mount needs correct ownership. Mitigation: Mount as read-only; container's entrypoint may need to copy to writable location if needed.

[Risk] Git not installed in custom tool images → User-defined tool types may not have git. Mitigation: Document requirement; built-in types already have or install git.

[Risk] SSH host key checking → Cloning from new hosts may fail. Mitigation: SSH config sets StrictHostKeyChecking no for clone operations.

Migration Plan

  1. Run Alembic migrations to add new columns
  2. Existing instances default to clone_mode='mount' (no behavior change)
  3. Existing repositories have ssh_key_id=null (no behavior change until assigned)
  4. No data migration needed

Open Questions

  • Should the .ssh mount be read-only or writable? (Writable needed if container generates new keys, but we don't support that)
  • Should we support submodules in cloned repos?