Introduction

LinkedIn switched from OAuth 2.0 to OIDC in 2023 with the Sign In with LinkedIn using OpenID Connect product. The older OAuth 2.0 product was deprecated and removed. If you set up LinkedIn login before 2023, you need to migrate to this product.

Keycloak doesn't have a built-in LinkedIn provider type, so you use the generic OpenID Connect v1.0 provider with LinkedIn's discovery URL. The setup takes about 15 minutes.

How identity brokering works

The login flow goes: user clicks "Sign in with LinkedIn" → Keycloak redirects to LinkedIn → user authorizes your app → LinkedIn sends an authorization code to Keycloak's broker endpoint → Keycloak exchanges it for tokens → Keycloak creates or links the user → user lands in your application.

The redirect URI you register in the LinkedIn Developer Portal is:

https://keycloak.example.com/realms/YOUR_REALM/broker/linkedin-oidc/endpoint

The alias linkedin-oidc appears in this URL. You set this alias when creating the identity provider in Keycloak.

Prerequisites

  • Keycloak 24+ running on HTTPS
  • A Keycloak realm with admin access
  • A LinkedIn account and a Company Page (required to create a LinkedIn app) — see the callout in Step 1 if you don't have one yet; it's easy to accidentally end up creating the wrong page type

Step 1 — Create a LinkedIn app

In the LinkedIn Developer Portal at developer.linkedin.com:

  1. My apps → Create app
  2. App name: your application name
  3. LinkedIn Page: select or create your company page
  4. App logo: upload a 100x100px logo
  5. Click Create app

A company page is required. You can create a free LinkedIn page if your organization doesn't have one yet.

The LinkedIn page is required for the app — it appears in the authorization dialog users see when they sign in with LinkedIn

:::warning Don't land on the Showcase Page form by accident If you don't have a company page yet and click Create a new LinkedIn Page from the app form, make sure you land on the Company page type — not Showcase Page or Educational Institution.

The giveaway that you're on the wrong form: it asks for an Associated organization page and shows a field like linkedin.com/showcase/*. A Showcase Page is a sub-page that hangs off an existing Company Page, so if you don't have one yet, this form asks for something you can't provide and you'll get stuck in a loop.

To create a plain Company Page instead:

  1. Go directly to https://www.linkedin.com/company/setup/new/, or from your LinkedIn homepage click the grid icon (top-right, "For Business") → Create a Company Page
  2. Choose the page type Company
  3. Fill in the page name, public URL, website (a placeholder like your repo URL is fine for a dev/test page), industry, and company size
  4. Upload a logo (min ~300x300px — a plain square image works for testing) and tick the authorization checkbox
  5. Click Create page

For a personal or test project, none of these details need to be real — a corporate email address is not required to create a basic Company Page, only for certain verification features. :::

Step 2 — Add the Sign In with LinkedIn product

LinkedIn apps don't come with OIDC by default. You request access to the product:

  1. In your app, go to the Products tab
  2. Find Sign In with LinkedIn using OpenID Connect
  3. Click Request access
  4. Accept the legal terms
This is the correct product for OIDC-based authentication — the older Sign In with LinkedIn product is deprecated

Access is typically granted within a few minutes. The product moves from "Request access" to an "Added" or active state. After it's added, the Auth tab shows the OIDC scopes: openid, profile, email.

These three scopes come from the OIDC product — no additional scopes are needed for basic sign-in

Step 3 — Configure the redirect URL

In the app's Auth tab:

  1. OAuth 2.0 settings → Authorized redirect URLs for your app → Add URL
  2. Enter: https://keycloak.example.com/realms/YOUR_REALM/broker/linkedin-oidc/endpoint
  3. Click Update
LinkedIn's redirect URL validation is strict — copy the URL directly from Step 4 below once you know the alias

Step 4 — Copy the Client ID and Client Secret

In the Auth tab:

  1. Application credentials section
  2. Copy the Client ID
  3. Click Generate next to Client Secret (or Show if already generated), then copy
Generate the secret once — rotate it in the LinkedIn portal if it needs to change, then update the Keycloak IDP config

Step 5 — Configure the Identity Provider in Keycloak

In the Keycloak admin console:

  1. Select your realm
  2. Identity Providers → Add provider → OpenID Connect v1.0
  3. Alias: linkedin-oidc
  4. Display name: LinkedIn
  5. Scroll down to Advanced settings and expand it — this is where the Discovery Endpoint field lives, not in General settings
  6. Discovery Endpoint: https://www.linkedin.com/oauth/.well-known/openid-configuration
  7. Client ID: paste from Step 4
  8. Client Secret: paste from Step 4
  9. Default Scopes: openid profile email

