Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/docs/integrations/gitlab.md

91 lines
4.6 KiB
Markdown

# 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
In the swarm UI, open an agent, choose **link account**, then **gitlab
account**. Fill in a label, the instance URL (it starts as `https://gitlab.com`)
and the token. The form shows the recommended scopes and the controller's
answer if it refuses the input. The linked account appears in the agent's list
of [linked accounts](../swarm/ui.md#linking-external-accounts) with a delete
action. The UI calls the controller's API, which you can also call directly:
```text
PUT /api/hives/{hive}/agents/{agent}/gitlab-accounts/{label}
{"url": "https://gitlab.example.org", "token": "<access 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:<label>` entry on the swarm's allowed-domains list. swarm-controller
derives the host from the URL it stored, so nothing the agent writes can widen
its egress. Deleting the account removes the entry.
## What the agent gets
An agent with a store identity (`services.hyperhive.agent.bao.addr`) has:
- the `glab` command, which reads its configuration from `<state>/glab/`;
- a git credential helper, `git-credential-hive-gitlab`, for each linked
instance;
- the `hive-agent-gitlab-accounts` unit and its timer.
The unit logs in to the store with the agent's own certificate, lists
`swarm/agents/<agent>/gitlab/`, reads each account, and writes two files in
`<state>/glab/` (mode `0600`) on boot and every two minutes, replacing a file
only when its content changed:
- `config.yml`, `glab`'s own configuration with one `hosts` entry per instance,
keyed by host and port, holding the token, the API protocol and the
subfolder. It sets `git_protocol: https`. The `host` default is the first
label's instance; inside a repository `glab` uses the host of its remote.
- `gitconfig`, one `[credential "<scheme>://<host>"]` block per instance, which
`/etc/gitconfig` includes. The helper answers only for a host that has an
account, so it never touches GitHub or the swarm's forge.
The unit generates both files. A deleted account leaves them on the next run, and
a hand edit doesn't survive. `glab` keeps one token per host: when two labels
name the same host, the first label in alphabetical order wins. If the unit
can't read one of the accounts, it replaces nothing and retries, so the files
keep the last complete set.
The unit fails fast and restarts itself every 30 seconds for up to a day, as
the other store fetches do, so a store that's down or sealed never holds the
container's boot open.
## Rolling out
The endpoint, the store path and the agent unit are new, and each end ignores
what it doesn't know. An old controller has no GitLab route, so no account gets
linked. An old agent has no unit, so a stored account sits unused. A new agent
under an old controller lists a store directory that doesn't exist and writes an
empty `glab` configuration.