Skip to content

user login should report the roles the alias holds — a wallet's other access tokens log in just as cleanly #153

Description

@workshop-maybe

Problem

user login reports that a session exists. It does not report who you now are, usefully.

Today, a successful headless login prints:

Authenticated as: qa-1778157478
User ID:
Key hash: d0b21a57da040e65d1ef7dfab1b17f68c421bdf9303b6608146ead43
Session expires: 2026-08-25T19:18:43Z

Every line of that is true for an alias that can do nothing. A wallet can hold several Andamio access tokens,
and user login --alias X succeeds for any of them — the gateway verifies the signature against the
address, and every token in that wallet passes. There is no error, no warning, and user status shows an
active session.

The failure only surfaces later, as an empty result that is indistinguishable from "there is genuinely nothing
to do":

$ andamio teacher assignments list --output json
{"data":[]}          # exit 0

That is correct per the failure contract — an empty result must be exit 0 — which is exactly why it cannot be
the place this gets caught. The distinction that is missing is "you hold no teacher role at all" versus
"you are a teacher and have no pending reviews."

How this bit us

During the #152 preprod sweep, preprod-wallets/andamio-preprod-001 turned out to hold three access tokens:

Alias Teacher courses Commitments awaiting review
qa-1778157478 2 1 (SUBMITTED)
tester_0001 3 0
andamio-preprod-001 1 not surveyed

#152's own text named the wrong one. Following it literally produces a run that logs in cleanly, lists
courses, finds nothing to assess, and reports success — having exercised the headline feature not at all. It
took an explicit wrong-alias control run to establish that, and nothing in the CLI would have volunteered it.

Proposal

Have user login print the roles the authenticated alias actually holds:

Authenticated as: qa-1778157478
Roles: teacher on 2 courses, owner of 2 courses, manager of 0 projects
Session expires: 2026-08-25T19:18:43Z

And say so plainly when there are none:

Roles: none — this alias holds no owner, teacher or manager role.
       If you expected otherwise, check which access token you meant:
       a wallet can hold several, and login succeeds for any of them.

Cost: one call, to an endpoint the CLI already uses

Resolved 2026-08-24 — this was originally filed asking whether three role lookups were too expensive. They
are not needed.
GET /api/v1/user/me, already wired up as andamio user me, returns the whole summary in
one request:

{"data":{"counts":{
  "teaching_courses": 2,
  "managing_projects": 1,
  "pending_reviews": 1,
  "enrolled_courses": 0,
  "contributing_projects": 0,
  "total_credentials": 0
}}}

Measured across all three access tokens in preprod-wallets/andamio-preprod-001:

Alias teaching_courses managing_projects pending_reviews
qa-1778157478 2 1 1
tester_0001 3 0 0
andamio-preprod-001 5 4 1

pending_reviews is the field that actually discriminates. tester_0001 — the alias #152 wrongly named —
reads 0, which is exactly the trap. One integer at login catches what previously took a wrong-alias
control run to establish.

So the implementation is: after a successful login, issue the existing user me call and print a line from
counts. No new endpoint, no new client code.

Remaining design notes:

  • Where: stderr, per the composability rules — it is human-facing progress, not data. user login has no
    --output json payload today, so nothing structured breaks.
  • Failure handling (the one real risk): a user me call that errors must not fail the login. The
    session is valid regardless; degrade to printing the alias alone. A cosmetic lookup must never fail an
    authentication.
  • Applies to both login paths — headless (--skey) and browser. The browser flow is the more likely place
    for a human to pick the wrong identity, since they choose it in a wallet UI.
  • user status is local-only today (no network calls). Adding roles there would change that property, so
    login is the better home unless we want status to gain a --refresh-style flag.

Release scoping

Worth deciding deliberately rather than by merge order. 1.0 is merged to main but not tagged (#128,
gated on the mainnet 2.5 cutover in andamio-ops#189). Anything landing on main now ships as 1.0 — after
the #152 sweep that just certified 1.0's surface against the v2.5.0-rc5 gateway.

This is a new user-facing behaviour, not a defect fix found by that sweep, so landing it now would change what
was validated. Recommend it goes after the 1.0 tag unless there is a reason to pull it forward, in which
case it needs a CHANGELOG entry and a re-verify of the login leg.

Related

  • Andamio-Platform/andamio-dev#18 — the documentation half: the acceptance-test prerequisites assume one
    access token per wallet. Docs and tooling are complementary here; neither alone closes this.
  • #152 — the sweep that surfaced it. Evidence in docs/validation/2026-08-preprod-v2.5.0-rc5.md, § Finding 1.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions