Skip to content

Account and pod deletion: admins first, then the right to erasure #17

Closed

Description

@nicolasdb

Why

CSS 7.2 deletes no account and no pod (README, "Accounts and pods"). So:

  • a pod name, once taken, stays taken, and every test round burns names (pocpod0 collected many throwaway accounts);
  • a test instance can only be cleaned by a full reset (docker compose down -v), which stops working the day a real account lives there;
  • the right to erasure (GDPR art. 17) cannot be honoured, not even by an admin.

Agreed shape

From ROADMAP.md:

  1. Admin deletion, inside CSS: a component on an admin route under /.account/, using CSS's own stores and locks. It deletes the pods' resources depth first, then delete('account', id) (logins, pods, WebID links, client credentials in one go). Deleting from the volume from outside is ruled out: that storage format is CSS's private business, and a script would race the server's locks.
  2. Admins = login emails listed in the instance's config.
  3. Front doors, all calling that one route:
    • scripts/admin.sh (list, delete-account) + a make target on the VPS;
    • an account-manager page in the overlay (accounts and their pods, a delete button each).
  4. Outside CSS: the connector's identities.json entries for a deleted WebID go too (mcp-connector/src/identityRegistry.js).
  5. Then self-service erasure: "Delete my account" on the person's own account page, same route limited to their account, password asked again, and the page says plainly what goes (their pods and everything in them, their WebID, the agents' access).

