docs: ADR 0038 — identity field ownership and the single edit surface #63

Sammanfogat
supernaut sammanfogade 1 incheckning från docs/adr-0038-identity-ownership in i main 2026-08-02 07:26:11 +00:00
Ägare

Records the decision behind the identity work: one place to edit each field, and
no field visible in two systems with different values.

Why

A user faces three account surfaces — Gitborg Auth, the portal, and the Git
application — and nothing tells them which is authoritative. That is an
integration gap rather than a presentation problem: Forgejo reads OIDC claims
once, when the account is created on first sign-in, and never again. Its copies
of the full name and email are therefore a local fork with no merge path back,
in either direction.

Today that means nobody has a meaningful display name anywhere, and the email
address is editable only in the one place where editing it has no effect.

What it decides

Gitborg Auth stays the owner of identity data. The portal becomes the single
place it is edited — because a verified email change needs to send mail, and
the identity provider cannot. Splitting it, with the name in one place and the
email in another, would reproduce the problem being solved.

The systems that do not own a field conceal it, using the styling hook each
already ships. Concealment and enforcement are deliberately separate mechanisms
and both are required: concealment alone leaves the API open, and enforcement
alone means users edit a field and watch it silently revert.

Username becomes fixed at sign-up. It is the owner segment of every repository
URL an account holds, so renaming is an operator action.

Worth reviewing closely

  • The never-clear rule: an absent attribute means "unknown", never "empty".
    A partial read must not be able to blank every user's identity.
  • The consequences section, particularly the widened read privilege and the
    fact that concealment can break silently on an upstream upgrade.
  • The alternatives, especially "signpost only" — the cheapest option, and a
    reasonable thing to disagree with me about.

Merge order

This ADR describes work in three other repositories. The projection should land
and run before any field is concealed, so that values are already correct when
the UI stops offering them.

Records the decision behind the identity work: one place to edit each field, and no field visible in two systems with different values. ## Why A user faces three account surfaces — Gitborg Auth, the portal, and the Git application — and nothing tells them which is authoritative. That is an integration gap rather than a presentation problem: Forgejo reads OIDC claims once, when the account is created on first sign-in, and never again. Its copies of the full name and email are therefore a local fork with no merge path back, in either direction. Today that means nobody has a meaningful display name anywhere, and the email address is editable only in the one place where editing it has no effect. ## What it decides Gitborg Auth stays the owner of identity data. The portal becomes the single place it is edited — because a verified email change needs to send mail, and the identity provider cannot. Splitting it, with the name in one place and the email in another, would reproduce the problem being solved. The systems that do not own a field conceal it, using the styling hook each already ships. Concealment and enforcement are deliberately separate mechanisms and both are required: concealment alone leaves the API open, and enforcement alone means users edit a field and watch it silently revert. Username becomes fixed at sign-up. It is the owner segment of every repository URL an account holds, so renaming is an operator action. ## Worth reviewing closely - The **never-clear rule**: an absent attribute means "unknown", never "empty". A partial read must not be able to blank every user's identity. - The **consequences** section, particularly the widened read privilege and the fact that concealment can break silently on an upstream upgrade. - The **alternatives**, especially "signpost only" — the cheapest option, and a reasonable thing to disagree with me about. ## Merge order This ADR describes work in three other repositories. The projection should land and run before any field is concealed, so that values are already correct when the UI stops offering them.
supernaut lade till 1 incheckning 2026-08-02 07:12:08 +00:00
docs: add ADR 0038 — identity field ownership and the single edit surface
Alla kontroller lyckades
ci / ci (pull_request) Successful in 12s
fa117fc828
Records why a user faces three account surfaces and no way to tell which is
authoritative: Forgejo's OIDC support is provisioning-only, so its full_name and
email are a local fork with no merge path back.

Kanidm stays the data owner; the portal becomes the one edit surface, because a
verified email change needs a mail sender and Kanidm has none. Splitting it —
name in Kanidm, email in the portal — would reproduce the original problem, so
both live in the portal.

Notes the two constraints that shaped it: Forgejo has no config value for the
full-name or email fields, and Kanidm cannot verify an address. Hence
concealment via each system's existing CSS hook plus enforcement by the
reconciler, which are separate mechanisms and both required.

Consequences cover the reconciler's widened Kanidm privilege, the upgrade risk
of CSS selectors, and the loss of commit attribution when a primary address
changes.
supernaut sammanfogade incheckning 4b22e6d24f till main 2026-08-02 07:26:11 +00:00
supernaut tog bort grenen docs/adr-0038-identity-ownership 2026-08-02 07:26:11 +00:00
Logga in för att delta i denna konversation.
Inga granskare
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-docs!63
Ingen beskrivning angiven.