GitHub
11/07/2026, 4:33 PMuser_admin, env_manager, read_only_admin, alert_admin. Role checks live in pkg/users/roles.go (HasRole, HasRoleContext, SetRoles, CheckManageUser) and reuse the per-request permission cache.
• API: role fields are on AdminUserView, GET /users/me and PATCH /users/me. ApiUserRequest takes them as optional booleans; leaving a field out leaves that role unchanged.
• Log-content alert rules (result_log, query_log, status_log) stay superuser-only for now. That covers creating, editing and deleting them, the channels they use (update, delete and test-send), and their alert history. History for non-superusers fails closed: only rows from currently existing non-log-content rules, filtered in the query before the limit. This gets relaxed in part 2.
• Alert channel secrets (reveal=1) are revealed only to superusers.
• Environment names must be unique on create and rename.
• CLI: osctrl-cli user add and user edit take --user-admin, --env-manager, --read-only-admin and --alert-admin, plus --no-… variants on edit. Both the DB and API paths work.
• OpenAPI is regenerated.
Security / operational impact
• Upgrade is a no-op for access. Existing global admins become superusers with no data migration. New columns default to false. Existing environment permissions are unchanged.
• New escalation paths were reviewed and closed. User admin → superuser is blocked and fails closed on DB errors. An environment manager can no longer take over another environment by renaming it and recreating its name. Alert admins can't exfiltrate log content or channel secrets.
• Known gap, not fixed here: nodes are linked to environments by name, and rename/delete don't migrate or remove osquery_nodes. After a superuser renames or deletes an environment, someone who recreates that name inherits its orphaned nodes. Marked with a shortcut: comment; follow-up PR.
• By design, per the spec: user admins can grant themselves any per-environment access and any non-superuser role.
• No frontend changes in this PR. The UI keeps keying off admin until part 5, so the new roles are grantable through the API and CLI only.
Validation
• `go test ./...`: pass
• `gofmt`: clean
• `make openapi-check`: clean
• `cd frontend && npm run check`: pass
• New tests: pkg/users/roles_test.go and cmd/api/handlers/{users,environments,readonly}_roles_test.go, plus additions to alerts_test.go and cmd/cli/user_roles_test.go. They cover every role × endpoint gate, check the database after each refusal, and test the escalation paths above.
• `golangci-lint`: 13 errcheck warnings, all in files this PR doesn't touch.
• Not run: Playwright (no frontend change).
jmpsec/osctrlGitHub
11/07/2026, 4:40 PM