{{define "admin_users"}} Accounts · llmgw

Accounts

{{len .Pending}} waiting for approval · {{len .Active}} active

{{if .Error}}

{{.Error}}

{{end}} {{if .Message}}

{{.Message}}

{{end}}

Waiting for approval

{{if .Pending}} {{range .Pending}}{{end}}
EmailNameSigned upProject
{{.Email}}{{.Name}}{{ago .CreatedAt}}
{{else}}

Nobody is waiting.

{{end}}

Accounts

{{if .Active}} {{range .Active}}{{end}}
EmailStateAdminProjectLast login
{{.Email}} {{.State}} {{if .IsAdmin}}yes{{else}}—{{end}} {{or .ProjectID "—"}} {{ago .LastLoginAt}} {{if eq (printf "%s" .State) "active"}}
{{else}}
{{end}}
{{else}}

No accounts yet.

{{end}}

Organizations, teams and projects

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.

{{if not .Orgs}}

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. */}} {{range .Projects}}{{end}} {{if not .Projects}}{{end}}
Organization / team / projectID
{{.Path}}{{.ID}}
No projects yet, so nobody can be approved.
{{end}}

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.

{{end}}