Bootstrap admin from proxy.is_admin + dev-mode honesty (one identity contract, both halves) #20
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_collab#20
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Two coupled gaps in collab's identity contract
After running collab in
--auth-mode=proxyend-to-end (withhero_proxyinjectingX-Hero-Uservia OAuth/IP-auto-login), I hit two issues that are really the two halves of the same architectural property: hero_proxy injects identity headers; hero_collab decides whether and how to act on them. Today collab's behaviour is inconsistent in both auth modes.Half 1 — Proxy mode: bootstrap deadlock
handlers/user.rs::meauto-provisions a new user row whenX-Hero-Useris set but no collab user exists yet. The auto-provisioned user lands with zero rights — no group memberships, no group_rights row. So:user.mesucceeds, creates a row for themcaller 'N' lacks permission for 'X.create'Chicken-and-egg on every fresh deployment. Today's escape hatch is direct SQL against
~/.hero/var/data/hero_collab/collab.db— not acceptable as the standard install flow.Repro
Half 2 — Dev mode: silent picker bypass
main.rs::handle_rpcprocesses anyX-Hero-Userheader it receives, regardless of--auth-mode. When the operator runs--auth-mode=devAND hasuser_networksrows inhero_proxy.proxy.dbmatching their loopback (a separate hero_proxy concept they may not even know is active), the chain becomes::9997find_user_for_ip(127.0.0.1)→ matchesuser_networks→ injectsX-Hero-User: sameh@example.comchat-app.js::init()seesauthenticated:true→ picker silently doesn't appearThis is confusing because:
--auth-mode=devwas explicitly set to "I want pickers / multi-user testing"user_networksis a hero_proxy concept; the collab operator may not realise it's overriding their dev-mode intentThe principle is: in dev mode, collab should be the source of truth for identity — period. Anything the proxy injects should be ignored.
Why one issue / one PR
These are the two halves of a single architectural property. Splitting them would leave collab in a half-honest state: either "proxy mode works but dev mode is silently broken" or "dev mode is honest but proxy mode has the bootstrap deadlock." Either intermediate state is more confusing than landing them together.
Fix shape
Half 1 (bootstrap admin in proxy mode)
In
handlers/user.rs's first-INSERT path ofuser.me:hero_proxy_sdk::users_list()for the identifier (3s timeout, mirrorsfederation::fetch_federated_users).is_admin = 1for this user → grant collab system admin.The fallback mirrors hero_osis's
first user_create gets Owner rolepattern. The grant is idempotent (INSERT OR IGNOREintogroups,group_members,group_rights).Half 2 (dev-mode honesty)
4-line shim at the top of
handle_rpcthat mapshero_usertoNonewhenstate.auth_mode == AuthMode::Dev, with atracing::debugso operators can see in logs that the header was dropped.Combined behaviour matrix
user_networksPR
Fix in
feat/admin-bootstrap. ~170 LOC acrosshandlers/user.rs+main.rs. No schema change. Uses already-importedhero_proxy_sdk.