Files
headquarter/openspec/changes/git-connection-model/design.md
T
alex 024278a3d2 docs(openspec): add FN-007 Git Connection Model change
- Add proposal, design, specs, and tasks for git connection model
- Include provider adapter, credential storage, SSH key lifecycle specs
- Add repository connection API and git operations specifications
2026-05-16 13:43:49 +02:00

79 lines
3.0 KiB
Markdown

## Context
The platform has a Git abstraction layer in `apps/api/app/git/` with:
- `provider.py`: GitProvider ABC (validate_connection, list_repos, create_deploy_key, delete_deploy_key, get_default_branch)
- `connection.py`: ConnectionManager (connect/disconnect/get_connection)
- `credentials.py`: GitCredential, AccessTokenCredential, CredentialStorage ABC
- `ssh_key.py`: SshKeyPair, SshKeyLifecycle with Ed25519 generation
- `operations.py`: GitOperations ABC, LocalGitOperations (clone/fetch/push are NotImplementedError)
- `types.py`: ProviderKind, CredentialKind, ConnectionStatus, SshKeyStatus enums
Current gaps:
- No concrete provider adapters (GitHub, GitLab)
- CredentialStorage has no database implementation
- LocalGitOperations is incomplete
- No RepositoryConnection router or API endpoints
- SSH key generation uses base64 placeholder
## Goals / Non-Goals
**Goals:**
- Implement concrete GitHub and GitLab provider adapters
- Create database-backed credential storage with encryption
- Complete LocalGitOperations with credential-aware subprocess
- Add RepositoryConnection router with CRUD endpoints
- Generate Ed25519 SSH keys and register deploy keys
- Frontend UI for repository connections and SSH key management
**Non-Goals:**
- Support for Gitea/Forgejo (deferred post-MVP)
- GitHub/GitLab OAuth app integration (use personal access tokens)
- Webhook management
- Repository mirroring
- Branch protection management
## Decisions
**1. Use httpx for provider API calls**
- Rationale: Already in dependencies, async support, consistent with FastAPI
- Alternative: requests - blocking, would need thread pool
**2. Store credentials encrypted with Fernet (same as secrets)**
- Rationale: Consistent with existing secret storage in FN-009
- Implementation: Reuse encryption service from app/encryption.py
**3. SSH keys generated per-repository (not per-user)**
- Rationale: Fine-grained access control, easy revocation per repo
- Alternative: Per-user keys - broader blast radius on compromise
**4. Provider adapters implement GitProvider ABC**
- Rationale: Clean abstraction, easy to add new providers
- Implementation: GitHubAdapter, GitLabAdapter with unified interface
**5. Git operations use subprocess with SSH key in temp file**
- Rationale: Standard git CLI is most reliable
- Implementation: Write key to temp file, set GIT_SSH_COMMAND env var
## Risks / Trade-offs
**[Risk] Personal access tokens have broad permissions**
→ Mitigation: Document minimal required scopes (repo read/write, deploy key management)
**[Risk] SSH keys in temp files are briefly exposed on disk**
→ Mitigation: Use 0600 permissions, clean up immediately after operation
**[Risk] Provider API rate limits**
→ Mitigation: Cache repository lists, implement exponential backoff
**[Risk] Token storage compromise**
→ Mitigation: Fernet encryption with rotation support
## Migration Plan
No migration. New feature.
## Open Questions
1. Should we support SSH key passphrases?
2. Do we need to validate repository URLs before connection?
3. Should we auto-detect provider from URL?