feat: role-based tool access, confirmation gates, and new orchestrator tools

- auth_utils: get_user_role() reads role from auth.json (admin|user, default user)
- manage_passwords: new `role` command to promote/demote users (admin-only by convention)
- tools/__init__: TOOL_ROLES map, CONFIRM_REQUIRED set, get_tools_for_role(),
  get_openai_tools_for_role() — both orchestrators now filter tools by caller's role
- tools/system: cortex_restart (detached subprocess, 5s delay), cortex_logs (admin-only)
- tools/web: http_fetch — direct URL fetch, distinct from web_search
- tools/files: file_list (directory listing), file_write (restricted paths, admin-only)
- tools/notify: nc_talk_send — proactive outbound via notification.py
- orchestrator_engine + openai_orchestrator: user_role param; CONFIRM_REQUIRED tools
  return a confirmation-request result instead of executing — loop breaks after Claude
  asks user to confirm in a follow-up message
- home/scott/auth.json: role set to admin

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-04-29 19:23:53 -04:00
parent 1603ad5124
commit 334e7f0dea
10 changed files with 581 additions and 87 deletions

View File

@@ -170,6 +170,25 @@ def cmd_google_add(args):
print(f"They can now sign in at {settings.cortex_base_url}/login using that Google account.")
def cmd_role(args):
if len(args) < 2:
print("Usage: manage_passwords.py role <username> admin|user")
sys.exit(1)
username, role = args[0], args[1].lower().strip()
if role not in ("admin", "user"):
print("Role must be 'admin' or 'user'.")
sys.exit(1)
from auth_utils import _read_auth, _write_auth
data = _read_auth(username)
if not data:
print(f"User '{username}' not found — no auth.json.")
sys.exit(1)
old_role = data.get("role", "user")
data["role"] = role
_write_auth(username, data)
print(f"Role for '{username}': {old_role}{role}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print(__doc__)
@@ -190,6 +209,8 @@ if __name__ == "__main__":
cmd_invite(rest)
elif command == "google-add":
cmd_google_add(rest)
elif command == "role":
cmd_role(rest)
else:
print(f"Unknown command: {command}")
print(__doc__)