Your enterprise customer just emailed: "Our employees can't find your app in Okta. Can you add a tile?" If you have no idea what they mean, this article is for you. By the end of it you will know exactly what they are asking for, why the deal might stall without it, and how to deliver it with Kinde in an afternoon.
When you sell software to enterprises, the people who actually log in every day rarely navigate to your app the way a consumer would. They sit inside a company portal, something like Okta, Microsoft Entra ID, or Google Workspace, and they launch every approved application from a single dashboard of tiles. If your app is not one of those tiles, it does not really exist to them, and the IT team that controls that dashboard will tell you so in plain terms.
That request, "add a tile to our portal," is a request for IdP-initiated single sign-on. It is one of the quieter blockers in B2B sales, because it almost never comes up in a demo and almost always comes up right before a contract is signed. This guide walks through what the flow is, why enterprises insist on it, the security concern that has historically made it risky, and how Kinde handles the whole thing so that your application code barely changes.
What you will learn
What IdP-initiated SSO is, and how it differs from the SP-initiated flow you already know
Why enterprise IT teams require it before they will deploy your app
The security risk that is unique to this flow, and how Kinde absorbs it for you
How to enable IdP-initiated SSO on a Kinde enterprise connection
How to set up the matching app tile in Okta, Microsoft Entra ID, and Google Workspace
Exactly what to send your customer's IT admin so they can finish their side
How to test both directions of the flow before you go live
The two directions of SAML
Every SAML single sign-on flow has two participants. The Identity Provider, or IdP, is the system that owns the user's identity and verifies who they are. That is the customer's Okta, Entra ID, or Google Workspace. The Service Provider, or SP, is the application the user wants to reach. In a Kinde setup, Kinde is the Service Provider, and your app sits behind Kinde.
The difference between the two flows comes down to one question: who starts the login?
In SP-initiated SSO, the user starts at your app. They click a sign-in button, your app hands off to Kinde, Kinde routes them to their IdP, they authenticate, and they come back authenticated. This is the flow most developers build first, and it is the one most consumer logins use.
In IdP-initiated SSO, the user starts inside their company portal. They are already logged into Okta or Entra ID for the day, they click your app's tile, and they land in your app already authenticated. Your app never sent them anywhere. The login simply arrives.
In SP-initiated flow your app starts the conversation. In IdP-initiated flow the identity provider does, and the assertion arrives unsolicited.
These are two entry points into the same destination. A single enterprise connection in Kinde can serve both, and most enterprise customers will end up using both depending on where their employees happen to be when they need your app.
Why enterprise customers ask for this
Large organizations do not let employees manage their own logins for dozens of business applications. Instead, the IT team maintains a central portal where every approved app appears as a tile, and that portal becomes the front door to the entire software stack. There are real reasons this matters to them, and understanding those reasons helps you have the right conversation when the request lands.
The first reason is simply how people work. An employee at a financial services firm opens their Okta dashboard in the morning and launches everything from there. They do not bookmark your app's login page, and many of them would not be able to find it if asked. If your app is missing from the portal, adoption inside that company quietly stalls, because the path of least resistance does not include you.
The second reason is governance. Enterprise IT teams need every application that touches company data to be visible in their identity stack, both so they can provision access centrally and so they can revoke it the instant someone leaves. When a thirty-person team is deactivated, IT expects that turning off the account in their IdP turns off access everywhere, including your app, on the same day.
An application that lives outside that system is a gap in their audit trail, and that gap is exactly the kind of thing that fails a SOC 2 or ISO 27001 review.
So when a customer asks for a tile, they are really asking whether your app can become a well-behaved citizen of their identity governance system. IdP-initiated SSO is a large part of the answer, and being able to say yes quickly is often what keeps the deal moving.
The security risk you should understand first
IdP-initiated SSO has a reputation among security engineers, and understanding why matters even though Kinde handles the hard part for you. Knowing the risk lets you answer your customer's security team with confidence rather than a shrug.
In an SP-initiated flow, your side starts the conversation. Kinde generates a request with its own identifier before the user is ever sent to the IdP, and when the response comes back, Kinde can confirm that it matches a request it actually made. There is a built-in handshake. The response is expected, and anything unexpected can be discarded.
IdP-initiated flow removes that handshake. The assertion arrives without any prior request from the Service Provider, which is why it is sometimes called an unsolicited response. That property is convenient for the user, but it opens a specific attack.
If an attacker can capture a valid SAML assertion, perhaps from a shared machine or an intercepted session, they can replay it to the Service Provider and potentially sign in as the original user, because there is no earlier request to check the assertion against.
This class of issue is well documented, and it is the reason mature SAML implementations apply strict validation to unsolicited assertions rather than trusting them on arrival.
For you as a developer building on Kinde, the architecture is what makes this manageable. Because Kinde is the Service Provider, the SAML assertion is posted to Kinde, not to your app. Kinde receives the unsolicited response, validates it, and only then issues your app its own session token.
The replay protection, the assertion validation, the freshness and integrity checks, all of that lives inside Kinde's SAML handling. Your application never parses a raw assertion, never touches the SAML XML, and never has to implement these defenses itself. You receive a clean, validated Kinde session that looks exactly like any other login.
This is the single most important architectural point in this article. The reason this integration is mostly configuration rather than code is that Kinde absorbs the part that is genuinely dangerous to get wrong.
Before you start: how Kinde models enterprise customers
A quick mental model will make the configuration steps make sense. In Kinde, each enterprise customer maps to a Kinde organization, and enterprise connections live on those organizations. The customer brings their own identity provider, Kinde acts as the Service Provider in front of it, and your application always talks to Kinde rather than to the customer's IdP directly.
You can attach a SAML connection at the environment level, meaning it is available across your business, or scope it to a single organization, meaning only that one customer uses it. For a typical B2B setup where each enterprise has its own Okta or Entra tenant, you will usually create the connection on that customer's organization.
You will be working with a handful of values during setup, and it helps to know them by name before they appear on screen:
- ACS URL (Assertion Consumer Service URL). This is Kinde's endpoint that receives the SAML response. You copy it from Kinde and give it to the customer's IT admin.
-
Entity ID. A shared identifier that must match exactly on both sides. In various consoles it appears as Entity ID, SP Entity ID, Audience, or
entityID. - IdP metadata URL. A publicly reachable URL hosting the IdP's SAML metadata XML, which Kinde reads to stay current on the IdP's signing certificate.
- Name ID format and key attributes. These describe how the user's identifier and details, such as email, first name, and last name, are carried in the assertion.
With those in hand, the setup is a matter of configuring two sides and making sure the shared values line up.
Step 1: Create or open the SAML enterprise connection in Kinde
Inside the Kinde dashboard, you reach a connection either through the customer's organization, by going to Organizations, opening the organization, and selecting Authentication, or at the environment level through Settings then Authentication. From there, in the enterprise connection section, you add a new enterprise connection and choose SAML, or open an existing SAML connection if you have already created one.
Give the connection a clear name, since this name becomes the label on the sign-in button your users may see. Once the connection exists, you configure its core SAML fields, which is the next step.
Step 2: Configure the core SAML fields
These fields define how Kinde and the customer's IdP understand each other. Most of them have sensible behavior, and you only need to be precise where the customer's IdP demands a specific value.
Name ID format. The Name ID is the element in the SAML assertion that uniquely identifies the user. The format you choose in Kinde must be one that the customer's IdP supports, so this is a value you confirm with their IT admin rather than guess.
Email key attribute. This tells Kinde which attribute in the SAML token carries the user's email. Setting it ensures the email comes through correctly, which matters both for identifying the user and for the friction-reducing behavior described later. Kinde recommends against leaving this blank, and will fall back to email if you do.
First name and last name key attributes. Optional, used for personalization and for mapping the user into your system cleanly.
Sign request algorithm. This is the cryptographic algorithm used to sign SAML requests. RSA-SHA256 is the secure, commonly used choice. RSA-SHA1 is older and widely deprecated, so you only select it if a particular IdP still requires it.
Protocol binding. This is the transport used to send the SAML request. HTTP POST sends it via an HTML form and handles larger, signed payloads, which is the common choice. HTTP Redirect sends it as a URL parameter and is lighter but size-limited. You match whatever the customer's IdP supports.
If you want a deeper reference for any of these, Kinde's advanced SAML configuration documentation covers each field in detail, but for most setups the defaults plus the customer's stated requirements are all you need.
Step 3: Turn on IdP-initiated SSO
Enabling IdP-initiated SSO is a single toggle. Kinde shipped support for it in February 2026. On the SAML connection, scroll to the IdP-initiated SSO behavior section and enable Accept requests.
The helper text spells out exactly what this does: it tells Kinde to accept unsolicited login requests sent to it by the identity provider, which is what allows the Kinde login page to be bypassed entirely when a user clicks the tile in their portal.
One detail here tells Kinde where to send the user after the unsolicited login lands, and getting it right is essential.
Kinde asks you to pass a relayState value in the IdP-initiated request, and that value is a target redirect URI carrying two parameters, client_id and connection_id. The client_id identifies which of your Kinde applications the user is signing in to, and the connection_id identifies which enterprise connection the assertion belongs to.
You configure this relayState on the identity provider side, in the app you set up there, so that every IdP-initiated login arrives pointed at the right application and connection. Without it, Kinde receives a valid assertion but has no instruction on where to take the user next.
Directly beneath the toggle is a second option, Use IdP email as login hint. Switching it on tells Kinde to carry the email from the SAML response into the login_hint query parameter, which lets the IdP skip its own account-selection screen when the user happens to be signed into more than one account. It is a small touch, but it removes a click for users who live in multiple Google or Microsoft accounts at once.
Two related options matter for a B2B setup. Trusting email addresses from the IdP lets Kinde match an incoming user to an existing account with the same email, rather than creating a duplicate identity, which makes for a more seamless sign-in. Single logout, if switched on, means that signing out of your app also signs the user out of the other apps on that connection, which some enterprise customers expect.
Step 4: Hand the ACS URL and Entity ID to your customer
With the Kinde side configured, copy two values to send to the customer's IT admin: the ACS URL and the Entity ID. These are the bridge between the two systems.
The ACS URL is where the IdP will post its SAML response, and it points at Kinde. The Entity ID is the shared identifier that has to match precisely on both sides. If you use a custom domain in Kinde, copy the custom domain version of the ACS URL instead of the default.
The Entity ID is the value most likely to cause a silent failure, because it shows up under different names in different consoles. In Kinde it is the Entity ID field. In the customer's IdP it might be labeled Audience, SP Entity ID, or simply Entity ID. If the strings do not match exactly, sign-in fails, often with an unhelpful invalid SAML response error.
So when you send these values, say explicitly that the Entity ID must be entered character for character on their side.
What to send your customer's IT admin
- ACS URL, copied from Kinde
- Entity ID, which must match character for character on both sides
- The Name ID format you configured
- A request for their IdP metadata URL in return
In return, you need one thing from them: the IdP metadata URL, a publicly reachable link to their SAML metadata XML. Kinde reads this URL so that the IdP's signing certificate stays current automatically.
One practical note, since it trips people up: some providers, Google Workspace among them, do not host the metadata file at a stable public URL, so the customer may need to host it somewhere reachable such as an S3 bucket, Cloudflare R2, or a public site, and give you that link.
Step 5: Set up the app tile on the IdP side
This is the half of the work that lives in the customer's identity provider, and it is the part that creates the tile. The exact clicks differ per provider, so here are the three most common, at the level of detail your customer's admin will recognize. Including them serves readers who are configuring both sides themselves, which many smaller enterprise admins do.
Okta
In the Okta admin console, the admin creates a new SAML application, enters the ACS URL and Entity ID from Kinde into the SAML settings, and configures the attribute statements so that email and name are passed through under the keys Kinde expects. Once the app is created and assigned to the relevant users or groups, it appears as a tile on those users' Okta dashboards.
Microsoft Entra ID
In the Entra admin center the admin goes to Enterprise applications, selects New application, then Create your own application, and chooses the option to integrate a non-gallery application. On the resulting app they open the single sign-on tile, select SAML, and edit the basic SAML configuration to add the Entity ID and ACS URL from Kinde. Entra carries email and name through claim attributes that use the schemas.xmlsoap.org claim URLs, and the admin copies the App federation metadata URL back to you as the IdP metadata URL.
Google Workspace
In the Google Admin console the admin goes to Apps, then Web and Mobile Apps, and chooses Add custom SAML app. After naming the app, Google shows its own identity provider details and a DOWNLOAD METADATA button, and because Google does not host that metadata XML at a stable public URL, the admin downloads it and uploads it somewhere reachable, such as a Cloudflare R2 bucket or a public file host, then provides that link as the IdP metadata URL.
On the Service provider details step the admin enters the ACS URL and the matching Entity ID from Kinde, sets the Name ID format to EMAIL, and sets the Name ID to Basic Information then Primary email. On the Attribute mapping step they map Primary email to the email key attribute Kinde expects, optionally adding first and last name, then finish and turn the app on for the chosen users so the tile appears.
Across all three, the shape is identical even though the labels move around: enter Kinde's ACS URL and Entity ID, map the attributes, hand back the metadata URL, and assign the app to users so the tile appears.
Step 6: Test both directions
Once both sides are configured and the connection is switched on, test the SP-initiated direction first, because it is the simpler check and it confirms the connection itself is sound. Open your app, trigger the enterprise sign-in, authenticate at the IdP, and confirm you land back in your app with a valid session. If you configured a home realm domain, the user is routed silently to the IdP. If not, they see a sign-in button labeled with your connection name.
Next, test the IdP-initiated direction. Go to the IdP portal as an assigned user, click your app's tile, and confirm you arrive in your app already authenticated, with no detour through a login screen. That is the IdP-initiated flow working end to end, and it is the experience your enterprise customer's employees will have every day.
A free Okta developer account or a test Entra tenant is enough to rehearse the whole thing before you involve a real customer, so that when a customer does ask, you can walk them through it from memory.
If something fails, the usual culprit is the Entity ID not matching exactly between Kinde and the IdP, followed by an unreachable or stale metadata URL. Both produce sign-in errors that look more mysterious than they are, so they are the first two things to recheck.
What your app code has to change
Almost nothing changes, and that is the whole point. Because Kinde is the Service Provider and absorbs the SAML handling, your application keeps talking to Kinde exactly as it already does. A user who arrives through the IdP-initiated flow shows up in your app as an authenticated Kinde session, indistinguishable in your code from a user who logged in any other way. There is no SAML parsing to write, no assertion to validate, no new endpoint to stand up on your side. The work you just did was configuration and coordination, which is precisely why this is something you can deliver to a customer quickly rather than scheduling a sprint for it.
// Your existing Kinde session check is unchanged.
// An IdP-initiated user arrives as a normal authenticated session.
import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";
const { isAuthenticated, getUser } = getKindeServerSession();
if (await isAuthenticated()) {
const user = await getUser();
// Same code path for every login method, IdP-initiated included.
}
The snippet above is illustrative of how little changes. The exact Kinde SDK call depends on your framework, and Kinde provides SDKs for React, Next.js, Node/Express, .NET, Flutter, Java, SvelteKit, Remix, Go, and Expo.
Wrapping up
The email that started this article, the one asking you to add a tile to a customer's portal, is no longer a mystery or a blocker. It is a request for IdP-initiated SSO, a flow where the identity provider starts the login and the assertion arrives unsolicited. Enterprises insist on it both for how their employees actually work and for the governance requirements that decide whether you pass a security review. The replay risk makes the flow sensitive, and Kinde, sitting in front of your app as the Service Provider, validates the unsolicited assertion so your code never has to.
The work is configuration rather than construction. Enable the Accept requests toggle on the Kinde connection, set the relayState with your client_id and connection_id on the identity provider side, exchange the ACS URL, Entity ID, and metadata URL with your customer's IT admin, set up the matching app on their Okta, Entra, or Google Workspace, and test both directions. Your customer's employees get a tile that drops them straight into your app, their IT team gets an application that behaves inside their identity governance, and the deal that was waiting on this keeps moving.
Kinde is free for up to 10,500 monthly active users, with no credit card required to start. You can create an account and configure your first enterprise connection at kinde.com, and the enterprise connections documentation walks through each provider in full detail.
Building something with Kinde and enterprise auth? I write about identity, billing, and agent infrastructure for developers. Follow along for more walkthroughs like this one.








Top comments (0)