SSO Config is deleted on cascade with the original user who set it up #2042

Closed
opened 2026-03-13 09:22:46 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @jakst on GitHub (Sep 29, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Set up Better Auth with the SSO plugin
  2. Create a user, an organization, and set up SSO credentials for it
  3. Invite another user to the org and make them owner
  4. Delete the original user

Now the SSO credentials for the organization are gone.

Current vs. Expected behavior

I don't expect SSO credentials to be deleted when the user who set the provider up is deleted. I don't understand why there's a user_id column in the sso_providers column at all tbh 🤔

What version of Better Auth are you using?

1.3.9 (also tried with 1.3.23)

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 24.6.0: Mon Jul 14 11:28:30 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T6030",
    "release": "24.6.0",
    "cpuCount": 12,
    "cpuModel": "Apple M3 Pro",
    "totalMemory": "36.00 GB",
    "freeMemory": "0.16 GB"
  },
  "node": {
    "version": "v24.8.0",
    "env": "development"
  },
  "packageManager": {
    "name": "pnpm",
    "version": "10.17.1"
  },
  "frameworks": [
    {
      "name": "solid",
      "version": "1.9.9"
    }
  ],
  "databases": [
    {
      "name": "drizzle",
      "version": "0.44.5"
    }
  ],
  "betterAuth": {
    "version": "1.3.9",
    "config": null
  }
}

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"

export const auth = betterAuth({
  baseURL,
  secret,

  session: {
    cookieCache: {
      enabled: true,
      maxAge: 15 * 60,
    },
  },

  user: {
    deleteUser: {
      enabled: true,
    },
  },

  account: {
    accountLinking: {
      enabled: true,
    },
  },

  advanced: {
    useSecureCookies: true,
  },

  emailAndPassword: {
    enabled: false
  },


  socialProviders: {
    github,
    google,
  },
  
  plugin: [
    admin(),
    oAuthProxy({ currentURL: baseURL }),
    organization({ invitationExpiresIn: INVITATION_EXPIRES_DAYS * 24 * 60 * 60 }),
    sso({ trustEmailVerified: true }),
    emailOTP({/* ... */}),
  ]
});

Additional context

No response

Originally created by @jakst on GitHub (Sep 29, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Set up Better Auth with the SSO plugin 2. Create a user, an organization, and set up SSO credentials for it 3. Invite another user to the org and make them owner 4. Delete the original user Now the SSO credentials for the organization are gone. ### Current vs. Expected behavior I don't expect SSO credentials to be deleted when the user who set the provider up is deleted. I don't understand why there's a `user_id` column in the `sso_providers` column at all tbh 🤔 ### What version of Better Auth are you using? 1.3.9 (also tried with 1.3.23) ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 24.6.0: Mon Jul 14 11:28:30 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T6030", "release": "24.6.0", "cpuCount": 12, "cpuModel": "Apple M3 Pro", "totalMemory": "36.00 GB", "freeMemory": "0.16 GB" }, "node": { "version": "v24.8.0", "env": "development" }, "packageManager": { "name": "pnpm", "version": "10.17.1" }, "frameworks": [ { "name": "solid", "version": "1.9.9" } ], "databases": [ { "name": "drizzle", "version": "0.44.5" } ], "betterAuth": { "version": "1.3.9", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ baseURL, secret, session: { cookieCache: { enabled: true, maxAge: 15 * 60, }, }, user: { deleteUser: { enabled: true, }, }, account: { accountLinking: { enabled: true, }, }, advanced: { useSecureCookies: true, }, emailAndPassword: { enabled: false }, socialProviders: { github, google, }, plugin: [ admin(), oAuthProxy({ currentURL: baseURL }), organization({ invitationExpiresIn: INVITATION_EXPIRES_DAYS * 24 * 60 * 60 }), sso({ trustEmailVerified: true }), emailOTP({/* ... */}), ] }); ``` ### Additional context _No response_
GiteaMirror added the bug label 2026-03-13 09:22:46 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 29, 2025):

This happens because the SSO provider schema includes a userId field that references the user who registered the provider, and the database schema (especially with Drizzle) sets up this foreign key with ON DELETE CASCADE. So, when the original user is deleted, any SSO providers they created are also deleted automatically by the database. There isn't any built-in config or hook in Better Auth to prevent this or to transfer ownership to another user—it's a side effect of the schema design and migration defaults source.

If you want to prevent this, you'll need to update your database schema: either remove the ON DELETE CASCADE from the userId foreign key, make userId nullable, or implement logic to transfer or nullify ownership before deleting a user. This will require a migration and possibly some custom logic in your app to handle SSO provider ownership. There’s no built-in Better Auth option for this right now, so it’s a manual change.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Sep 29, 2025): <!-- Answer --> This happens because the SSO provider schema includes a `userId` field that references the user who registered the provider, and the database schema (especially with Drizzle) sets up this foreign key with `ON DELETE CASCADE`. So, when the original user is deleted, any SSO providers they created are also deleted automatically by the database. There isn't any built-in config or hook in Better Auth to prevent this or to transfer ownership to another user—it's a side effect of the schema design and migration defaults [source](https://github.com/better-auth/better-auth/blob/f6cbdcc84ee5d2971fdcc8b23ff7c174f88cf45b/packages/better-auth/src/plugins/sso/index.ts). If you want to prevent this, you'll need to update your database schema: either remove the `ON DELETE CASCADE` from the `userId` foreign key, make `userId` nullable, or implement logic to transfer or nullify ownership before deleting a user. This will require a migration and possibly some custom logic in your app to handle SSO provider ownership. There’s no built-in Better Auth option for this right now, so it’s a manual change. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/f9db2f0a-2d9a-4391-b5c0-c1221d4a6758?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/f9db2f0a-2d9a-4391-b5c0-c1221d4a6758?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/f9db2f0a-2d9a-4391-b5c0-c1221d4a6758?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/f9db2f0a-2d9a-4391-b5c0-c1221d4a6758?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/f9db2f0a-2d9a-4391-b5c0-c1221d4a6758?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/f9db2f0a-2d9a-4391-b5c0-c1221d4a6758?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/f9db2f0a-2d9a-4391-b5c0-c1221d4a6758?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4971)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#2042