Files
mesh-catalog/modules/gitea/cmd/agent-teams/main.go
T
jschoubben 64c893e2c2 F-catalog-B: the gitea module removes the npm pair's teams packages and readers and their accounts
ADR 0605 §5 revokes the npm write token, and the 14:04 deferral is withdrawn (security review F5): the
accounts the removed pair provisioner made (mesh_<node>_<consumer>) still logged in with write on the
organisation's packages. cmd/agent-teams, run at each start of the module and change of its teams value,
removes both teams and each account of that form whose only teams they are, never purging: one the forge
refuses to delete because it owns something keeps it and has its login prohibited.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
2026-11-04 17:15:41 +01:00

45 lines
1.6 KiB
Go

// agent-teams: the agents' read teams on the forge (novox/hq ADR 0365 clause 3, issue 758). A program the node's
// runtime runs once when the module starts and again whenever the module's config value `agent-read-teams` changes:
// it reads the file the mesh renders from that value, and makes the forge's teams named agent-read-* match it. Each
// team reads only; its repositories and its members (agent accounts, agent-<node>) are exactly the value's. It
// touches nothing else of the value's kind: no team without the prefix, no repository or account of another kind. Beside
// the value it removes what the module made once and declares no more (retire.go): the npm pair's teams packages and
// readers and the accounts in them alone.
//
// It says each change on stdout in one line, and never a secret.
package main
import (
"context"
"fmt"
"os"
"time"
"gitea/internal/forgehttp"
)
func main() {
forge, missing := forgehttp.FromEnv()
file := os.Getenv("MESH_AGENT_TEAMS_FILE")
if file == "" {
missing = append(missing, "MESH_AGENT_TEAMS_FILE")
}
if len(missing) > 0 {
fmt.Fprintf(os.Stderr, "agent-teams: %v not set by the manifest; nothing was changed\n", missing)
os.Exit(1)
}
value, err := ReadValue(file)
if err != nil {
fmt.Fprintln(os.Stderr, "agent-teams:", err)
os.Exit(1)
}
s := &Syncer{Forge: forge, Log: func(format string, a ...any) { fmt.Printf(format+"\n", a...) },
WaitFor: 3 * time.Minute, Poll: 5 * time.Second}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
if err := s.Sync(ctx, value); err != nil {
fmt.Fprintln(os.Stderr, "agent-teams:", err)
os.Exit(1)
}
}