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:
- My apps → Create app
- App name: your application name
- LinkedIn Page: select or create your company page
- App logo: upload a 100x100px logo
- Click Create app
A company page is required. You can create a free LinkedIn page if your organization doesn't have one yet.
:::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:
- 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 - Choose the page type Company
- 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
- Upload a logo (min ~300x300px — a plain square image works for testing) and tick the authorization checkbox
- 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:
- In your app, go to the Products tab
- Find Sign In with LinkedIn using OpenID Connect
- Click Request access
- Accept the legal terms
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.
Step 3 — Configure the redirect URL
In the app's Auth tab:
- OAuth 2.0 settings → Authorized redirect URLs for your app → Add URL
- Enter:
https://keycloak.example.com/realms/YOUR_REALM/broker/linkedin-oidc/endpoint - Click Update
Step 4 — Copy the Client ID and Client Secret
In the Auth tab:
- Application credentials section
- Copy the Client ID
- Click Generate next to Client Secret (or Show if already generated), then copy
Step 5 — Configure the Identity Provider in Keycloak
In the Keycloak admin console:
- Select your realm
- Identity Providers → Add provider → OpenID Connect v1.0
- Alias:
linkedin-oidc - Display name:
LinkedIn - Scroll down to Advanced settings and expand it — this is where the Discovery Endpoint field lives, not in General settings
- Discovery Endpoint:
https://www.linkedin.com/oauth/.well-known/openid-configuration - Client ID: paste from Step 4
- Client Secret: paste from Step 4
- Default Scopes:
openid profile email
Click Add.
:::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:
| Field | Value |
|---|---|
| Authorization URL | https://www.linkedin.com/oauth/v2/authorization |
| Token URL | https://www.linkedin.com/oauth/v2/accessToken |
| User Info URL | https://api.linkedin.com/v2/userinfo |
| JWKS URL | https://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:
| Claim | Description |
|---|---|
sub | Unique LinkedIn user ID |
name | Full name |
given_name | First name |
family_name | Last name |
email | Email address |
picture | Profile photo URL |
locale | Locale string (e.g., en_US) |
Keycloak's generic OIDC provider doesn't add default mappers, so add them manually:
- 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
Step 7 — Configure the First Login Flow
In Identity Providers → LinkedIn-oidc → Settings → First 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.
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.
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:
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:
- 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.
- 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.
- Common mismatches:
- Alias mismatch — the most frequent cause. If your Keycloak alias is
linkedin-openid-connectbut 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 —
/endpointand/endpoint/are treated as different URIs. - http vs https.
- Stray whitespace from copy-pasting, which is invisible but breaks the match.
- Realm name casing.
- Alias mismatch — the most frequent cause. If your Keycloak alias is
- Delete the incorrect entry on LinkedIn's side, paste the exact copied value, and click Update.
- 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.