[GH-ISSUE #9031] SSO list providers returns all providers across all org regardless of activeOrganization set in the session #19888

Open
opened 2026-04-15 19:15:02 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @opswiz on GitHub (Apr 8, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/9031

Is this suited for github?

  • Yes, this is suited for github

Reproduction

  1. Create two org
  2. Set organizationId while create a provider
  3. list providers from either of the organization
  4. They get all providers in all organization

Current vs. Expected behavior

When a sso provider is registered for orgnanization. the list provider returns all organizations even when activeOrganizationId is set in the session. The list providers don't seem to also not accept a filter at-least to filter the providers by orgniazation.

ideally list providers should return the SSO providers only belonging to the organization when organizationId is provided while registering the provider

What version of Better Auth are you using?

1.5.6

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.4.0: Thu Mar 19 19:33:09 PDT 2026; root:xnu-12377.101.15~1/RELEASE_ARM64_T8112",
    "release": "25.4.0",
    "cpuCount": 8,
    "cpuModel": "Apple M2",
    "totalMemory": "8.00 GB",
    "freeMemory": "0.11 GB"
  },
  "node": {
    "version": "v24.14.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.9.0"
  },
  "frameworks": [
    {
      "name": "react",
      "version": "19.2.4"
    },
    {
      "name": "hono",
      "version": "^4.12.11"
    }
  ],
  "databases": [
    {
      "name": "@prisma/client",
      "version": "^7.6.0"
    }
  ],
  "betterAuth": {
    "version": "^1.5.6",
    "config": {
      "secret": "[REDACTED]",
      "baseURL": "http://localhost:5150",
      "session": {
        "expiresIn": 172800,
        "updateAge": 86400,
        "cookieCache": {
          "enabled": true,
          "maxAge": 300
        }
      },
      "advanced": {
        "trustedProxyHeaders": true,
        "defaultCookieAttributes": {
          "sameSite": "Strict"
        }
      },
      "account": {
        "accountLinking": {
          "allowDifferentEmails": false,
          "allowUnlinkingAll": true
        }
      },
      "emailVerification": {
        "autoSignInAfterVerification": true
      },
      "emailAndPassword": {
        "enabled": false
      },
      "databaseHooks": {
        "user": {
          "create": {}
        }
      },
      "plugins": [
        {
          "name": "sso",
          "config": {
            "id": "sso",
            "endpoints": {},
            "hooks": {
              "before": [
                {}
              ],
              "after": [
                {}
              ]
            },
            "schema": {
              "ssoProvider": {
                "modelName": "ssoProvider",
                "fields": {
                  "issuer": {
                    "type": "string",
                    "required": true,
                    "fieldName": "issuer"
                  },
                  "oidcConfig": {
                    "type": "string",
                    "required": false,
                    "fieldName": "oidcConfig"
                  },
                  "samlConfig": {
                    "type": "string",
                    "required": false,
                    "fieldName": "samlConfig"
                  },
                  "userId": {
                    "type": "string",
                    "references": {
                      "model": "user",
                      "field": "id"
                    },
                    "fieldName": "userId"
                  },
                  "providerId": {
                    "type": "string",
                    "required": true,
                    "unique": true,
                    "fieldName": "providerId"
                  },
                  "organizationId": {
                    "type": "string",
                    "required": false,
                    "fieldName": "organizationId"
                  },
                  "domain": {
                    "type": "string",
                    "required": true,
                    "fieldName": "domain"
                  },
                  "domainVerified": {
                    "type": "boolean",
                    "required": false
                  }
                }
              }
            },
            "options": {
              "domainVerification": {
                "enabled": true,
                "tokenPrefix": "ops-dv"
              },
              "organizationProvisioning": {
                "disabled": true,
                "defaultRole": "member"
              }
            }
          }
        }
      ],
      "logger": {
        "disabled": false,
        "disableColors": false,
        "level": "debug"
      }
    }
  }
}

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

Backend, Client, Package

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
  plugins: [
        organization({),
        sso({
          domainVerification: {
            enabled: true,
          },
          organizationProvisioning: {
            disabled: true, // disable org provisioning
            defaultRole: 'member', // Default role for new members
          },
    }),
  ]
});