Click Add.

After saving, Keycloak fetches the discovery document and pre-fills the authorization, token, and userinfo URLs automatically

:::note The Discovery Endpoint field is a convenience, not a hard requirement What Keycloak actually needs to talk to LinkedIn is four specific URLs: the Authorization URL, Token URL, User Info URL, and JWKS URL. The Discovery Endpoint field is just a shortcut — paste one URL, Keycloak fetches the JSON document behind it, and auto-fills those four fields for you instead of you typing each one by hand.

If you skip the Discovery Endpoint field entirely, or it's not visible in your Keycloak version, you can fill in the same four fields manually instead:

FieldValue
Authorization URLhttps://www.linkedin.com/oauth/v2/authorization
Token URLhttps://www.linkedin.com/oauth/v2/accessToken
User Info URLhttps://api.linkedin.com/v2/userinfo
JWKS URLhttps://www.linkedin.com/oauth/openid/jwks

Both approaches produce the same result — a working provider with those four values populated. If your login flow already redirects to LinkedIn and completes successfully, these values are already set correctly one way or another; there's nothing extra to configure. If you're ever unsure whether a provider has valid endpoints, scroll through General settings and confirm the Authorization URL and Token URL fields point at linkedin.com.

One quirk either way: the Discovery Endpoint field is part of the Advanced settings section, but only on the initial Add identity provider form. Once the provider is saved, this field disappears — if you go back to edit an existing provider later, the Settings page shows General settings and an Advanced settings section (Scopes, Store tokens, Sync mode, and so on), but no Discovery Endpoint field appears anywhere on the edit view, even under the same "Advanced settings" heading. Keycloak resolves everything into internal endpoint values at creation time and doesn't expose them for editing afterward. If you need to change the discovery URL or any of the four endpoint values later, there's no in-place edit — delete the identity provider and re-create it from scratch. :::

The discovery URL Keycloak needs is:

https://www.linkedin.com/oauth/.well-known/openid-configuration

Verify the alias is linkedin-oidc — it must match the alias in the redirect URI you registered in Step 3. If you choose a different alias, update the redirect URL in the LinkedIn Developer Portal to match.

Step 6 — Configure attribute mappers

LinkedIn's OIDC token includes these claims:

ClaimDescription
subUnique LinkedIn user ID
nameFull name
given_nameFirst name
family_nameLast name
emailEmail address
pictureProfile photo URL
localeLocale string (e.g., en_US)

Keycloak's generic OIDC provider doesn't add default mappers, so add them manually:

  1. Identity Providers → LinkedIn-oidc → Mappers → Add mapper

Email mapper:

  • Mapper type: Attribute Importer
  • Name: email
  • Field Path: email
  • User Attribute Name: email

First name mapper:

  • Mapper type: Attribute Importer
  • Name: firstName
  • Field Path: given_name
  • User Attribute Name: firstName

Last name mapper:

  • Mapper type: Attribute Importer
  • Name: lastName
  • Field Path: family_name
  • User Attribute Name: lastName
Without these mappers, new Keycloak users created via LinkedIn login have no name or email stored in their profile

Step 7 — Configure the First Login Flow

In Identity Providers → LinkedIn-oidc → SettingsFirst Login Flow, the default first broker login:

  • Prompts the user to review their profile once on first login
  • Checks if a Keycloak account already exists with the same email
  • If a match exists, prompts account linking
  • If no match, creates a new Keycloak user

Set Sync Mode to force if you want LinkedIn to be the source of truth for name and email on every login.

Use force sync if users update their LinkedIn profile and you want Keycloak to reflect those changes automatically

Step 8 — Test the login

Open a private browser window and go to your Keycloak realm login page. A LinkedIn button appears below the standard login form.

The button label uses the Display Name you set when creating the provider — LinkedIn in this case

Click it, sign in on LinkedIn, and authorize the app. What happens next depends on whether the email LinkedIn returns already matches an existing Keycloak user.

If the email is new, Keycloak creates a new user automatically and logs you in — no extra prompts.

