92 lines
2.9 KiB
Markdown
92 lines
2.9 KiB
Markdown
|
|
# Multi-Agent Forgejo Infrastructure
|
||
|
|
|
||
|
|
Setting up a self-hosted Forgejo instance for multi-agent teams. Each agent host gets its own machine user, SSH key, and scoped permissions. No shared credentials.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
```
|
||
|
|
Forgejo (code.example.org:2222)
|
||
|
|
├── user: admin (bootstrap only)
|
||
|
|
├── user: agent-1 (write all repos, browser UI for PR review)
|
||
|
|
├── user: agent-2 (write all repos, SSH only)
|
||
|
|
└── user: agent-3 (write all repos, SSH only)
|
||
|
|
|
||
|
|
Vaultwarden (vault.example.org)
|
||
|
|
└── org: ProjectName
|
||
|
|
├── collection: agent-secrets (day-to-day passwords, tokens)
|
||
|
|
├── collection: bootstrap (admin tokens, setup keys)
|
||
|
|
└── collection: deploy (deploy secrets)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Setup Order
|
||
|
|
|
||
|
|
### 1. Create repos via API
|
||
|
|
|
||
|
|
Forgejo API needs a token with: `write:repository`, `write:user`, `write:organization`.
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl -X POST "https://<forgejo>/api/v1/user/repos" \
|
||
|
|
-H "Authorization: token <token>" \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"name":"repo-name","description":"...","private":false}'
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Create machine users via admin API
|
||
|
|
|
||
|
|
Requires `write:admin` scope on the token.
|
||
|
|
|
||
|
|
- Untick "require password change" for SSH-only users.
|
||
|
|
- Keep it ticked for users that need browser access (e.g. Hermes for PR review).
|
||
|
|
- Emails: use per-agent aliases for audit trail.
|
||
|
|
|
||
|
|
### 3. Register SSH keys via admin API
|
||
|
|
|
||
|
|
Keys registered under the admin account get credited to the admin, not the machine user. Always use the admin API endpoint for the target user:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# WRONG — adds to admin's keys
|
||
|
|
curl -X POST "https://<forgejo>/api/v1/user/keys" ...
|
||
|
|
|
||
|
|
# CORRECT — adds to target user
|
||
|
|
curl -X POST "https://<forgejo>/api/v1/admin/users/<username>/keys" \
|
||
|
|
-H "Authorization: token <admin-token>" \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"key":"ssh-ed25519 AAA...","title":"<username>@<host>","read_only":false}'
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. Set repo collaborators
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl -X PUT "https://<forgejo>/api/v1/repos/<owner>/<repo>/collaborators/<user>" \
|
||
|
|
-H "Authorization: token <token>" \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"permission":"write"}'
|
||
|
|
```
|
||
|
|
|
||
|
|
HTTP 204 = success. Requires `write:repository` on the token.
|
||
|
|
|
||
|
|
### 5. SSH config per host
|
||
|
|
|
||
|
|
```ssh-config
|
||
|
|
Host code.example.org
|
||
|
|
HostName code.example.org
|
||
|
|
User git
|
||
|
|
Port 2222
|
||
|
|
IdentityFile ~/.ssh/forgejo-<username>
|
||
|
|
IdentitiesOnly yes
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6. Bootstrap token lifecycle
|
||
|
|
|
||
|
|
Create → use for setup → **delete immediately after**.
|
||
|
|
|
||
|
|
API token deletion is not exposed externally on Forgejo. Delete manually at `https://<forgejo>/user/settings/applications`. Day-to-day git operations use SSH keys only — no tokens needed.
|
||
|
|
|
||
|
|
## Agent Self-Serve Doc
|
||
|
|
|
||
|
|
After initial setup, agents on new hosts can self-bootstrap by reading a FORGEJO-SETUP.md doc in the repo. Template at `templates/FORGEJO-SETUP.md`.
|
||
|
|
|
||
|
|
## Vaultwarden Integration
|
||
|
|
|
||
|
|
See `references/vaultwarden-bw-cli.md` for the full `bw` CLI workflow: login→unlock→session→lock pattern, collection management, and quirks.
|