Additional context

No response

Originally created by @opswiz on GitHub (Apr 8, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/9031 ### Is this suited for github? - [x] Yes, this is suited for github ### Reproduction 1. Create two org 2. Set organizationId while create a provider 3. list providers from either of the organization 4. They get all providers in all organization ### Current vs. Expected behavior When a sso provider is registered for orgnanization. the list provider returns all organizations even when activeOrganizationId is set in the session. The list providers don't seem to also not accept a filter at-least to filter the providers by orgniazation. ideally list providers should return the SSO providers only belonging to the organization when organizationId is provided while registering the provider ### What version of Better Auth are you using? 1.5.6 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.4.0: Thu Mar 19 19:33:09 PDT 2026; root:xnu-12377.101.15~1/RELEASE_ARM64_T8112", "release": "25.4.0", "cpuCount": 8, "cpuModel": "Apple M2", "totalMemory": "8.00 GB", "freeMemory": "0.11 GB" }, "node": { "version": "v24.14.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.9.0" }, "frameworks": [ { "name": "react", "version": "19.2.4" }, { "name": "hono", "version": "^4.12.11" } ], "databases": [ { "name": "@prisma/client", "version": "^7.6.0" } ], "betterAuth": { "version": "^1.5.6", "config": { "secret": "[REDACTED]", "baseURL": "http://localhost:5150", "session": { "expiresIn": 172800, "updateAge": 86400, "cookieCache": { "enabled": true, "maxAge": 300 } }, "advanced": { "trustedProxyHeaders": true, "defaultCookieAttributes": { "sameSite": "Strict" } }, "account": { "accountLinking": { "allowDifferentEmails": false, "allowUnlinkingAll": true } }, "emailVerification": { "autoSignInAfterVerification": true }, "emailAndPassword": { "enabled": false }, "databaseHooks": { "user": { "create": {} } }, "plugins": [ { "name": "sso", "config": { "id": "sso", "endpoints": {}, "hooks": { "before": [ {} ], "after": [ {} ] }, "schema": { "ssoProvider": { "modelName": "ssoProvider", "fields": { "issuer": { "type": "string", "required": true, "fieldName": "issuer" }, "oidcConfig": { "type": "string", "required": false, "fieldName": "oidcConfig" }, "samlConfig": { "type": "string", "required": false, "fieldName": "samlConfig" }, "userId": { "type": "string", "references": { "model": "user", "field": "id" }, "fieldName": "userId" }, "providerId": { "type": "string", "required": true, "unique": true, "fieldName": "providerId" }, "organizationId": { "type": "string", "required": false, "fieldName": "organizationId" }, "domain": { "type": "string", "required": true, "fieldName": "domain" }, "domainVerified": { "type": "boolean", "required": false } } } }, "options": { "domainVerification": { "enabled": true, "tokenPrefix": "ops-dv" }, "organizationProvisioning": { "disabled": true, "defaultRole": "member" } } } } ], "logger": { "disabled": false, "disableColors": false, "level": "debug" } } } } ``` ### Which area(s) are affected? (Select all that apply) Backend, Client, Package ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, plugins: [ organization({), sso({ domainVerification: { enabled: true, }, organizationProvisioning: { disabled: true, // disable org provisioning defaultRole: 'member', // Default role for new members }, }), ] }); ``` ### Additional context _No response_
GiteaMirror added the bug label 2026-04-15 19:15:02 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Apr 8, 2026):

This is a confirmed gap in the SSO plugin. The listSSOProviders endpoint (GET /sso/providers) fetches all providers from the database and then filters based on whether the user is an admin/owner in each provider's organization — but it never references session.activeOrganizationId to scope results to the current organization [1].

Specifically, the current logic:

  1. Fetches all providers from the DB with no WHERE clause on organizationId [2]
  2. Splits them into user-owned (no org) and organization-scoped providers [3]
  3. For organization providers, checks if the user is admin/owner in each organization via batchCheckOrgAdmin(), returning providers from all matching orgs [4]

