Skip to content

PostgreSQL installs seed the admin with email = username, so the first-run "Sign-in email" step never appears #3554

Closed

Description

@obasilakis

Build: v1.0.0-rc2 (96f88f9). Row: B24 (Trinity 1.0 testing matrix).

Steps

  1. Install from the published images with the bundled PostgreSQL and a provisioned admin password: TRINITY_IMAGE_TAG=v1.0.0-rc2 bash scripts/deploy/trinity-do-create.sh (which runs start.sh --provision --cloud digitalocean --hosted --unattended with ADMIN_PASSWORD set).
  2. Sign in as admin.

Observed

  • GET /api/users/me → {"username":"admin","email":"admin","name":null,"picture":null,"role":"admin"}.
  • select id, username, email, role from users → 1|admin|admin|admin.
  • The first-run overlay lists five steps: Secure this instance, Connect Claude, Other keys, Your first agent, Usage sharing. The "Sign-in email" step is absent.
  • Settings → Access → User Management shows the admin's email as admin.

Expected
The admin created from ADMIN_PASSWORD has no email, the first-run overlay offers the "Sign-in email" step, and docs/user-docs/guides/deploying/digitalocean.md ("lists six steps: Secure this instance, Sign-in email, Connect Claude, Other keys, Your first agent and Usage sharing") matches what the operator sees.

Cause
The two database tracks seed the admin differently.

  • PostgreSQL: the admin-seeding path in src/backend/database.py calls UserOperations.update_user_password(), whose create branch in src/backend/db/users.py inserts email=username.
  • SQLite: src/backend/database.py runs INSERT INTO users (username, password_hash, role, created_at, updated_at), leaving email NULL.

The overlay's email step is eligible for an admin and pending while !hasEmail (components/onboarding/firstRunSteps.js), and hasEmail is !!auth.userEmail. With email = "admin" it is truthy, so the step never renders. The step's own comment says it exists for exactly this install shape (the ADMIN_PASSWORD-provisioned one, "where nobody was ever asked").

docker-compose.hosted.yml bundles PostgreSQL, so every hosted install provisioned with an admin password takes the PostgreSQL branch. The code is the same on dev.

Not checked
Whether anything else reads the admin's email and misbehaves on the literal admin (email-code sign-in, agent sharing by email, notifications).

Suggested fix
Insert the admin with no email in the update_user_password() create branch, matching the SQLite track, and add a migration (both tracks) that nulls users.email where it equals users.username and contains no @.

Activity

  1. added
    status-readyGreenlit and ready for development (vetted; counterpart to status-incubating)
    complexity-lowComplexity: low (board points 1-3)
    on Oct 12, 2026
  2. added and removed
    status-readyGreenlit and ready for development (vetted; counterpart to status-incubating)
    on Oct 19, 2026
  3. self-assigned this
    on Oct 19, 2026
  4. added 2 commits that reference this issue on Oct 19, 2026
  5. added
    status-in-devMerged to dev, awaiting release cut to main
    and removed on Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions