91 lines
4.6 KiB
Markdown
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.
|