So if you're an admin in Org A and Org B, you'll always get providers from both, regardless of which org is active in your session. There's also no query parameter to filter by organizationId.

As a workaround, you could filter the returned list client-side by organizationId until this is addressed upstream.

To reply, just mention @dosu.


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

<!-- gh-comment-id:4204077945 --> @dosubot[bot] commented on GitHub (Apr 8, 2026): <!-- Answer --> This is a confirmed gap in the SSO plugin. The `listSSOProviders` endpoint (`GET /sso/providers`) fetches **all** providers from the database and then filters based on whether the user is an admin/owner in each provider's organization — but it never references `session.activeOrganizationId` to scope results to the current organization [[1]](https://github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/routes/providers.ts#L156-L234). Specifically, the current logic: 1. Fetches all providers from the DB with no `WHERE` clause on `organizationId` [[2]](https://github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/routes/providers.ts#L178-L181) 2. Splits them into user-owned (no org) and organization-scoped providers [[3]](https://github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/routes/providers.ts#L183-L189) 3. For organization providers, checks if the user is admin/owner in **each** organization via `batchCheckOrgAdmin()`, returning providers from **all** matching orgs [[4]](https://github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/routes/providers.ts#L197-L216) So if you're an admin in Org A and Org B, you'll always get providers from both, regardless of which org is active in your session. There's also no query parameter to filter by `organizationId`. As a workaround, you could filter the returned list client-side by `organizationId` until this is addressed upstream. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=brand-link).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-great_response#message_id=f604e18d-9d0f-462a-99c1-766ce1d79e7e&feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-irrelevant_answer#message_id=f604e18d-9d0f-462a-99c1-766ce1d79e7e&feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-incorrect_sources#message_id=f604e18d-9d0f-462a-99c1-766ce1d79e7e&feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-too_verbose#message_id=f604e18d-9d0f-462a-99c1-766ce1d79e7e&feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-hallucination#message_id=f604e18d-9d0f-462a-99c1-766ce1d79e7e&feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-bug_report#message_id=f604e18d-9d0f-462a-99c1-766ce1d79e7e&feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-other#message_id=f604e18d-9d0f-462a-99c1-766ce1d79e7e&feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=chat-badge)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20is%20a%20confirmed%20gap%20in%20the%20SSO%20plugin.%20The%20%60listSSOProviders%60%20endpoint%20%28%60GET%20/sso/providers%60%29%20fetches%20%2A%2Aall%2A%2A%20providers%20from%20the%20database%20and%20then%20filters%20based%20on%20whether%20the%20user%20is%20an%20admin/owner%20in%20each%20provider%27s%20organization%20%E2%80%94%20but%20it%20never%20references%20%60session.activeOrganizationId%60%20to%20scope%20results%20to%20the%20current%20organization%20%5B%5B1%5D%5D%28https%3A//github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/routes/providers.ts%23L156-L234%29.%0A%0ASpecifically%2C%20the%20current%20logic%3A%0A%0A1.%20Fetches%20all%20providers%20from%20the%20DB%20with%20no%20%60WHERE%60%20clause%20on%20%60organizationId%60%20%5B%5B2%5D%5D%28https%3A//github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/routes/providers.ts%23L178-L181%29%0A2.%20Splits%20them%20into%20user-owned%20%28no%20org%29%20and%20organization-scoped%20providers%20%5B%5B3%5D%5D%28https%3A//github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/routes/providers.ts%23L183-L189%29%0A3.%20For%20organization%20providers%2C%20checks%20if%20the%20user%20is%20admin/owner%20in%20%2A%2Aeach%2A%2A%20organization%20via%20%60batchCheckOrgAdmin%28%29%60%2C%20returning%20providers%20from%20%2A%2Aall%2A%2A%20matching%20orgs%20%5B%5B4%5D%5D%28https%3A//github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/routes/providers.ts%23L197-L216%29%0A%0ASo%20if%20you%27re%20an%20admin%20in%20Org%20A%20and%20Org%20B%2C%20you%27ll%20always%20get%20providers%20from%20both%2C%20regardless%20of%20which%20org%20is%20active%20in%20your%20session.%20There%27s%20also%20no%20query%20parameter%20to%20filter%20by%20%60organizationId%60.%0A%0AAs%20a%20workaround%2C%20you%20could%20filter%20the%20returned%20list%20client-side%20by%20%60organizationId%60%20until%20this%20is%20addressed%20upstream.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=join-discord)&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/9031)
Author
Owner

