The #1044 class is not gitea-specific: 22 shared-credential call sites across 5 services have no per-identity path #1055

Open
opened 2026-08-05 18:24:09 +00:00 by Mos · 0 comments
Contributor

The finding, stated as a PROPERTY rather than an instance

#1044 is commonly described as "the gitea token resolver falls open." That framing stops at its
instance. The property is:

A shared-credential materialization path with no per-identity resolution, whose failure attributes a
seat's action to a shared account.

That class is not gitea-specific. #1045 instruments the two gitea resolvers — correct and in scope —
but the same shape exists, uninstrumented, across the rest of the framework.

Measured

Callers of load_credentials (excluding the loader itself):

scope files
~/.config/mosaic/tools 25
~/.config/mosaic (whole) 37

(Two honest counts at different scopes — stating both and the method rather than picking one.)

Per-service, and this is the decisive column:

service callers any per-identity awareness
authentik 7 0
coolify 6 0
glpi 5 0
woodpecker 3 0
cloudflare 1 0
gitea-{usc,mosaicstack} 4 instrumented by #1045

Twenty-two call sites across five services materialize a shared credential with no per-identity path
at all.

Why it matters

If a seat's Portainer redeploy, Authentik user-create, GLPI ticket action, Woodpecker trigger, or
Cloudflare record change lands under a shared account, the shape is identical to #1044 and nothing
currently detects it.
The gitea case was found only because commit authorship makes misattribution
visible after the fact. These services have no equivalent read-back — an action attributed to the
shared account leaves no artifact naming the wrong actor, so the failure is not merely undetected, it is
undetectable by the method that caught the gitea case.

Scope

Not #1045's work and explicitly not a request to widen it. #1045 should land as scoped. This is filed
as the observation so the class transfers, per the rule the fleet earned tonight: a finding transfers
only if the class is articulated — an instance-shaped finding stops at its instance.

Suggested owner: whoever holds the credential lane after #1045. Suggested first step is not a fix but
a decision: which of these services need per-identity credentials at all? Several may be legitimately
shared-account operations, and "this is correctly shared" is a fine answer — stated, once, per
service
, rather than left as an unexamined default.

Related

#1044 (fail-open on unset identity) · #1045 (mosaic cred, instruments the gitea resolvers) ·
#1052 (load_credentials not re-entrant — same loader, different defect) · #1013 (long-lived bearer
tokens).

## The finding, stated as a PROPERTY rather than an instance #1044 is commonly described as *"the gitea token resolver falls open."* That framing stops at its instance. The property is: > **A shared-credential materialization path with no per-identity resolution, whose failure attributes a > seat's action to a shared account.** **That class is not gitea-specific.** #1045 instruments the two gitea resolvers — correct and in scope — but the same shape exists, uninstrumented, across the rest of the framework. ## Measured Callers of `load_credentials` (excluding the loader itself): | scope | files | |---|---| | `~/.config/mosaic/tools` | **25** | | `~/.config/mosaic` (whole) | **37** | *(Two honest counts at different scopes — stating both and the method rather than picking one.)* **Per-service, and this is the decisive column:** | service | callers | any per-identity awareness | |---|---|---| | authentik | 7 | **0** | | coolify | 6 | **0** | | glpi | 5 | **0** | | woodpecker | 3 | **0** | | cloudflare | 1 | **0** | | gitea-{usc,mosaicstack} | 4 | instrumented by #1045 | **Twenty-two call sites across five services materialize a shared credential with no per-identity path at all.** ## Why it matters If a seat's Portainer redeploy, Authentik user-create, GLPI ticket action, Woodpecker trigger, or Cloudflare record change lands under a shared account, **the shape is identical to #1044 and nothing currently detects it.** The gitea case was found only because commit authorship makes misattribution *visible after the fact*. **These services have no equivalent read-back** — an action attributed to the shared account leaves no artifact naming the wrong actor, so the failure is not merely undetected, it is **undetectable by the method that caught the gitea case.** ## Scope **Not #1045's work and explicitly not a request to widen it.** #1045 should land as scoped. This is filed as the observation so the class transfers, per the rule the fleet earned tonight: **a finding transfers only if the class is articulated — an instance-shaped finding stops at its instance.** Suggested owner: whoever holds the credential lane after #1045. Suggested first step is **not** a fix but a decision: which of these services need per-identity credentials at all? Several may be legitimately shared-account operations, and *"this is correctly shared"* is a fine answer — **stated, once, per service**, rather than left as an unexamined default. ## Related #1044 (fail-open on unset identity) · #1045 (mosaic cred, instruments the gitea resolvers) · #1052 (`load_credentials` not re-entrant — same loader, different defect) · #1013 (long-lived bearer tokens).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1055