If a Keycloak user already exists with that email (for example, you're testing with the same admin account you used to set up the realm), the default first broker login flow stops and shows an "Account already exists" screen:

This is expected behavior, not an error — it appears whenever the LinkedIn email matches an existing Keycloak account

You get two choices:

  • Review profile — edit the profile fields Keycloak received from LinkedIn before creating a brand-new, separate account
  • Add to existing account — link the LinkedIn identity to the existing Keycloak user instead of creating a duplicate

For most setups you want Add to existing account. Clicking it prompts you to authenticate with your existing Keycloak credentials to prove ownership before the link is created:

After signing in, the accounts are linked and you're logged in. This account-linking behavior comes from the first broker login flow described in Step 7 — if you set Sync Mode to force, subsequent logins will also overwrite the linked user's name/email fields with whatever LinkedIn reports.

Finally, confirm the federated account: Keycloak admin → Users → find the user → Identity Provider Links tab. The external user ID is the LinkedIn sub value.

Troubleshooting common issues

"Bummer, something went wrong" on LinkedIn authorization page

The LinkedIn app hasn't had the Sign In with LinkedIn using OpenID Connect product activated, or the access request is pending. Check the Products tab in the Developer Portal and confirm the product shows as active. Also check that the OAuth 2.0 scopes list includes openid, profile, and email.

"The redirect_uri does not match"

LinkedIn shows this as "Bummer, something went wrong" — "The redirect_uri does not match the registered value" on its authorization page. The redirect URI registered in the LinkedIn Developer Portal and the one Keycloak sends must match exactly — LinkedIn does a strict string comparison, not a fuzzy one.

To fix it:

  1. In Keycloak, go to Identity Providers → your LinkedIn provider → Settings. In the General settings section, click the copy icon next to the Redirect URI field — don't retype it, since it's truncated on screen and easy to transcribe wrong.
  2. In the LinkedIn Developer Portal, go to your app's Auth tab → Authorized redirect URLs for your app, and compare the existing entry against what you just copied.
  3. Common mismatches:
    • Alias mismatch — the most frequent cause. If your Keycloak alias is linkedin-openid-connect but you registered a URL ending in /broker/linkedin-oidc/endpoint (or any other alias), it will fail. The alias segment in the URL must match the alias field in Keycloak exactly.
    • Trailing slash/endpoint and /endpoint/ are treated as different URIs.
    • http vs https.
    • Stray whitespace from copy-pasting, which is invisible but breaks the match.
    • Realm name casing.
  4. Delete the incorrect entry on LinkedIn's side, paste the exact copied value, and click Update.
  5. Wait a minute for LinkedIn's change to propagate, then retry the login in a fresh private browser window.

Discovery endpoint returns 404

This can happen if LinkedIn's OIDC product hasn't been fully activated on the app. Wait a few minutes after requesting access, then try again. The discovery URL is:

https://www.linkedin.com/oauth/.well-known/openid-configuration

Confirm it returns a valid JSON document by opening it in a browser before entering it in Keycloak.

Users can log in but name fields are blank

The attribute mappers in Step 6 weren't added, or the claim names don't match. LinkedIn sends given_name and family_name, not firstName and lastName. The mapper translates between them — the Claim field uses LinkedIn's name, the User Attribute Name field uses Keycloak's name.

"Error: invalid_client" during token exchange

The Client Secret is wrong or expired. Go to the LinkedIn Developer Portal → Auth tab → Application credentials and generate a new secret. Update the Keycloak IDP configuration with the new value.

Production checklist

  • LinkedIn page created as a Company page, not a Showcase Page or Educational Institution
  • Sign In with LinkedIn using OpenID Connect product activated and showing as active
  • Redirect URI copied from Keycloak's copy button (not retyped) and pasted into LinkedIn's Authorized redirect URLs exactly
  • Redirect URI in LinkedIn Developer Portal matches Keycloak alias exactly, including case and trailing slash
  • Client secret stored outside source control
  • Attribute mappers configured for email, firstName, and lastName
  • Discovery endpoint (or the four manual endpoint URLs) verified before configuring Keycloak — opening the discovery URL in a browser should return valid JSON; note this is a convenience, not a mandatory field
  • Sync Mode chosen deliberately
  • Tested with an account that has a verified email on LinkedIn
  • Tested the account-linking path (login with an email that already has a Keycloak user) so the "Account already exists" flow is understood before real users hit it

Need help integrating LinkedIn with Keycloak?

We deliver production-ready LinkedIn + Keycloak integrations in 1–3 weeks.

Fixed-price, zero vendor lock-in, full source code ownership.

See integration packages