@opswiz commented on GitHub (Apr 8, 2026):

@dosu

As a workaround, you could filter the returned list client-side by organizationId until this is addressed upstream.

Yeah, but it compromises security, we need to filter or add additional layer on api to filter in backend.

<!-- gh-comment-id:4204150920 --> @opswiz commented on GitHub (Apr 8, 2026): @dosu >As a workaround, you could filter the returned list client-side by organizationId until this is addressed upstream. Yeah, but it compromises security, we need to filter or add additional layer on api to filter in backend.
Author
Owner

@dosubot[bot] commented on GitHub (Apr 8, 2026):

You're right that client-side filtering isn't a proper solution. That said, to clarify the actual security surface here — the endpoint does sanitize provider responses before returning them. Sensitive credentials like OIDC clientSecret and SAML privateKey are completely stripped, and clientId is masked to only show the last 4 characters [1] [2]. So the data leaking across organizations is metadata (issuer, domain, endpoints, certificate fingerprints, etc.), not raw secrets.

Still, that metadata leak is a real concern — an admin in Org A shouldn't be able to see that Org B has an SSO provider configured for a specific domain/issuer, even if the secrets are masked. It's an information disclosure issue, and filtering server-side is the correct fix.

Until this is addressed in the plugin, a practical backend workaround would be to add a middleware or hook on the /sso/providers route that filters the response by the session's activeOrganizationId before it reaches the client:

// Example: server-side filtering via a proxy/wrapper
app.get('/api/sso-providers', async (c) => {
  const response = await auth.api.listSSOProviders({ headers: c.req.raw.headers });
  const session = await auth.api.getSession({ headers: c.req.raw.headers });
  const activeOrgId = session?.session?.activeOrganizationId;
  
  const filtered = response.filter(
    (p) => p.organizationId === activeOrgId || !p.organizationId
  );
  return c.json(filtered);
});

This keeps the filtering server-side while the upstream fix is pending.

To reply, just mention @dosu.


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

