load_credentials gitea-mosaicstack cannot succeed: loader expects a flat token key, config is per-seat #1083

Open
opened 2026-08-06 20:33:41 +00:00 by Mos · 0 comments
Contributor

Summary

load_credentials gitea-mosaicstack cannot succeed on a host whose credentials.json uses per-seat keys. The loader reads a flat .token; the config provides per-seat entries. The result is a hard failure on the documented path every agent is told to use.

Evidence

Key names only — no values read or shown.

tools/_lib/credentials.sh:186   GITEA_TOKEN <- .gitea.mosaicstack.token      <- what the loader reads

credentials.json  gitea.mosaicstack keys = default · homelab_jarvis · homelab_mos
                                          · url · usc_jarvis · usc_mos       <- NO `token` key
                  gitea.usc         keys = description · token · url · username   <- flat, loads fine

The loader exports GITEA_URL, then the non-empty guard at :189 fires and GITEA_TOKEN stays empty. The error text names gitea.mosaicstack.token — a key the config does not use — so the message points away from the cause.

Impact

On the affected host, two of three agents that need git.mosaicstack.dev are blind to it. This is not a revoked credential and not a permissions decision: the credentials are present under per-seat names, and the documented reader cannot reach them. It reads like a migration where the config shape moved and the loader did not.

Suggested direction

Not prescribing the fix, since the intended end state is an operator decision:

  • If per-seat keys are the target shape, teach the loader to resolve a seat (e.g. from MOSAIC_GIT_IDENTITY) with default as the documented fallthrough; or
  • if flat is the target shape, migrate the config; or
  • support both and say which wins.

Whichever is chosen, the failure message should name the key that was actually looked for and the shape that was found, since the current text names neither.

Explicitly not done

No agent selected another seat's key to work around this. Picking a named seat's credential by hand is identity inheritance performed deliberately, and no one tests a credential fallthrough by obtaining a shared token. The affected seats remained read-only and blind by choice.

No closing keywords intended; none used.

## Summary `load_credentials gitea-mosaicstack` **cannot succeed** on a host whose `credentials.json` uses per-seat keys. The loader reads a flat `.token`; the config provides per-seat entries. The result is a hard failure on the documented path every agent is told to use. ## Evidence Key names only — no values read or shown. ``` tools/_lib/credentials.sh:186 GITEA_TOKEN <- .gitea.mosaicstack.token <- what the loader reads credentials.json gitea.mosaicstack keys = default · homelab_jarvis · homelab_mos · url · usc_jarvis · usc_mos <- NO `token` key gitea.usc keys = description · token · url · username <- flat, loads fine ``` The loader exports `GITEA_URL`, then the non-empty guard at `:189` fires and `GITEA_TOKEN` stays empty. The error text names `gitea.mosaicstack.token` — a key the config does not use — so the message points away from the cause. ## Impact On the affected host, two of three agents that need `git.mosaicstack.dev` are blind to it. This is not a revoked credential and not a permissions decision: the credentials are present under per-seat names, and the documented reader cannot reach them. It reads like a migration where the **config shape moved and the loader did not**. ## Suggested direction Not prescribing the fix, since the intended end state is an operator decision: - If per-seat keys are the target shape, teach the loader to resolve a seat (e.g. from `MOSAIC_GIT_IDENTITY`) with `default` as the documented fallthrough; or - if flat is the target shape, migrate the config; or - support both and say which wins. Whichever is chosen, the failure message should name **the key that was actually looked for and the shape that was found**, since the current text names neither. ## Explicitly not done No agent selected another seat's key to work around this. Picking a named seat's credential by hand is identity inheritance performed deliberately, and no one tests a credential fallthrough by obtaining a shared token. The affected seats remained read-only and blind by choice. No closing keywords intended; none used.
Mos added the bug label 2026-08-06 20:33:41 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1083