ACS URL and Audience URI in Okta
Two small fields decide whether your single sign-on works or fails. Learn what they mean, where they come from, how Okta and your application check them, and how to fix them when they go wrong.
Imagine you work at a company with forty different web apps. Without single sign-on, you would need forty usernames and forty passwords. You would forget some, reuse others, and call the help desk far too often. With single sign-on, often shortened to SSO, you prove who you are once, and every app trusts that proof. Okta is one of the most widely used services that makes this possible.
But for one app to trust Okta, both sides must agree on a few facts before anyone logs in. Where should Okta deliver the proof? And how does the app know the proof was meant for it, and not for some other app? Those two questions are answered by two settings you will see on almost every Okta SAML screen: the ACS URL and the Audience URI. People mix them up all the time, and a single wrong character in either one can lock a whole company out of an app.
This guide teaches both from zero. We start with the big picture, then the words you need, then each field, then a full walk through the Okta screens. After that we follow a login step by step, see how the app checks every value, and finish with security, troubleshooting, good habits, and common mistakes.
1The Big Picture: Why Two Systems Must Agree
Before any field makes sense, you need to know who the players are and why they must share a few facts in advance.
The two players in every SSO login
Every SAML single sign-on login involves two systems. The first is the Identity Provider, usually shortened to IdP. This is the system that knows your users and checks their passwords and extra security steps. In this guide, Okta is the IdP. The second is the Service Provider, shortened to SP. This is the application the user actually wants to use, such as a learning portal, a ticketing tool, or a cloud console.
The user sits in the middle with a web browser. The browser carries messages between the IdP and the SP. The two systems never need to speak to each other directly during a login. That is a very important design choice, and it is the reason the two fields in this guide matter so much.
Think of a big music festival. The ticket office (Okta) checks your identity and gives you a wristband. Each stage (an application) has a guard who looks at your wristband. The guard does not call the ticket office. The guard just checks that the wristband is real and that it is the right kind for this stage. The ACS URL is like the exact gate where your wristband is checked. The Audience URI is like the stage name printed on the wristband.
Why they must agree in advance
Because the browser carries the message, anyone could in theory try to hand an app a fake message, or hand an app a real message that was meant for a different app. To stop that, Okta and the app exchange a few facts once, during setup. Okta learns the exact address where the app wants to receive logins. The app learns the name Okta will stamp on every login message. Later, at login time, each side checks the other against those saved facts.
If the two sides do not agree, the login fails. It does not fail loudly with a helpful message in many cases. It often fails with a short, confusing error page. That is why learning these two values properly saves hours of debugging later.
Okta calls the ACS URL by a different name on its screen: “Single sign-on URL”. Many people hunt for a field called “ACS URL” in Okta and cannot find it. It is there, just under a different label.
2SAML in Plain English
SAML is the language Okta and the app speak. A few words from it will make the rest of this guide easy.
What SAML is
SAML stands for Security Assertion Markup Language. It is an open standard, first created in the early 2000s, that lets one system tell another system “this person has been checked, and here are some facts about them”. The version used almost everywhere today is SAML 2.0, finished in 2005. It is older than many popular login tools, and it is still the main choice for company logins to business software because it is stable and widely supported.
The words you will meet
Assertion
The signed statement from Okta that says who the user is and how they were checked. It is the “wristband”.
Response
The envelope that carries the assertion from Okta to the app. A response can hold one or more assertions.
AuthnRequest
An optional message the app sends to Okta to say “please log this person in”. It starts the SP-initiated flow.
Metadata
A file that describes a system: its name, its web addresses, and its signing certificate. Both sides can publish one.
Entity ID
A unique name for a system. Okta has one. The app has one. They are just text strings that act as names.
Binding
The method used to carry a message through the browser. The two common ones are HTTP-Redirect and HTTP-POST.
How messages travel: bindings
A binding is simply a delivery method. With HTTP-Redirect, the message is squeezed into the web address itself, and the browser is sent to that address. This is used for short messages such as the login request. With HTTP-POST, the message is placed inside a hidden web form, and the browser submits the form automatically. This is used for the larger response, because it holds a signed assertion that is too big for an address. The ACS URL is exactly where that hidden form is submitted.
The trust comes from certificates
How does the app know the response truly came from Okta? Okta signs it with a private key, and the app holds the matching public certificate, which it received during setup. If the signature checks out, the app knows two things: the message really came from Okta, and nobody changed it on the way through the browser. The ACS URL and Audience URI work alongside this signature. The signature proves who wrote the message, and these two values prove where it was meant to go and who it was meant for.
A signed assertion is like a letter with a wax seal. The seal proves who sent it and that nobody opened it. But a sealed letter still needs an envelope with the right street address (the ACS URL) and a name at the top saying who it is for (the Audience URI). A perfect seal on a letter delivered to the wrong house, or written for the wrong person, should still be turned away.
SAML messages are written in a text format called XML, and the response is encoded in a way called Base64 before it is sent. You rarely need to read them by hand, but browser tools can decode them for you when you troubleshoot. We cover that later.
3What Is the ACS URL?
ACS stands for Assertion Consumer Service. It is the front door of your application for SAML logins.
The definition
The ACS URL is a web address on your application, the Service Provider. It is the one place that is willing to accept a SAML response from Okta and turn it into a logged-in session. The word “consumer” means the app is the one that consumes, or uses, the assertion. When Okta finishes checking a user, it tells the browser to send the signed response to this address.
The ACS URL belongs to the application, not to Okta. The application’s makers decide what it is. For a ready-made product, the vendor gives you the value in their setup guide. For an app your own team builds, you choose it and your code must listen there. In Okta, you type that value into the field called Single sign-on URL.
Picture an office building with one reception desk that accepts courier deliveries. A courier with a package cannot just wander into any room. They must go to that one desk, where the receptionist checks the package and signs for it. The ACS URL is that reception desk. If Okta delivers the package to a different door, nobody will sign for it.
What the ACS URL looks like
It is an ordinary web address, and it must use HTTPS in any real setup. Typical shapes include an address with a path such as /saml/acs, /sso/saml, or /auth/saml/callback. Some products include a unique identifier for your account inside it, so the address is different for every customer. Others use one fixed address for everyone. Neither style is better; they simply reflect how the vendor built the product.
Exact match matters
Okta and the app compare these addresses character by character. A trailing slash, a different capital letter, the word “http” instead of “https”, or a missing port number can all cause a mismatch. This is one of the most common causes of broken SSO, and it is almost always caused by a copy-and-paste slip. Wildcards are not allowed, so you cannot say “any address under this domain”.
One address or several
Most apps have exactly one ACS URL. A few large products publish more than one, for example one per region or one per binding. SAML metadata can number them with an index, so that a login request can say “use the second one”. Okta supports this idea through an option that lets the app request other single sign-on URLs, covered in a later chapter.
Real-world example: Slack
Slack publishes the address you must use as the single sign-on URL for your workspace, and it follows a pattern that includes your workspace name. When your IT team connects Slack to Okta, they paste Slack’s ACS address into Okta’s Single sign-on URL field. If they paste the address of a different workspace, logins land in the wrong place and fail.
Never confuse the ACS URL with Okta’s own sign-in address. Okta’s address is where the user logs in. The ACS URL is where the user’s proof is delivered. They live on different systems and do different jobs.
4What Is the Audience URI?
If the ACS URL answers “where does it go?”, the Audience URI answers “who is it for?”.
The definition
The Audience URI is the name that Okta writes inside the assertion to say which application the assertion was created for. In the SAML standard it is called the Audience, and it sits inside a section called the audience restriction. In practice, it carries the same value as the application’s Entity ID, which is why Okta labels the field Audience URI (SP Entity ID).
“Audience” is the same word used for a theatre audience: the people a performance is meant for. An assertion with an audience restriction says, in effect, “this proof is only for the application named here”. When the app receives it, the app compares that name to its own entity ID. If they match, the app continues. If they do not, the app must reject the assertion, even if the signature is perfect.
Think of a gift card that says “Valid only at Maple Street Bakery”. The card is real and has real money on it. But if you try to use it at a different shop, the cashier will refuse it. The Audience URI is the “valid only at” line on the card. It stops a real login from one app being quietly reused at another.
It is a name, not always an address
The word “URI” is a little misleading. A URI is a general kind of identifier. It can look like a web address, such as https://learn.acme-example.com/saml/metadata, or like a plain label, such as urn:amazon:webservices. The app does not need to host anything at that address. It is only a label that must match exactly. Many people waste time trying to open the Audience URI in a browser, when it was never meant to be opened.
Who decides the value
Like the ACS URL, the Audience URI is owned by the application. The vendor documents the value, or shows it on their SSO settings page, or publishes it inside their SAML metadata file. You copy it into Okta. Okta does not invent it. Okta only copies it into each assertion it creates for that app.
Real-world example: AWS account federation
When you connect an AWS account to Okta using the standard SAML federation approach, the audience value is a fixed label that AWS documents, shown as urn:amazon:webservices, and the ACS address is the AWS sign-in SAML endpoint. Every Okta customer using that integration uses the same two values, because AWS built it that way. The pre-built AWS app in the Okta Integration Network already fills them in for you.
Why this field is a security feature
Without an audience check, an attacker or a careless user could take a valid assertion made for a low-risk app and present it to a high-risk app that trusts the same Okta. The audience restriction is what makes that fail. Each app only accepts assertions with its own name on them. We return to this in the security chapter.
Different words, same thing: Audience URI, SP Entity ID, Audience Restriction, Entity ID, and “Identifier” in some vendor screens often all point to the same value. When two vendor screens use different words, check the description rather than guessing.
5ACS URL vs Audience URI: Side by Side
The two values are easy to mix up. This chapter puts them next to each other, and adds the other values that travel with them.
| Question | ACS URL | Audience URI |
|---|---|---|
| What does it answer? | Where should the login proof be delivered? | Which application is the proof meant for? |
| Okta field name | Single sign-on URL | Audience URI (SP Entity ID) |
| Who owns the value? | The application (SP) | The application (SP) |
| Must it be a real web address? | Yes, it must be reachable over HTTPS | No, it can be any unique text label |
| Where does it appear in SAML? | Destination, Recipient, and the request’s consumer address | The Audience inside the conditions of the assertion |
| What does the browser do with it? | Submits the response to it | Nothing, the browser never sees it as an address |
| What happens if it is wrong? | Delivery fails, or the app rejects a mismatch | The app rejects the assertion as not meant for it |
The cousins: Recipient, Destination, and Issuer
Three other values travel with the ACS URL and Audience URI, and they often appear in the same Okta screen or the same error message. It helps to know them now.
Destination
Written on the outer response. It says which address the response was sent to. The app checks it equals its own ACS URL.
Recipient
Written inside the assertion’s subject section. It says which address may use this assertion. The app checks it too.
Issuer
The name of Okta’s side for this app. The app compares it to the issuer value it saved from Okta’s metadata.
RelayState
A small piece of text that rides along so the app can send the user to the right page after login.
In Okta, a single checkbox ties several of these together. It reads “Use this for Recipient URL and Destination URL”. When it is ticked, Okta copies the Single sign-on URL into both the Recipient and the Destination. This is correct for the vast majority of applications. Only a few unusual products need different values for each, and in that case you untick the box and fill them separately.
A package label has several parts. The street address on the outside is the Destination. The “deliver only to this person at this address” note on the inside is the Recipient. The “who is this for” name is the Audience. The sender’s return label is the Issuer. A careful receiver checks every part of the label, not just one.
The Audience URI and the Issuer sound alike but point in opposite directions. The Audience is the app’s name. The Issuer is Okta’s name. When someone says “entity ID” without more detail, ask which side they mean.
6Where These Fields Live in Okta
A walk through the Okta Admin Console when you create a custom SAML app. Button names can shift slightly between Okta releases, but the idea stays the same.
Start a new app integration
In the Admin Console, open Applications, then Applications, and choose Create App Integration. Pick SAML 2.0 as the sign-in method and continue.
Fill in General Settings
Give the app a name that people will recognise on their dashboard, and optionally add a logo. This step has no SAML values yet.
Enter the Single sign-on URL
On the Configure SAML step, paste the application’s ACS URL into the field called Single sign-on URL. This is where Okta will deliver every login.
Decide about Recipient and Destination
Leave the box “Use this for Recipient URL and Destination URL” ticked unless the vendor tells you otherwise. Ticked means Okta reuses the ACS URL for both.
Enter the Audience URI
Paste the application’s entity ID into Audience URI (SP Entity ID). Check it twice for stray spaces, a missing slash, or the wrong case.
Choose the name format and username
Set the Name ID format and the Application username. These tell the app how to identify the person, for example by email address.
Add attribute statements if needed
Extra facts such as first name, last name, or group membership can be sent with the login. Many apps need these to create the user’s profile.
Preview, finish, and assign people
Okta lets you preview the assertion before you save. After finishing, assign users or groups to the app so it appears on their dashboard.
Copy Okta’s side back to the app
On the Sign On tab, Okta shows its own sign-in address, its issuer, and its signing certificate, plus a metadata link. Give these to the application so it can trust Okta.
Other fields on the same screen
Beside the two key fields, the screen holds several settings that affect how these values behave. Default RelayState chooses the page the user lands on after login. Name ID format chooses how the user is named, with common choices such as email address, persistent, transient, or unspecified. Application username chooses which Okta profile value becomes the login name. In the advanced area you can choose whether the response and the assertion are signed, the signing algorithm, whether to encrypt the assertion, and which certificate to use. There is also the SAML Issuer ID, which controls the issuer name Okta writes.
Requestable SSO URLs
Below the Single sign-on URL, Okta offers an option to allow the app to request other SSO URLs. When you switch it on, you can list extra ACS addresses, each with an index number. This is useful when an application has several valid delivery addresses and decides at login time which one to use. If the app asks for an address that is not on the list, Okta refuses the request instead of delivering to an unknown place.
Pre-built apps do this for you
The Okta Integration Network, called the OIN, holds thousands of ready-made app templates. When you pick one, many of the fields are pre-filled or built from a small number of questions, such as your account name. The ACS URL and Audience URI are produced from your answers using patterns the vendor and Okta agreed on. For these apps, you rarely type either value by hand. For a custom or in-house app, you always do.
Real-world example: a company builds its own learning portal
Acme Learning builds an internal training site. Its developers decide the ACS URL is https://learn.acme-example.com/saml/acs and the entity ID is https://learn.acme-example.com/saml/metadata. The IT team creates a custom SAML app in Okta, pastes the first into Single sign-on URL and the second into Audience URI, then sends Okta’s issuer and certificate back to the developers. Both sides now agree.
Keep your test and production apps separate in Okta. A test copy of the app should have its own ACS URL and Audience URI that match the test version of the application, never the production ones.
7Architecture and Components
Let us zoom out and see every moving part in a typical Okta SAML setup, and where each value lives.
flowchart LR
U["User and Web Browser"]
subgraph SP["Service Provider - the Application"]
A1["Login Entry Point"]
A2["ACS Endpoint - the ACS URL"]
A3["Saved Settings: Entity ID, Okta Issuer, Okta Certificate"]
end
subgraph IDP["Identity Provider - Okta"]
O1["Okta SSO Endpoint"]
O2["Sign-in and MFA Service"]
O3["App Settings: Single sign-on URL, Audience URI"]
O4["Signing Key"]
O5["User Directory"]
end
U --> A1
A1 --> O1
O1 --> O2
O2 --> O5
O3 --> O4
O4 --> U
U --> A2
A2 --> A3
Component by component
The browser is the courier. It carries the login request to Okta and carries the signed response back to the app. It is not trusted. It can be inspected and, in the wrong hands, tampered with, which is why signatures matter.
The login entry point on the app is the page or route that starts a login. For SP-initiated logins, it creates a request and sends the user to Okta. For some apps, it just redirects the user to Okta’s address without any request at all.
The ACS endpoint is the code on the app that listens at the ACS URL. It reads the response, checks the signature and every value inside, creates a session, and redirects the user into the app. This is the most security-sensitive piece of code in the whole integration.
Okta’s SSO endpoint is the address on Okta that receives login requests for your specific app. It includes an identifier unique to that app, so one Okta organization can host many SAML apps side by side.
The sign-in and multi-factor service checks the password and any extra proof, such as a phone prompt or a security key. The app never sees this step and never handles the password. That is one of the biggest benefits of SSO.
The app settings in Okta hold the Single sign-on URL and the Audience URI you typed. The signing key is the private key Okta uses to sign responses for the app. The directory holds users, groups, and profile facts.
An airport works the same way. The security check (Okta’s sign-in and MFA) is separate from the airline gate (the ACS endpoint). The boarding pass carries the flight number (Audience) and the gate (ACS URL). The gate staff only look at the pass and the printed seal, they do not redo the security check.
When something breaks, ask: is the problem on the Okta side, the browser path, or the application side? The diagram above helps. If Okta’s log shows a successful login, the trouble is probably after Okta, at the ACS endpoint or its saved settings.
8Internal Working: The SP-Initiated Login
This is the most common flow. The user starts at the application and is sent to Okta to prove who they are.
sequenceDiagram
autonumber
participant U as User Browser
participant S as Service Provider
participant O as Okta
U->>S: Open the app page
S->>U: Redirect to Okta with an AuthnRequest
U->>O: Follow redirect to the Okta SSO address
O->>O: Check the request ACS address against the app settings
O->>U: Show sign-in page and ask for MFA
U->>O: Enter password and approve MFA
O->>O: Build assertion with Audience and sign it
O->>U: Return a form targeting the ACS URL
U->>S: Auto-submit form to the ACS URL
S->>S: Check signature, Destination, Recipient, Audience, time
S->>U: Create session and show the app
Step by step
The user visits the app
The user opens a page that needs a login. The app sees there is no session yet and decides to use SSO.
The app builds a login request
The app creates an AuthnRequest. It includes its own entity ID, a unique request number, and often the ACS URL it wants the answer sent to. It sends the browser to Okta with this request attached to the address.
Okta reads and checks the request
Okta finds the app using the address the browser arrived at. If the request names an ACS address, Okta compares it with the Single sign-on URL, or with the requestable URLs you listed. A mismatch is refused here, before the user ever sees a password box.
The user signs in
If the user has no active Okta session, Okta asks for a password and any extra factor. If they already signed in earlier today, this step is skipped. That is the “single” in single sign-on.
Okta builds and signs the assertion
Okta writes the Audience URI from your app settings into the assertion. It also writes the Recipient, the Destination, the user’s name, the time limits, and the number of the request it is answering. Then it signs the content.
The response travels through the browser
Okta returns a tiny web page holding a hidden form that points at the ACS URL. A little script submits it automatically. The user normally sees only a brief flash.
The app validates and logs the user in
The ACS endpoint runs its checks. If all pass, the app creates its own session, often a cookie, and sends the user to the page they first wanted, using the RelayState value.
Notice that the ACS URL shows up in two places. In step 2 the app may tell Okta where it wants the answer. In step 6 Okta actually delivers there. Okta only trusts the first if it matches the address you configured. This two-way agreement is what stops a forged request from redirecting a user’s proof to an attacker’s server.
You ask a bank to mail you a statement. You write your address on the form. The bank does not simply trust the form, because anyone could write any address on it. It compares what you wrote with the address it already has on file. Okta does the same with the ACS URL in the login request.
9The IdP-Initiated Login and Multiple ACS Addresses
Sometimes the user starts at Okta instead. This changes how the ACS URL and Audience URI are used.
sequenceDiagram
autonumber
participant U as User Browser
participant O as Okta Dashboard
participant S as Service Provider
U->>O: Sign in to the Okta dashboard
O->>U: Show app tiles
U->>O: Click the app tile
O->>O: Build assertion with no request to answer
O->>U: Return a form targeting the configured ACS URL
U->>S: Auto-submit form to the ACS URL
S->>S: Validate the assertion
S->>U: Create session and show the app
What is different
In an IdP-initiated login, the user first signs in to Okta’s dashboard and clicks a tile for the app. No request came from the app, so Okta has nothing to answer. Okta simply builds an assertion using the settings you saved and posts it to the configured Single sign-on URL. The app receives a response it never asked for. Many apps allow this. Some deliberately refuse it, because without a request number to match, the app has one fewer check against replayed responses.
IdP-initiated login is convenient, because users like clicking a tile. But it is a little weaker, because the response is not tied to a request. Some security-focused teams switch it off in the application and allow only SP-initiated logins. Ask what your own security rules require.
Why several ACS addresses exist
Some products serve users from several regions or several customer-specific domains. A single account might have more than one valid delivery address. In Okta, you can switch on the option that allows the app to request other SSO URLs, then add each address with an index. At login, the app’s request can point to one of them by address or by index number. Okta delivers only to a listed address. The configured main Single sign-on URL is used for the default case and for IdP-initiated logins.
One address only
Simple and safest. Right for most custom apps and for the majority of products in the OIN.
Several regional addresses
Useful when one vendor account spans regions. List each address as a requestable URL.
Several customer domains
Useful when one app serves many branded domains. Keep the list as short as you can.
Test and live sites
Use two separate Okta apps instead of two addresses in one app. This keeps data and access apart.
Real-world example: a SaaS vendor with many customers
A project-tracking vendor gives each customer a private address such as a customer name followed by the vendor’s domain. Each customer configures their own Okta app with their own address as the ACS URL and their own entity ID. The vendor’s code reads the customer name from the address and loads the right settings. This is called a multi-tenant design, and it is why the same vendor can show you different ACS values than your friend at another company.
10Data Flow and the Life of an Assertion
An assertion is born, signed, delivered, checked, and then expires within minutes. Knowing its life explains many strange failures.
What is inside the assertion
An assertion is organised in sections. The issuer section names Okta’s side. The signature section holds the digital seal. The subject section names the user, and holds the confirmation data that includes the Recipient, an expiry time, and the number of the request being answered. The conditions section holds the earliest and latest valid times and the audience restriction with the Audience URI. The authentication statement records when and how the user signed in. The attribute statement carries extra facts such as email, name, and groups.
Created
Okta fills the sections using your app settings and the user’s profile. The Audience URI and Recipient are copied from the values you typed.
Signed, and optionally encrypted
Okta signs it with its private key. If you turned on assertion encryption, Okta also locks the contents with the app’s public key, so even the browser cannot read the user’s data.
Delivered
The hidden form carries it to the ACS URL through the browser, encoded as text.
Validated
The app checks the signature and every value, as the next chapter explains.
Consumed
The app creates its own session. From now on the assertion is no longer needed, and the app’s cookie keeps the user logged in.
Expired
A few minutes after creation, the assertion is worthless. Okta commonly allows about five minutes. A copied assertion becomes useless after that.
Time matters
The assertion carries a “not before” time and a “not on or after” time. If the app’s clock is far from Okta’s clock, the app may think a fresh assertion is not yet valid or already expired. Apps normally allow a small difference, often a few minutes, called clock skew. Servers should keep their clocks in sync using a standard time service. Time errors look very much like address errors from the outside, so always rule them out.
A one-day lift ticket at a ski resort carries a date, the resort name, and a hologram. It is scanned at the gate. It stops working tomorrow, it does not work at another resort, and you cannot photocopy it for a friend if the gate keeps a log of used tickets. An assertion has all of those protections.
11How the Application Validates Every Value
The ACS endpoint is a checklist. Each item can fail on its own. Here is the usual order.
flowchart TD
S["Response arrives at the ACS URL"]
C1{"Signature valid with Okta certificate?"}
C2{"Issuer matches saved Okta issuer?"}
C3{"Destination equals this ACS URL?"}
C4{"Recipient equals this ACS URL?"}
C5{"Audience equals my Entity ID?"}
C6{"Current time inside valid window?"}
C7{"Request number matches, assertion not seen before?"}
OK["Create session and log user in"]
NO["Reject with an error"]
S --> C1
C1 -->|yes| C2
C1 -->|no| NO
C2 -->|yes| C3
C2 -->|no| NO
C3 -->|yes| C4
C3 -->|no| NO
C4 -->|yes| C5
C4 -->|no| NO
C5 -->|yes| C6
C5 -->|no| NO
C6 -->|yes| C7
C6 -->|no| NO
C7 -->|yes| OK
C7 -->|no| NO
The checks in simple words
| Check | Question it answers | Value compared |
|---|---|---|
| Signature | Did Okta really write this, and is it unchanged? | Okta’s public certificate saved in the app |
| Issuer | Is this from the Okta setup I trust? | Okta issuer saved from metadata |
| Destination | Was this response sent to me? | The app’s own ACS URL |
| Recipient | May this assertion be used at my address? | The app’s own ACS URL |
| Audience | Was this made for me? | The app’s own Entity ID |
| Time window | Is it still fresh? | Not-before and not-on-or-after times |
| Request match and replay | Did I ask for this, and is it new? | Stored request number, stored assertion numbers |
Two things stand out. First, three checks compare against values you typed into Okta: the Destination, the Recipient, and the Audience. Those come from the two fields in this guide. Second, any one failed check ends the login. The app does not “mostly” accept a response.
Where the error message appears
Because the failure happens inside the app, the user sees the app’s own error page, not Okta’s. Wording varies a lot from one product to another. Some say the audience is not valid. Others say the recipient does not match, or give a generic message such as “SSO failed”. Check the app’s own logs, since they usually name the exact check that failed.
If the vendor’s error mentions a mismatch but you cannot see the difference, paste both values into a text editor on separate lines and compare them. Hidden spaces, line breaks, and look-alike characters caused by copying from a document often hide in plain sight.
12Real-World and Industry Examples
The pattern is the same everywhere, but each vendor picks different values. Here are well-known examples and what to learn from each.
Slack: values tied to your workspace
Slack’s SAML setup asks for a single sign-on address tied to your workspace and an audience value that Slack documents. Your IT team copies both from Slack’s guide into Okta. The lesson is that the vendor’s documentation is the source of truth, and that workspace names sit inside the ACS value.
Amazon Web Services: fixed values for everyone
AWS account federation uses a fixed sign-in SAML endpoint as the ACS address and a fixed label as the audience. Because the values are shared by every customer, the security of the integration rests on the signature, on the role information inside the assertion, and on Okta’s own controls. The lesson is that a shared value is fine when the vendor designs the rest of the flow to be safe.
Salesforce: your own domain as the name
Salesforce shows its entity ID and ACS address on its single sign-on settings page, and these are linked to your organisation’s own Salesforce domain. When a company moves to a new custom domain, the saved values must change in both Salesforce and Okta together. The lesson is that renaming a domain is a change to the SSO contract, and needs a plan.
Atlassian cloud products: values issued by the vendor
Atlassian’s access management for its cloud products generates the ACS address and the entity ID for you and shows them on an admin page. You copy those into the identity provider. The lesson is that many vendors generate the values and expect you to copy them, not invent them.
Vendor gives both values
Most common. Copy exactly from the vendor’s screen or metadata file. Never retype them by hand.
You choose both values
For apps you build. Pick stable names that will not change when servers move or teams reorganise.
Metadata import
Some apps publish a metadata file that holds both values. Importing it avoids typing mistakes completely.
OIN template
Okta pre-fills the shape of the values. You supply only account-specific words, such as your subdomain.
The exact values and screen wording at each vendor change over time as products are updated. Always read the vendor’s current setup page rather than relying on an old blog post, including this one, for the precise strings.
13Security: Why These Two Fields Protect You
These values are not paperwork. Each one closes a real attack path.
Threat 1: using a login at the wrong app
Suppose a user has a valid assertion for a minor app, such as a lunch-menu tool. If a high-value app, such as the payroll system, accepted any assertion from the same Okta, a malicious owner of the lunch tool could replay the user’s assertion at payroll and log in as that user. The audience check blocks this. The payroll app only accepts assertions with its own name on them. This is sometimes called a token substitution or confused-audience attack.
Threat 2: sending a login to the wrong place
If an attacker could trick Okta into delivering an assertion to an address the attacker controls, they would capture the user’s proof. Okta defends against this by delivering only to the configured Single sign-on URL, or to a listed requestable URL. The app defends by checking the Destination and Recipient. Together this is the delivery check.
Threat 3: replay and tampering
A captured response could be submitted again later. Defences include the short expiry, the request-number check on SP-initiated logins, and a stored list of used assertion numbers. Tampering is stopped by the signature. A weakness called XML signature wrapping tries to hide forged content next to the signed part, so good SAML libraries must check that the part they read is the part that was signed. This is a strong reason never to write your own SAML code when a maintained library exists.
A hotel key card opens only your room, only during your stay, and only at that hotel. If it opened every room, never expired, or worked at other hotels, one stolen card would be a disaster. Audience, delivery, and time checks are the “only your room, only now, only here” rules for a login.
Good security habits for these fields
Do
- Use HTTPS for the ACS URL, always.
- Keep the Audience URI unique to each app and each environment.
- Require signed assertions, and keep the signing certificate current.
- Reject assertions that fail any one check.
- Keep server clocks in sync.
- Use a well-maintained SAML library for any custom app.
Do not
- Use wildcards or loose matching for either value.
- Reuse one Audience URI across unrelated apps.
- Skip the audience check “just to make it work”.
- Leave a test app pointing at production data.
- Share certificates or private keys in email or chat.
- Leave IdP-initiated login on if you do not need it.
Certificate rotation
Okta’s signing certificate does not last forever. When it nears its end date, you create a new one in Okta and give the app the new public certificate. If the app is not updated in time, every login fails at the signature check. Plan the change with an overlap, and put the expiry date in a shared calendar, because this is one of the most common causes of surprise SSO outages.
When a login “does not work”, people are tempted to turn off checks in the app. Never accept this as a fix. A disabled audience or destination check turns a security control into a decoration. Find the real mismatch instead.
14Monitoring, Logging, and Troubleshooting
When SSO breaks, you need to see what Okta sent and what the app expected. These are the tools and habits that find the problem fast.
Where to look
System Log
The Okta Admin Console keeps a log of events. Look for single sign-on events for your app and user. It shows whether Okta thought the login worked, and gives a reason if it did not.
Assertion preview
While configuring, Okta can show a preview of the assertion it will build. Use it to confirm the Audience, Recipient, and Destination values before real users try.
SAML tracer extension
A browser add-on records the messages that pass through the browser and decodes them into readable text. This is the most helpful tool for SAML problems.
App-side logs
Most products log which validation check failed. These logs usually point straight at the cause, so ask the vendor or your developers where to find them.
A calm way to troubleshoot
Did Okta succeed?
Check the Okta log. If Okta shows an error, the issue is before delivery, such as an assignment problem, a failed factor, or an ACS address mismatch in the request.
Capture the response
Reproduce the login with the browser add-on running. Open the captured response and read the decoded assertion.
Compare three values
Find the Destination, the Recipient, and the Audience in the capture. Compare each one to what the application expects, character by character.
Check the time and the certificate
Compare the valid-time window with the real time. Confirm the application holds Okta’s current certificate.
Fix one thing, test again
Change a single value, then test with a fresh private browser window. Changing many things at once hides the real cause.
Common symptoms and likely causes
| What you see | Likely cause | What to do |
|---|---|---|
| App says the audience is invalid | Audience URI in Okta differs from the app’s entity ID | Copy the entity ID from the app and paste it again |
| App says the recipient or destination does not match | Single sign-on URL differs from the app’s ACS URL, or the Recipient/Destination box is set differently | Fix the Single sign-on URL and tick the shared box |
| Okta refuses before the sign-in page | The app’s request names an ACS address that Okta does not know | Match the address, or add it as a requestable URL |
| Signature or certificate error | App holds an old or wrong Okta certificate | Upload the current certificate or metadata |
| Assertion expired or not yet valid | Clock difference between Okta and the app server | Sync the server clock with a time service |
| Works from the tile but not from the app | SP-initiated settings or request address differ from the IdP-initiated ones | Compare the request’s ACS address with Okta’s settings |
| Login works but user lands in the wrong place | Wrong or missing RelayState | Set the default RelayState or fix the app’s deep link |
| Login works but profile is empty | Missing attribute statements | Add the attributes the app expects, with the exact names |
Be careful with captured assertions. They contain real user data. Treat a capture like a password, and do not paste it into public chats or tickets. Redact personal details before sharing.
Monitoring for the long term
Good teams do not wait for users to complain. They watch for a rise in failed SSO events for a given app in the Okta log, and they set an alert. They keep a list of every SAML app with its ACS URL, Audience URI, certificate expiry date, and owner. They test SSO after any change to the app’s domain, load balancer, or certificate. Even a simple weekly look at the failure count will catch most problems before a big group of users is locked out.
15Design Patterns and Anti-Patterns
Some habits keep SSO calm for years. Others cause a crisis at the worst moment.
Patterns worth copying
One Okta app per environment
Create separate apps for development, test, and production. Each has its own ACS URL and Audience URI. A mistake in test never touches real users.
Stable entity names
Choose names that do not depend on a server name or a team name. If you can, use a label that will survive a move to a new host.
Metadata exchange
Import and export metadata files instead of typing values. This removes most typing errors and shows when the certificate changes.
Per-tenant values
For multi-customer apps, store each customer’s ACS URL, Audience, and Okta certificate together, and look them up using the address the request arrived at.
SSO inventory
Keep a simple registry of every SAML app, with its values, owner, and certificate expiry. It pays for itself the first time something breaks.
Change together
Whenever a domain changes, update the app and the Okta settings in the same planned window, with a rollback plan ready.
Anti-patterns to avoid
The habit
A team gives every internal app the same Audience URI, because it is easier to remember and saves setup time.
Why it hurts
Any assertion made for one app is now valid at every other app. The audience check becomes useless, and a weak app can be used to break into a strong one.
Do this instead
Give each app and each environment its own unique Audience URI, and write it in the registry.
The habit
When a login fails, a developer turns off audience or destination checking in the app so that “it just works”.
Why it hurts
The mismatch is still there, hidden. The security gap stays open for years, and nobody remembers it exists until an audit or an incident.
Do this instead
Find the exact mismatch with a captured assertion and fix the value in Okta or the app.
The habit
The ACS URL points at a server name that is likely to change, such as an individual machine or a temporary test address.
Why it hurts
Moving the app or replacing the server silently breaks SSO for everyone, and the fix must be done in two systems at once.
Do this instead
Use a stable, friendly address behind a load balancer or a managed gateway, and keep it the same for the life of the app.
16Best Practices and Common Mistakes
A short, practical checklist you can use every time you set up a SAML app in Okta.
Before you start
- Read the vendor’s current SAML setup page, and note the ACS URL, the entity ID, and any special notes.
- Ask whether the vendor offers a metadata file or link. Prefer it over typing.
- Decide who will own the app, and who will renew the certificate.
- Confirm whether the app needs IdP-initiated login, SP-initiated login, or both.
While you configure
- Paste values from the source. Never retype them from a screenshot.
- Keep the Recipient and Destination box ticked unless the vendor says otherwise.
- Pick the Name ID format that the app expects, and set the application username to match.
- Send only the attributes the app needs. Less data means less risk.
- Use the assertion preview before assigning real users.
After you finish
- Test with an assigned user in a clean private browser window, for both login directions.
- Record the values and certificate expiry in your registry.
- Set an alert for repeated failed SSO events in the Okta log.
- Plan certificate renewal at least a month before expiry.
Mistakes seen again and again
Trailing slash
One side ends with a slash, the other does not. To a computer, they are two different strings.
http versus https
A single missing letter “s” produces a mismatch, and is also a security weakness.
Swapped values
The entity ID is pasted into the ACS field, or the other way round. Both look like web addresses, so it is easy to do.
Hidden characters
Copying from a document or email adds spaces or line breaks. A plain text editor shows them.
Wrong environment
A production Okta app is set up with test values, or the other way round, and nobody notices until launch day.
Forgotten certificate
The certificate expires and no one is alerted. Every user is then locked out at once.
A fast mental check: the ACS URL must be an address that actually works on the internet, the Audience URI only needs to be a unique name. If you ever paste a value into the wrong box, this difference helps you notice.
17Advantages, Disadvantages, and Trade-Offs
The strict matching of the ACS URL and Audience URI is both a strength and a nuisance. Here is the honest picture.
Advantages
- Strong protection from assertions being sent to, or used at, the wrong application.
- The app never sees passwords, and Okta handles multi-factor checks.
- One place for access rules: add or remove a user in Okta and all apps follow.
- Mature standard with broad support in business software.
- Clear, checkable values that make audits and reviews simple.
Disadvantages
- Exact matching makes small typing errors cause full outages.
- Vendors use different words for the same fields, which confuses people.
- Certificate rotation needs coordination across two systems.
- Error messages are often vague and vary by product.
- Each new app and each environment adds more values to manage.
Trade-offs to think about
- Security versus convenience: IdP-initiated logins are friendly for users but have less protection against replay. Choose per app.
- Simplicity versus flexibility: one ACS URL is simple. Several requestable URLs allow regional or branded setups, but need careful upkeep.
- Typed values versus metadata: typing is quick for a single app. Metadata exchange takes slightly longer at the start but removes many errors.
- Shared versus unique audience names: shared names save effort and weaken security. Unique names cost a little more bookkeeping and add real safety.
How this compares with OpenID Connect
Okta also supports OpenID Connect, often shortened to OIDC, a newer way to do SSO built on a different design. It has close cousins of both values. The redirect URI plays a role like the ACS URL: it is the registered address where the login result is delivered, and it must match exactly. The client ID plays a role like the Audience URI: it names the app that the token is meant for. If you understand these two SAML values well, the OIDC ideas will feel familiar. SAML is still very common for older and enterprise software, while OIDC is common for newer web and mobile apps.
SAML and OIDC are like two postal systems. They use different forms and different envelopes, but both need a verified delivery address and a clear name on the package. Learning to fill in one form properly prepares you for the other.
18Deployment and Cloud: Load Balancers, Proxies, and the ACS URL
Many “mystery” mismatches have nothing to do with Okta. They come from the network layers that sit in front of your application.
The app sometimes does not know its own address
In a modern cloud setup, users do not talk straight to your application servers. Their request first meets a CDN, a web firewall, or a load balancer, and only then reaches the app. A common design is called TLS termination: the load balancer handles the secure HTTPS connection, then passes the request on to the app over plain HTTP inside the private network. The app, looking only at the connection it received, may believe its own address starts with “http” and has an internal host name. If the app builds its ACS URL from what it sees, the result will not match the public address you typed into Okta.
Picture a large office where a receptionist at the front forwards visitors to a back room. The people in the back room only see “a visitor from the front desk”. If you ask them “what is the building’s street address?”, they might say the name of their internal corridor. The public street address is something only the front of the building knows. The app has the same problem unless the front layer tells it the truth.
The usual fixes
Forwarded headers
Load balancers can pass along the original scheme and host name in standard headers. Configure the app framework to trust these headers from your own load balancer only.
Fixed public address
Better still, store the public ACS URL as a setting in the app. It is then never guessed from the incoming request.
Keep paths unchanged
If a gateway rewrites paths, such as adding or removing a prefix, the address the user sees may differ from the address the app sees. Keep the ACS path the same on both sides.
Allow POST and large bodies
The response arrives as a form post. Firewalls, CDNs, and API gateways must let it through, and must accept a body that can be several kilobytes.
Caching and the ACS endpoint
A content delivery network is built to remember pages. The ACS endpoint must never be remembered. Each response is unique to one user and one moment. Configure the CDN to pass POST requests to the app and to skip caching for the whole SAML path. Otherwise, one user’s login may be served wrongly to another, or a login may fail because the app never received the request.
Many servers behind one address
With several app servers behind a load balancer, the browser may reach a different server for the second step than the first. For SP-initiated logins, the app remembers the request number it sent. For replay protection, it remembers assertion numbers it has seen. If each server keeps its own private memory, a response can arrive at a server that never saw the request, and a good login will be refused. The fix is to keep that small memory in a shared place, such as a shared cache or database, with a short expiry.
Real-world example: an AWS-hosted application
A team runs its web app on AWS behind an Application Load Balancer that ends the HTTPS connection. The app reads the original scheme from the forwarded protocol header, and a shared in-memory cache keeps recent request and assertion numbers. The public ACS URL is stored as an application setting. The team also tests SSO after every infrastructure change, such as new firewall rules or a new domain, because those are the changes most likely to break it.
If you move an app to a new domain, to a new gateway, or behind a new CDN, treat it as an SSO change. The ACS URL, the Audience URI, and perhaps the certificate may all need to be reviewed together.
19The Other Half: What Okta Gives the Application
So far we focused on the two values that come from the app. The trust only works if the app also saves the values that come from Okta.
The three things the app needs from Okta
After you finish creating the app in Okta, the Sign On tab shows the details the application must be told. Many apps accept them all at once through a metadata link or file. Others ask for each item separately.
Sign-on address
Okta’s own address for this app, where the app sends users to log in. It contains an identifier unique to your app, so it differs from app to app.
Issuer
Okta’s name for this app connection. The app compares it with the issuer inside every response, and rejects a response from any other name.
Signing certificate
The public half of the key Okta uses to sign responses. The app uses it to prove the response is genuine and unchanged.
Do not mix up the two sets of values
A very common error is to swap the two sets. The app’s ACS URL and Audience URI go into Okta. Okta’s sign-on address, issuer, and certificate go into the application. Each side stores what the other side gave it. It helps to write both sets on a small sheet with the headings “We give Okta” and “Okta gives us”.
| Value | Who owns it | Where you type it |
|---|---|---|
| ACS URL | Application | Okta, in Single sign-on URL |
| Audience URI | Application | Okta, in Audience URI (SP Entity ID) |
| Sign-on address | Okta | Application, as the identity provider’s login address |
| Issuer | Okta | Application, as the identity provider’s entity ID |
| Signing certificate | Okta | Application, as the trusted certificate |
Two companies agree to work together and swap contact sheets. Company A gives its delivery address and its official name. Company B gives its sender name, its office address, and a sample signature to compare against. Each company keeps the other’s sheet. If either sheet is wrong, orders go astray or get refused.
Name ID and attributes: who is the user?
One more part of the response matters to the app: the name of the user. The Name ID is the main identifier, such as an email address. The application must match it to an account in its own system. If the app expects an email address but Okta sends a different format, the app will say it cannot find the user, even though everything else is correct. Extra attributes, such as first name and group, are matched by their exact attribute name. A tiny spelling difference means the app sees nothing. These settings are not the ACS URL or the Audience URI, but they are often the very next problem after you fix those two.
Finish the two address and name values first, then test. Only after a login reaches the app and fails on the user, move on to Name ID and attributes. Solving one problem at a time makes each failure easier to read.
20Performance, Scalability, and Reliability
The ACS endpoint is a small piece of code, but it can face a huge crowd all at once. Here is how to keep it fast and how to handle failures.
The morning rush
Logins are not spread evenly across the day. At the start of a work shift or the start of an exam, thousands of people may open the app within the same few minutes. Each of them triggers one trip to Okta and one post to the ACS URL. The ACS endpoint has real work to do on each one: it decodes the text, parses the XML, checks a digital signature, checks several values, may decrypt the assertion, and creates a session. Checking a signature uses noticeable computing power, so a login spike is a CPU spike.
A stadium has many entry gates. If only one gate is open when fifty thousand fans arrive, the line is enormous, even if each ticket check is quick. Opening more gates (more app servers) solves it, as long as every gate follows the same checking rules and shares the same list of used tickets.
Ways to keep it healthy
- Scale out: run several app servers behind a load balancer, and add more before known busy times.
- Keep the endpoint light: do the validation, create the session, and redirect. Leave heavy work, such as loading large profiles or sending emails, for after the redirect.
- Reuse parsed settings: load Okta’s certificate and the saved values once and keep them in memory, rather than reading them from a database on every login.
- Use a shared, expiring memory: for request numbers and used assertion numbers, with a lifetime a little longer than the assertion’s validity.
- Set sensible session lengths: a longer app session means fewer logins and less load, but a slightly longer window after a user is removed. Choose with your security team.
- Limit body size sensibly: allow enough for a normal response, and refuse anything wildly bigger, which is likely abuse.
What if Okta is unavailable?
The application only needs Okta at the moment of login. Users who already have an app session usually keep working until the session ends, because the app does not call Okta for each page. New logins, however, cannot succeed. Good teams plan for this. They keep a protected emergency way in for a few administrators, such as a local account with a very strong password and extra controls, and they test it. They also watch Okta’s status page and set a clear message to show users when sign-in is down.
Other failure scenarios
| Failure | Effect | How to recover |
|---|---|---|
| Okta signing certificate expires | All logins fail at signature check | Upload the new certificate to the app, then test |
| Domain or address changes | ACS and Audience values stop matching | Update Okta and the app together, or roll back |
| App servers drift apart in time | Some logins pass, others show expired assertions | Fix clock synchronisation on every server |
| Shared memory cache is lost | SP-initiated logins fail for a short time | Restore the cache, users simply retry |
| Firewall blocks the ACS path | Users see a blank page or a gateway error after signing in | Allow POST to the ACS path and larger bodies |
| Okta app deactivated or user unassigned | Okta refuses before delivery | Reactivate the app or assign the user |
Large companies with big morning login peaks, such as retailers, banks, and school systems, rehearse these failures. A practice run of “the certificate expired” or “Okta is slow” shows who does what, long before a real incident.
21Glossary of Terms
A quick reference for every term used in this guide, in plain words.
| Term | Plain meaning |
|---|---|
| SSO | Single sign-on. Prove who you are once, then reach many apps without more passwords. |
| IdP | Identity Provider. The system that checks users. In this guide, Okta. |
| SP | Service Provider. The application the user wants to use. |
| SAML | The standard language the IdP and the SP use to share login proof. |
| Assertion | The signed statement about the user, carried from Okta to the app. |
| Response | The envelope that holds one or more assertions plus delivery details. |
| AuthnRequest | A message from the app asking Okta to log a user in. |
| ACS URL | The app’s address that receives and uses the signed response. |
| Single sign-on URL | Okta’s screen label for the ACS URL. |
| Audience URI | The name of the app that an assertion is meant for. |
| Entity ID | A unique name for one side of the trust. Both Okta and the app have one. |
| Destination | The address a response says it was sent to. |
| Recipient | The address the assertion says may use it. |
| Issuer | The name of the side that created the message. |
| RelayState | Extra text that travels along so the app knows where to send the user next. |
| Name ID | The main identifier of the user, such as an email address. |
| Attribute | An extra fact about the user, sent with the login, such as a name or group. |
| Binding | The method used to carry a message through the browser. |
| Metadata | A file describing a system’s name, addresses, and certificate. |
| Certificate | A public key wrapped with details, used to check a digital signature. |
| Clock skew | The small difference between two computers’ clocks. |
| Replay | Reusing a captured login message a second time. |
| OIN | Okta Integration Network. The catalogue of ready-made app templates. |
| OIDC | OpenID Connect. A newer SSO standard with a redirect URI and a client ID. |
22Frequently Asked Questions
Short answers to the questions people ask most.
23Summary and Key Takeaways
If you remember only a handful of ideas from this guide, make them these.
Key Takeaways
- ACS URL means “where”: it is the application’s address that receives the signed login response. Okta calls the field Single sign-on URL.
- Audience URI means “who for”: it is the application’s entity ID, written into the assertion so only that app accepts it.
- Both values belong to the application. You copy them into Okta from the vendor’s page or metadata, and never invent them for a ready-made product.
- Matching is exact. A slash, a capital letter, or a missing “s” in https can break a login. Copy and paste, and compare in plain text.
- The app validates many things: signature, issuer, destination, recipient, audience, time, and replay. Any one failure ends the login.
- Keep environments separate. Use a different Okta app, ACS URL, and Audience URI for each, and track them in a registry along with certificate expiry dates.
- Troubleshoot with evidence: read the Okta log, capture the response with a browser add-on, and compare the three values before changing anything.