Blocking

  • A solid-kit ADR first (next is 012). It would be the image's second component after pod-name-guard, and CLAUDE.md makes that a decision, not a commit: every component is code to carry across every CSS release (ADR 009).
  • Check upstream before building: does CSS main / 8.0 bring account deletion itself? 8.0 already breaks pod-name-guard's context (ROADMAP, "Next stock CSS"), so a second component doubles that carry cost. The answer goes into the ADR.
  • How admins are configured: a list of emails reaching the config at start. Same mechanism as the CSS email settings, which are also written at start from the environment (add an SMTP provider for CSS mapsofmaking/maps_of_making#15): settle it there first, reuse it here.

Waits on this

Handoffs

  • Design and the ADR: solid-kit (docs/adr/), where the image's components are decided.
  • Build: here, beside pod-name-guard/; the gate before a tag in CLAUDE.md, plus a test that deletes an account with a pod and checks the name can be taken again.
  • Connector cleanup: mcp-connector/ in this repo.
  • Backoffice: the account page's "Delete my account" may live in solid-backoffice rather than the overlay's stock pages; to decide in the ADR.

🤖 Generated with Claude Code

Activity

  1. nicolasdb commented on Nov 3, 2026

    @nicolasdb
    OwnerAuthor

    Upstream check (one of the blocking boxes), done 2026-11-03 on the stock images:

    • edge = 7.3.0 (Node 24) and next = 8.0.0-alpha.3: the only delete handlers under dist/identity/interaction are DeleteClientCredentialsHandler and DeletePasswordHandler. No account deletion, no pod deletion, no new .account/ route for either.
    • Not checked: CSS main commits after alpha.3, and upstream issues/PRs that may be planning it.

    So as of today, neither the next 7.x nor the 8.0 alpha brings deletion. This goes into ADR 012 (draft in solid-kit).

  2. added a commit that references this issue on Nov 3, 2026
  3. nicolasdb commented on Nov 3, 2026

    @nicolasdb
    OwnerAuthor

    Slice 1 (admin delete) is in #35, with ADR 012 accepted in nicolasdb/solid-kit#19. CI is green on both layouts: an account with a pod is deleted by an admin, a non-admin gets 403 and nobody signed in gets 401, the login stops working, and the same pod name is taken again (200).

    Finding while building: the resource store refuses to delete a pod root (root storage, Solid §5.4), and createPod answers 409 while anything is at the base. So the root goes through the data accessor under the write lock.

    Still open here: slice 2 (admin.sh list, the account-manager page, a make target in vps-infra) and slice 3 (self-service erasure, once its home is decided).

    🤖 Generated with Claude Code

  4. added a commit that references this issue on Nov 3, 2026
  5. nicolasdb commented on Nov 3, 2026

    @nicolasdb
    OwnerAuthor

    Adding leaving altogether to this issue, found while resetting a mom-home test pod (nicolasdb/solid-kit#22 covers leaving one app):

    • Archive before retire. Before deleting, offer an export of the pod (its files, as they are, in one download) so leaving never means losing. Possibly an "archived" state: the pod read-only, then deleted after a delay.
    • Revoke apps' sign-ins. Deleting the account must end the client authorizations it granted (home, backoffice, connector), together with the identities.json cleanup in point 4.
    • Order when a space is on Maps of Making: off the map first (mapsofmaking/maps_of_making unregister issue), then the pod. Otherwise the map keeps a pin to a 404.
    • The ADR here and solid-kit#22 should read as one story: leaving an app vs. leaving the pod.

    🤖 Generated with Claude Code

  6. nicolasdb commented on Nov 3, 2026

    @nicolasdb
    OwnerAuthor
  7. nicolasdb commented on Nov 3, 2026

    @nicolasdb
    OwnerAuthor

    Where this stands (2026-11-03)

    Admin side: done, in 7.3.0-4 (#35, #36, #37, release #38; ADR 012 + its amendment in solid-kit#19, #20, #21).

    • scripts/admin.sh opens a TUI on the server's terminal. It lists, sorts, filters, selects and deletes accounts with their pods, then removes the connector's agents for them.
    • The permission is the server's shell: a token the container renews at each start. There is no admin email list, because CSS never verifies emails.
    • Tried end to end on Maps of Making (rc.1): 9 test accounts were deleted, the server stayed healthy, and the names are free again. Docs: docs/admin/ (Diataxis).

    Correction to the dependency map: this issue no longer waits on its ADR or on an upstream check. ADR 012 is accepted, and CSS up to 7.3.0 and 8.0.0-alpha.3 has no deletion, checked 3 Nov. What is still open is the next stage below.

    Next stage: leaving altogether (self-service)

    One story with nicolasdb/solid-kit#22. Leaving an app (solid-kit#22 → mapsofmaking/mom-home#48 → nicolasdb/solid-backoffice#16) removes one app's footprint. Leaving the pod (here) removes everything. "Delete my account" runs these steps, in this order:

    1. Archive. Offer an export of the pod, its files as they are, in one download. Leaving never means losing.
    2. Off the map first (A space leaves the map: unregister, read from its own file mapsofmaking/maps_of_making#73), when the space is on Maps of Making. Otherwise the map keeps a pin to a 404. Generic form: an app's footprint declaration (solid-kit#22) can say "this app published you somewhere", and the page lists those before deleting.
    3. End the apps' sign-ins. This is a finding to verify first. CSS keeps OIDC grants, sessions and refresh tokens in .internal/idp/adapter/. Its findAccount does not check that the account still exists, so deleting the account probably does not end them. A refresh token could keep minting tokens for that WebID until it expires.
      • For a WebID inside a deleted pod, that is mostly harmless: the profile is gone, so verifiers reject the tokens.
      • For a WebID hosted elsewhere and linked to the account, it is a real gap.
      • Needs a test: sign in an app, delete the account, try a refresh. If confirmed, the deletion also removes the account's grants, read through the data accessor as the listing now does (CSS's own entries() stalls on the lock files: see docs/admin/explanation.md). This also applies to the admin deletion that shipped.
    4. Delete pods and account: the same deletion as the admin side, already proven.
    5. Connector clean-up: the same removeIdentitiesFor.

    The door. Same deletion code, different permission: the person's own sign-in plus their passphrase typed again. Shape: POST /.account/account/<id>/delete/ behind stock AuthorizedRouteHandler, checked with PasswordStore.authenticate.

    Where the button lives (ADR 012's open question). Recommendation: the route lives in the overlay, so every instance gets it, and the button lives in solid-backoffice#16, beside "Apps that keep data here". Steps 1 and 2 need what the backoffice already reads: the pod, and the apps' footprints. The stock account page gets one line pointing there.

    Slices (each usable on its own)

    Slice What Depends on
    3a the route: own account, passphrase again, the deletion. Smoke: sign up, delete yourself, the name is free, the login is gone nothing
    3b end the sign-ins: the test above, then remove the grants if confirmed (admin deletion too) 3a for the self-service case; the admin case can go first
    3c archive: one download of the pod nothing (could be a backoffice feature)
    3d off the map before deleting mapsofmaking/maps_of_making#73, solid-kit#22 for the generic form
    3e the button and the page that says plainly what goes solid-backoffice#16, 3a

    Before 3a: a second amendment to ADR 012 (self-service door, order of steps, where the button lives), deliberated with solid-kit#22 so the two read as one story.

    🤖 Generated with Claude Code

  8. nicolasdb commented on Nov 3, 2026

    @nicolasdb
    OwnerAuthor

    Re-scoped (2026-11-03). 7.3.0-4 is released, with account and pod deletion by the instance's admins from the server's terminal.

    Leaving altogether is bigger than this issue. It is the endgame of the person's journey, a validation story for every vertical, so it is parked where the journeys live: nicolasdb/solid-kit#23 (introduction → onboarding → scaffolding → leaving altogether). The self-service slices planned above (3a–3e) are opened from there when that journey is scheduled.

    One piece stays here, as its own issue, because it touches what already shipped: #39, deleting an account may not end the sign-ins it granted (test first).

    Suggest closing this issue as done for its first half (admins). The right to erasure continues in solid-kit#23.

    🤖 Generated with Claude Code

  9. nicolasdb commented on Nov 3, 2026

    @nicolasdb
    OwnerAuthor

    Closed: admin half done in 7.3.0-4. The right to erasure continues in nicolasdb/solid-kit#23, the sign-in follow-up in #39.

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions