{{define "admin_users"}}
{{len .Pending}} waiting for approval · {{len .Active}} active
{{.Error}}
{{end}} {{if .Message}}{{.Message}}
{{end}}| Name | Signed up | Project | ||
|---|---|---|---|---|
| {{.Email}} | {{.Name}} | {{ago .CreatedAt}} | ||
Nobody is waiting.
{{end}}| State | Admin | Project | Last login | ||
|---|---|---|---|---|---|
| {{.Email}} | {{.State}} | {{if .IsAdmin}}yes{{else}}—{{end}} | {{or .ProjectID "—"}} | {{ago .LastLoginAt}} | {{if eq (printf "%s" .State) "active"}} {{else}} {{end}} |
No accounts yet.
{{end}}Where an account lives. A person is approved into a project, a project belongs to a team, and a team to an organization — and a quota can be written on any of the three, so the shape here is the shape the bill takes.
No organizations yet. Create one, then a team in it, then a project in the team — an account can only be approved into a project.
{{else}} {{/* One path column, not three: the store returns the chain already joined, which is the string the approval chooser shows, and three headers over one value line up with nothing. */}}| Organization / team / project | ID |
|---|---|
| {{.Path}} | {{.ID}} |
| No projects yet, so nobody can be approved. | |
Four things are deliberately not here. Making someone an admin,
resetting a password, issuing keys on another
person's behalf and setting any quota all need a shell on the control plane — llmgw users promote,
reset-password, llmgw keys, llmgw keys limits.
A stolen admin session can approve, suspend and make somewhere to put people; it
cannot hand itself more access, take over an account, or raise what anybody is
allowed to spend.