<!-- gh-comment-id:4204160139 --> @dosubot[bot] commented on GitHub (Apr 8, 2026): <!-- Answer --> You're right that client-side filtering isn't a proper solution. That said, to clarify the actual security surface here — the endpoint does sanitize provider responses before returning them. Sensitive credentials like OIDC `clientSecret` and SAML `privateKey` are completely stripped, and `clientId` is masked to only show the last 4 characters [[1]](https://github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/routes/providers.ts#L84-L154) [[2]](https://github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/utils.ts#L81-L86). So the data leaking across organizations is metadata (issuer, domain, endpoints, certificate fingerprints, etc.), not raw secrets. Still, that metadata leak is a real concern — an admin in Org A shouldn't be able to see that Org B has an SSO provider configured for a specific domain/issuer, even if the secrets are masked. It's an information disclosure issue, and filtering server-side is the correct fix. Until this is addressed in the plugin, a practical backend workaround would be to add a middleware or hook on the `/sso/providers` route that filters the response by the session's `activeOrganizationId` before it reaches the client: ```ts // Example: server-side filtering via a proxy/wrapper app.get('/api/sso-providers', async (c) => { const response = await auth.api.listSSOProviders({ headers: c.req.raw.headers }); const session = await auth.api.getSession({ headers: c.req.raw.headers }); const activeOrgId = session?.session?.activeOrganizationId; const filtered = response.filter( (p) => p.organizationId === activeOrgId || !p.organizationId ); return c.json(filtered); }); ``` This keeps the filtering server-side while the upstream fix is pending. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=brand-link).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-great_response#message_id=b748e1c7-ab3a-4acf-a5a0-b040379872ea&feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-irrelevant_answer#message_id=b748e1c7-ab3a-4acf-a5a0-b040379872ea&feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-incorrect_sources#message_id=b748e1c7-ab3a-4acf-a5a0-b040379872ea&feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-too_verbose#message_id=b748e1c7-ab3a-4acf-a5a0-b040379872ea&feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-hallucination#message_id=b748e1c7-ab3a-4acf-a5a0-b040379872ea&feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-bug_report#message_id=b748e1c7-ab3a-4acf-a5a0-b040379872ea&feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-other#message_id=b748e1c7-ab3a-4acf-a5a0-b040379872ea&feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=chat-badge)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=You%27re%20right%20that%20client-side%20filtering%20isn%27t%20a%20proper%20solution.%20That%20said%2C%20to%20clarify%20the%20actual%20security%20surface%20here%20%E2%80%94%20the%20endpoint%20does%20sanitize%20provider%20responses%20before%20returning%20them.%20Sensitive%20credentials%20like%20OIDC%20%60clientSecret%60%20and%20SAML%20%60privateKey%60%20are%20completely%20stripped%2C%20and%20%60clientId%60%20is%20masked%20to%20only%20show%20the%20last%204%20characters%20%5B%5B1%5D%5D%28https%3A//github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/routes/providers.ts%23L84-L154%29%20%5B%5B2%5D%5D%28https%3A//github.com/better-auth/better-auth/blob/c665898953a7e9357152a4a1392fd3657a269ffd/packages/sso/src/utils.ts%23L81-L86%29.%20So%20the%20data%20leaking%20across%20organizations%20is%20metadata%20%28issuer%2C%20domain%2C%20endpoints%2C%20certificate%20fingerprints%2C%20etc.%29%2C%20not%20raw%20secrets.%0A%0AStill%2C%20that%20metadata%20leak%20is%20a%20real%20concern%20%E2%80%94%20an%20admin%20in%20Org%20A%20shouldn%27t%20be%20able%20to%20see%20that%20Org%20B%20has%20an%20SSO%20provider%20configured%20for%20a%20specific%20domain/issuer%2C%20even%20if%20the%20secrets%20are%20masked.%20It%27s%20an%20information%20disclosure%20issue%2C%20and%20filtering%20server-side%20is%20the%20correct%20fix.%0A%0AUntil%20this%20is%20addressed%20in%20the%20plugin%2C%20a%20practical%20backend%20workaround%20would%20be%20to%20add%20a%20middleware%20or%20hook%20on%20the%20%60/sso/providers%60%20route%20that%20filters%20the%20response%20by%20the%20session%27s%20%60activeOrganizationId%60%20before%20it%20reaches%20the%20client%3A%0A%0A%60%60%60ts%0A//%20Example%3A%20server-side%20filtering%20via%20a%20proxy/wrapper%0Aapp.get%28%27/api/sso-providers%27%2C%20async%20%28c%29%20%3D%3E%20%7B%0A%20%20const%20response%20%3D%20await%20auth.api.listSSOProviders%28%7B%20headers%3A%20c.req.raw.headers%20%7D%29%3B%0A%20%20const%20session%20%3D%20await%20auth.api.getSession%28%7B%20headers%3A%20c.req.raw.headers%20%7D%29%3B%0A%20%20const%20activeOrgId%20%3D%20session%3F.session%3F.activeOrganizationId%3B%0A%20%20%0A%20%20const%20filtered%20%3D%20response.filter%28%0A%20%20%20%20%28p%29%20%3D%3E%20p.organizationId%20%3D%3D%3D%20activeOrgId%20%7C%7C%20%21p.organizationId%0A%20%20%29%3B%0A%20%20return%20c.json%28filtered%29%3B%0A%7D%29%3B%0A%60%60%60%0A%0AThis%20keeps%20the%20filtering%20server-side%20while%20the%20upstream%20fix%20is%20pending.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=join-discord)&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/9031)
Author
Owner

@surendarcs commented on GitHub (Apr 8, 2026):

Hi,
https://github.com/better-auth/better-auth/pull/9037
look into this

<!-- gh-comment-id:4205629996 --> @surendarcs commented on GitHub (Apr 8, 2026): Hi, https://github.com/better-auth/better-auth/pull/9037 look into this
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#19888