Declare the forge-account provision, its provider bundle, its fact and the keys it reads (issue 955 F4)

This commit is contained in:
2026-10-16 22:46:27 +02:00
parent c346bba34e
commit 1081a5f3ea
3 changed files with 55 additions and 0 deletions
+12
View File
@@ -221,3 +221,15 @@ whenever the tools' account is set up, with the administrator's login (`GiteaAdm
account is no repository's administrator, so no tool can. A rule found keeps the statuses it requires; a repository
with none is given one that requires none. `judgeProtectionChange` refuses, for `main`, a change that enables
push, drops the merge whitelist or widens it past that account.
## The forge account for git over ssh (novox/hq ADR 0399, ADR 0400, issue 955)
Gitea provides `forge-account`, and `cmd/forge-account-provider` answers its consumers (the `ssh-client` of each
machine). The provision has no credential: a public key is no secret. For a machine whose ssh-client has reported its
key in the state `keys` (read, `ssh-client.keys`), the provider makes the account `agent-<node>` in the agents team
(`internal/forgeaccount`, the code `cmd/agent-token` shares), registers the key under the title `mesh:<node>.<account>`,
and serves the entry values `user`, `ssh_host` (the forge machine's mesh name, from the fact `forge-host`), `ssh_port`,
`known_host` (read from the forge's own sshd with `ssh-keyscan`), `ssh_base` and `https_base`. A machine that has
reported no key gets no entry, and its client says it waits. Keys titled `mesh:` that are no longer wanted are removed,
a key added by hand never is. Every consumer is made again every ten minutes and at once when a key changes.
`go test ./cmd/forge-account-provider ./internal/forgeaccount` runs it against a fake forge.
+1
View File
@@ -0,0 +1 @@
${consumers:forge-account}
+42
View File
@@ -177,6 +177,12 @@
"default": "mesh-tools mesh-admin jschoubben"
}
},
"facts": {
"forge-host": {
"path": "/etc/gitea/forge-host",
"template": "{{range .Machines}}{{if eq .Name $.Node}}{{.FQDN}}{{end}}{{end}}\n"
}
},
"resources": [
{
"id": "mesh-state",
@@ -313,6 +319,13 @@
"agent-read-teams"
]
},
{
"id": "consumers",
"type": "file",
"path": "${dir:state}/consumers.json",
"mode": "0600",
"template": "files/consumers.json"
},
{
"id": "agent-teams",
"type": "process",
@@ -353,6 +366,10 @@
"issued-by": "software",
"tool": "gitea_agent_token"
}
},
{
"name": "forge-account",
"scope": "mesh"
}
],
"build": {
@@ -451,6 +468,25 @@
"loads": [
"agent-teams"
]
},
{
"name": "forge-account-provider",
"kind": "bundle",
"language": "go",
"system": "arch",
"from": "cmd/forge-account-provider",
"binary": "forge-account-provider",
"loads": [
"forge-account-provider"
],
"env": {
"MESH_GITEA_URL": "http://127.0.0.1:${port:3000}",
"MESH_GITEA_ADMIN_USER": "mesh-admin",
"MESH_GITEA_ADMIN_PASSWORD_FILE": "${dir:state}/admin.secret",
"MESH_GITEA_ORIGINS_FILE": "${dir:mesh-state}/origins",
"MESH_GITEA_SSH_PORT": "222",
"MESH_FORGE_HOST_FILE": "/etc/gitea/forge-host"
}
}
]
},
@@ -460,5 +496,11 @@
"failregex": "^.*Failed authentication attempt for .* from <HOST>(?::\\d+)?\\s*$\n ^.*Invalid user .* from <HOST> port \\d+\\s*$\n ^.*User \\S+ from <HOST> not allowed because .*$",
"jail": "backend = systemd\njournalmatch = CONTAINER_NAME=gitea\nport = http,https,222\nmaxretry = 3\nfindtime = 1d\nbantime = 1d"
}
],
"state": [
"bound"
],
"reads": [
"ssh-client.keys"
]
}