Skip to content

12 November 2026

B2B login on your own identity provider

A proof of concept: Shopify B2B buyers sign in through the company's own identity provider (Keycloak over OpenID Connect) instead of Shopify's native login, and land in a B2B session that carries their company, location, catalogue and prices. A working lab, and the seven things the docs leave out.

The short version. A B2B buyer can sign in to a Shopify Plus store with your own authentication rather than Shopify’s native login, and still land exactly where a B2B buyer should: inside their company account, with their company’s catalogue and prices. Two jobs make that work. The identity provider proves who the buyer is. Shopify’s native B2B carries the company data. One binding step joins them, and it has to happen before the buyer’s first sign-in. We built this as a proof of concept on a development store with Keycloak, and published the lab so you can run it yourself.

This is a proof-of-concept note, not a case study. The lab uses a generic realm and a demo buyer, and nothing in it belongs to a client.


1. Why bring your own login to Shopify B2B

Many B2B operations already run an identity platform. Their trade customers sign in to an ordering portal, a service desk and a documents area with one account, governed by one set of rules: password policy, MFA, who gets switched off when they leave. Asking those buyers to keep a separate Shopify login, with its own one-time codes, splits that governance in two.

Shopify Plus lets a store hand customer sign-in to an external provider over OpenID Connect. Shopify’s documentation walks through Auth0, Okta, Microsoft Entra ID and Amazon Cognito. It does not cover Keycloak, the open-source identity server a lot of B2B estates run, and it says nothing about how B2B company contacts behave once an external provider is in front of the login. That gap is what this proof of concept fills.

2. The shape of it

sequenceDiagram
    actor Buyer
    participant Store as Shopify storefront
    participant Accounts as Shopify customer accounts
    participant IdP as Keycloak (your identity provider)
    participant Integration as Your integration layer

    Integration->>Accounts: Before go-live, seed the buyer and bind them to their company and location
    Buyer->>Store: Chooses Sign in
    Store->>Accounts: Customer accounts flow
    Accounts->>IdP: Authorization request (code flow, no PKCE challenge)
    IdP->>Buyer: Login form, with your rules (password, MFA)
    Buyer->>IdP: Credentials
    IdP->>Accounts: Authorization code
    Accounts->>IdP: Token request (client id and secret)
    IdP->>Accounts: ID token and refresh token (email, email_verified, sub)
    Accounts->>Store: Shopify matches the customer by email and opens the session
    Store->>Buyer: B2B session with company, location, catalogue and prices

Keycloak is connected in the Shopify admin as a Custom or other OpenID Connect provider. When a buyer signs in, Shopify hands them to Keycloak, Keycloak authenticates them and returns an ID token, and Shopify matches the customer by email. If that customer is already a contact of a company, the session that opens is a B2B session: their location, their catalogue, their prices.

The token itself carries no company. The connection imports a fixed set of claims (email, name, phone, address, tags) and has no way to assign a company or a location. The company binding is an admin-side step your integration performs with two Admin API calls, companyAssignCustomerAsContact and companyLocationAssignRoles. That split is the point of the design: your identity platform owns authentication, and Shopify’s native B2B owns the commercial relationship.

3. What we proved on the store

On a Shopify Plus development store, with Keycloak as the active provider:

  • A seeded company contact signs in through Keycloak and lands in their B2B account, with the location picker, the location’s catalogue and its prices, and Add to cart available.
  • An unverified email is refused. Shopify sends the buyer to a “verify your email” step and does not let them in.
  • The session outlives the access token. With a 60-second access token in Keycloak, the buyer was still signed in minutes later: Shopify refreshes in the background.
  • Signing out from the account menu signs the buyer out of Keycloak too. Shopify performs an RP-initiated logout: it calls the realm’s end-session endpoint with the ID token and returns to a registered address. We saw it in the Keycloak log.

4. Seven things the docs leave out

1. Do not enforce PKCE. This one stops you at the first step. Shopify connects as a confidential client, with a client id and secret, and sends no PKCE challenge. If your realm enforces PKCE, Keycloak rejects the authorization request with “Missing parameter: code_challenge_method” and Shopify’s connection test fails with a bare 400. Keycloak still accepts PKCE from clients that send it; just do not require it.

2. Every user needs the offline_access role, explicitly. Shopify asks for the offline_access scope because it wants a refresh token. Without the role, the login looks fine right up to the token exchange, which fails with “Offline tokens not allowed for the user or client.” The role is a realm default, but users brought in through a realm import do not receive default roles, so assign it to them directly.

3. Email is the identity key, and it must be verified. Shopify matches customers by email and requires email_verified to be true. A directory that does not mark emails as verified dead-ends every sign-in.

4. The one-second budget is real. Shopify fails the flow if the discovery, token or userinfo endpoint takes longer than about a second to answer. That constrains where you host the identity provider and how warm you keep it. Measure it before you activate.

5. Single sign-out works in one direction. Signing out of the store ends the buyer’s browser session at Keycloak. Two caveats. A logout started in another application on the same realm does not reach Shopify, which has no back-channel logout, so a portal that wants one logout across the estate has to coordinate it. And the refresh token Shopify holds is not revoked by that browser logout, so set your realm’s session lifetimes deliberately.

6. Shopify’s session is durable and independent. Once a buyer is signed in, Shopify keeps its own session in a persistent cookie. It survives closing the browser, it does not re-check the identity provider on every page, and it runs for as long as the refresh token stays valid (Shopify allows up to about ninety days, and Keycloak’s offline-session idle limit, thirty days by default, is reached first if the buyer is away). The design consequence: binding a buyer to a company after they have signed in does not upgrade the session they already have. We assigned a signed-in buyer to a company through the Admin API and their view stayed unchanged.

7. So bind before the first sign-in. For an existing trade customer base, seed the customers and their company contacts from your CRM before you switch the login over; their first sign-in then lands straight in B2B. For a brand-new buyer whose customer record is created by their first sign-in, run the binding from your integration and have them sign in again afterwards. Plan the onboarding journey around that one extra sign-in, rather than discovering it in support.

5. Run it yourself

The lab is a docker compose up: Keycloak configured the way Shopify needs it, an edge that exposes only the realm’s sign-in endpoints, a quick public tunnel so Shopify can reach your laptop, and a check script that confirms the provider meets Shopify’s requirements before you connect it. The README has the admin checklist, field by field.

The lab: github.com/mfnusrta-meta/shopify-keycloak-b2b-sso

Run it on a development store or in a planned window: activating an identity provider replaces sign-in for every customer until you switch back.

6. When not to reach for this

  • You are not on Shopify Plus. Bringing your own identity provider is a Plus feature.
  • Your buyers do not already have an account elsewhere. If Shopify is the only thing they sign in to, its passwordless one-time codes are simpler and need nothing from you.
  • Your identity platform cannot answer within a second, or cannot verify emails. Fix that first, or every sign-in fails.
  • You need logout to flow from other applications into the store. Shopify has no back-channel logout today; budget for coordinating it in your portal.

7. The principle

Let the system that is best at a job own it. Your identity platform already knows who your people are and what rules apply to them. Shopify’s B2B already knows companies, locations, catalogues and prices. Connect them at one seam, an OpenID Connect login plus a single binding step, and keep each side authoritative for what it does well.

References & further reading

Verified against Shopify customer accounts in November 2026 with Keycloak 26.8.2. Shopify’s admin screens change; check them against your store.

Working on something related?

Happy to talk it through. No commitment — just a conversation.