diff --git a/README.md b/README.md index c355c35a..4448be80 100644 --- a/README.md +++ b/README.md @@ -90,9 +90,10 @@ box it gets: [subagent](docs/tools/subagent.md) - **forge** — its own Forgejo account, the `hive-forge` CLI, git credentials, and notifications turned into todos. Optional linked - accounts on other forges, and GitHub (`gh` + push) via + accounts on other forges, GitLab (`glab` + push), and GitHub (`gh` + push) via `services.hyperhive.agent.github.enable`. → - [forge](docs/integrations/forge.md) · [github](docs/integrations/github.md) + [forge](docs/integrations/forge.md) · [gitlab](docs/integrations/gitlab.md) · + [github](docs/integrations/github.md) - **matrix** — its own account(s) on the swarm homeserver, as MCP tools. → [matrix](docs/tools/matrix.md) - **knowledge** — the swarm's shared `internal/knowledge` repo, read-only diff --git a/docs/README.md b/docs/README.md index 16caa0e8..7aa65bc6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -58,6 +58,8 @@ declarations. the PAT injected?** → [`integrations/github.md`](integrations/github.md) (operator content up top; the `gh`/git-push + notification-poller mechanics are in a collapsed "Implementation" section at the bottom). +- **How to give an agent GitLab accounts (`glab` + `git push`, more than one + instance)?** → [`integrations/gitlab.md`](integrations/gitlab.md). - **What's `/knowledge`? How does the swarm-wide knowledge repo sync, and how to contribute a document?** → [`integrations/knowledge.md`](integrations/knowledge.md). - **What does `hivectl` do? Provisioning, gateway users, container diff --git a/docs/integrations/gitlab.md b/docs/integrations/gitlab.md new file mode 100644 index 00000000..e2563437 --- /dev/null +++ b/docs/integrations/gitlab.md @@ -0,0 +1,88 @@ +# GitLab accounts + +Give an agent managed accounts on one or more GitLab instances: a `glab` CLI +and `git push` over HTTPS, both authenticated by operator-supplied access +tokens, with no manual `glab auth login`. + +An agent can hold any number of accounts, each under a label you choose. Two labels +can name two instances, such as `gitlab.com` and a self-hosted one. Provisioning +needs no per-agent nix declaration and no rebuild: the agent fetches its tokens +from the swarm secret store itself. + +## Linking an account + +The swarm UI has no GitLab dialog yet, so link an account with the controller's +API. This is the same route family as the other +[linked accounts](../swarm/ui.md#linking-external-accounts): + +```text +PUT /api/hives/{hive}/agents/{agent}/gitlab-accounts/{label} +{"url": "https://gitlab.example.org", "token": ""} +``` + +- `label` is lowercase letters, digits and hyphens. It names the account in the + store and in the account list. +- `url` is the instance's base URL. The host must be a DNS name: an IP + address, `localhost` and a single-label name get a 400, because the agent + reaches the instance through its hive's egress proxy, which takes names + only. A port and a subfolder (`https://example.org:8443/gitlab`) are part of + the address. The path may hold letters, digits and `. _ ~ / -`; a URL with + user information, a query, a fragment or any other character gets a 400, so + every stored account is one the agent uses. +- A plain `http://` URL works, and then the token crosses the network in + cleartext. Use `https://` unless the instance sits on a trusted network. +- `token` is a GitLab personal, group or project access token. Scope it + `api` and `write_repository`: `glab` needs the first, and `git push` over + HTTPS needs the second. Use a dedicated bot account and the narrowest token + that does the agent's work, because the agent has passwordless sudo and can + act within the token's scopes. + +A label that holds an account already answers 409; delete it first +(`DELETE .../gitlab-accounts/{label}`), then link again. No route hands a +token back. `GET /api/hives/{hive}/agents/{agent}/linked-accounts` lists the +account as kind `gitlab`, with its label and URL. + +Linking also allows the instance's host in the agent's egress, as a +`link:gitlab: