What the Browser Carries
Module 6 of 6 in the chapter Single Sign-On: The Browser Is the Broker, chapter 4 of Securing Salesforce: Identity and Access. Each module stands on its own.
The question this module answers: What’s actually inside the SAML request and the SAML response, and what does Salesforce check before it lets Priya in?
A big old XML file
Section titled “A big old XML file”All through this chapter, Priya’s browser has been carrying two messages: a SAML request, and a SAML response. It’s time to open them.
SAML stands for Security Assertion Markup Language. It’s an open standard, published by OASIS, and the version in use today, SAML 2.0, dates from 2005. An assertion is a statement one system makes about a person to another: “this is Priya, and here’s how she proved it.” That’s what the identity provider sends to Salesforce.
And what does a SAML message actually look like? It’s just a big old XML file. XML is text with labelled parts, so a program can find each part by its name: who sent it, who it’s for, when it was made. You don’t need to read XML to understand single sign-on. You need to know which parts are in there, and why each one is there. So this module names the parts, then opens a sample of each message so you can find them. Chapter 6 goes further, and ties each part to the Setup field that controls it.
Who writes the request?
Section titled “Who writes the request?”Here’s the question I ask every class. Who creates the SAML request? People look at the swim lane from module 3, and they say the browser.
It isn’t the browser. The browser only carries it. The service provider creates it. Priya asks Salesforce for a record. Salesforce sees she isn’t logged in, but it knows this org has an identity provider. So Salesforce writes a SAML request, puts it on the browser, and sends the browser on to the identity provider. The request says, in effect: please go log this person in.
What’s in it is short:
- Who’s asking: the issuer, Salesforce’s own name in this relationship (its Entity ID, usually the org’s My Domain address).
- Where it’s going: the identity provider’s address.
- Where to send the answer: Salesforce’s own login address, so the identity provider knows where to send Priya back.
- Its own ID, and the time it was made. Every SAML message gets a unique ID and a timestamp. Hold on to both; they matter in a moment.
- A signature, if you choose. Salesforce can sign its requests, with the Request Signing Certificate from module 4, so the identity provider knows the request really came from Salesforce.
The response: a sealed letter in an envelope
Section titled “The response: a sealed letter in an envelope”The identity provider shows Priya the login screen, she proves who she is, and it writes the SAML response. Think of the letters with the seals from chapter 3: the response is the envelope, and inside it is the sealed letter, the assertion.
The envelope says:
- Where it’s going: back to Salesforce, the destination.
- Which request it answers. This one matters. The response is in response to a specific request, and it carries that request’s ID. So it can’t just come in cold. If someone grabs a response meant for another request and tries to use it, the IDs don’t match.
- Who it’s from, and when it was made.
- Whether it worked. The status must say success.
What’s inside the assertion
Section titled “What’s inside the assertion”Inside the envelope is the assertion itself: the identity provider’s statement about Priya. These are the parts to know:
- The issuer: who’s making the statement, the identity provider.
- The subject: who to log in as. This is the identity provider telling Salesforce, “log her in as this person.” For Salesforce, it must be either the user’s Salesforce username or their Federation ID. Chapter 6 shows why the Federation ID is usually the better choice.
- The conditions: when the assertion is valid, not before one time and not on or after another, and who it’s for, the audience. The audience must match the Entity ID Salesforce expects.
- The recipient: where it’s meant to be delivered, Salesforce’s login address.
- The authentication statement: when Priya signed in, and how she proved it. Remember from the front door that Salesforce needs to know how she proved who she is, not only who she is.
- Attributes, if you want them: extra fields, such as her email address, title or role. The identity provider can add them, and Salesforce can use them to create or update her user record as she logs in. That’s just-in-time provisioning, in chapter 12.
- The signature: the seal over all of it, made with the identity provider’s private key. Salesforce’s own advice is that the identity provider signs both the response and the assertion. The sample I showed classes in 2024 was signed with SHA-1; today, use SHA-256 (chapter 3, module 3).
Open the messages
Section titled “Open the messages”Here are all three side by side: the request Salesforce writes, the envelope the identity provider sends back, and the sealed letter inside it. The small numbers are the checks Salesforce makes, coming up next.
Now the real thing. These are trimmed from the samples I walk through in class, with Priya in place of my demo user, example addresses, and SHA-256 in place of the old SHA-1. MyDomainName stands for your org’s My Domain, the way Salesforce’s own documentation writes it. The long IDs and signature values are cut short with ”…”.
The SAML request
Section titled “The SAML request”<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" ID="_2CAAAAYtjf8PNMDAwMDAw…" IssueInstant="2026-11-03T15:03:24Z" Destination="https://idp.example.com/sso" AssertionConsumerServiceURL="https://MyDomainName.my.salesforce.com" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"> <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://MyDomainName.my.salesforce.com</saml2:Issuer></saml2p:AuthnRequest>That’s the whole request. Find the parts:
IDandIssueInstant: its own ID and the time it was made.Destination: where it’s going, the identity provider.AssertionConsumerServiceURL: where to send the answer, back to Salesforce.Issuer: who’s asking, Salesforce.
There’s no signature on this one. Salesforce adds it only if you choose to sign requests.
The SAML response, with the assertion inside
Section titled “The SAML response, with the assertion inside”<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" ID="_3c3bd60b9ecebc800920…" InResponseTo="_2CAAAAYtjf8PNMDAwMDAw…" IssueInstant="2026-11-03T15:04:36Z" Destination="https://MyDomainName.my.salesforce.com" Version="2.0"> <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://idp.example.com</saml2:Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> <ds:Reference URI="#_3c3bd60b9ecebc800920…"> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> <ds:DigestValue>cxnM4A0w7HXsiDTiug…</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>FfCKfRAeCqEuqOwr87…</ds:SignatureValue> </ds:Signature> <saml2p:Status> <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </saml2p:Status> <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_ec3f3208f463445cd2fa…" IssueInstant="2026-11-03T15:04:36Z" Version="2.0"> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">…the same shape, over the assertion…</ds:Signature> <saml2:Subject> <saml2:NameID>priya@example.com</saml2:NameID> <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml2:SubjectConfirmationData InResponseTo="_2CAAAAYtjf8PNMDAwMDAw…" NotOnOrAfter="2026-11-03T15:09:36Z" Recipient="https://MyDomainName.my.salesforce.com"/> </saml2:SubjectConfirmation> </saml2:Subject> <saml2:Conditions NotBefore="2026-11-03T15:04:06Z" NotOnOrAfter="2026-11-03T15:09:36Z"> <saml2:AudienceRestriction> <saml2:Audience>https://MyDomainName.my.salesforce.com</saml2:Audience> </saml2:AudienceRestriction> </saml2:Conditions> <saml2:AuthnStatement AuthnInstant="2026-11-03T15:04:36Z"> <saml2:AuthnContext> <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef> </saml2:AuthnContext> </saml2:AuthnStatement> <saml2:AttributeStatement> <saml2:Attribute Name="email"> <saml2:AttributeValue>priya@example.com</saml2:AttributeValue> </saml2:Attribute> </saml2:AttributeStatement> </saml2:Assertion></saml2p:Response>It looks like a lot. Read it as the envelope, then the letter.
The envelope, the outer Response:
InResponseTo: the request’s ID, character for character. This is the response being “in response to a specific request”.Destination: Salesforce’s login address, the same one the request asked for.Issuer: the identity provider.Signature: the seal on the envelope. Look at the twoAlgorithmvalues:rsa-sha256andsha256. In my 2024 sample, those saidsha1.Status:Success.
The letter, the Assertion inside:
ID: its own ID, so Salesforce can refuse it if it comes back a second time.Issuerand its ownSignature: the identity provider again, sealing the assertion itself.SubjectandNameID: who to log in as. Here it’s Priya’s Federation ID,priya@example.com.SubjectConfirmationData: the request’s ID once more, theRecipient, and aNotOnOrAftertime.Conditions:NotBeforeandNotOnOrAfter, five and a half minutes apart, and theAudience, Salesforce’s Entity ID.AuthnStatement: when Priya signed in, and how.PasswordProtectedTransportmeans a password, over TLS.AttributeStatement: one extra field, her email address.
Notice how often the same few values repeat: Salesforce’s address three times, the request’s ID twice, the identity provider’s name twice. That’s on purpose. Each copy is checked in a different place, so a message changed or copied from somewhere else fails at least one check.
Five questions before Priya gets in
Section titled “Five questions before Priya gets in”So the response arrives at Salesforce’s login server, in Priya’s browser. What does Salesforce check? Here’s how I teach it. Five questions:
- The signature: is it valid?
- Who did it come from? Our identity provider?
- Is it going to us, the service provider?
- Is it within the date window?
- And who am I logging in?
Every answer must be yes. And Salesforce adds a sixth: have we seen this assertion before? Every assertion has a unique ID, and Salesforce refuses one it’s already used.
When an answer is no, Salesforce writes it down. Each failure has its own name in Login History, and that name tells you which question failed.
Learn those names. When a single sign-on login fails, Login History is the first place to look, and the error usually points straight at the part that’s wrong: the certificate, the issuer, the Entity ID, the clock, or the user. Chapter 16 goes further, with Salesforce’s SAML Assertion Validator.
Why the times are there
Section titled “Why the times are there”Why put a timestamp in a message at all? What are we protecting against?
Picture someone who catches a SAML response, stores it, and comes back a day later to use it again, pretending to be Priya. That’s called a replay attack. The time window stops it: an assertion is only good for a few minutes. Salesforce’s rule is that it must receive the assertion within 5 minutes of its timestamp, plus or minus 3 minutes. In practice, that’s up to 8 minutes after the timestamp, or 3 minutes before it. And the unique ID stops the same assertion being used twice, even inside the window.
Now you can see why the clocks from module 5 matter so much. Both sides compare these times against their own clocks. If the service provider’s clock or the identity provider’s clock is off by more than the window, every SAML message is rejected, and single sign-on collapses for everyone. Both should be on the same, exact time, kept in sync automatically. Clocks that are off can be one of the single greatest sources of single sign-on failures. And it’s one more reason for the back door: someone has to be able to get in and fix the clock.
Enough to get you in, by itself
Section titled “Enough to get you in, by itself”Here’s the part that should make you sit up. A SAML response is enough to get Priya into Salesforce by itself. Whoever holds a valid one, inside its window, is let in as her.
That’s why everything around it matters. It has to travel over TLS, the safe road from chapter 3, so nobody can read it on the way. It has to be signed properly, so nobody can change it. It’s tied to one request and one recipient, and it expires in minutes, so a stolen one is worth very little. Each part of the message is there for a reason.
The end of the chapter
Section titled “The end of the chapter”You’ve now seen what single sign-on really is: one identity provider, a browser that carries everything by redirect, a certificate installed in advance, a back door for the people who keep it running, and a signed message with a few exact parts.
It’s like the man who takes his car to a mechanic because it’s running badly. The mechanic listens, picks up one screwdriver, turns one screw, and says, “That’ll be three hundred dollars.” “Three hundred dollars? To turn one screw?” “No. It’s five dollars to turn the screw, and two hundred and ninety-five to know which screw, and how far to turn it.” Single sign-on is like that. There aren’t many settings, but every one has to be exactly right.
So turn the screws yourself. This chapter’s practice has you build two free Salesforce orgs, one as the identity provider and one as the service provider, ready to connect. Then chapter 5 asks the question every identity design starts with: single sign-on or OAuth?
What an architect decides here
Section titled “What an architect decides here”- Which values each side expects: the issuer, the Entity ID and audience, the recipient address, and what goes in the subject, written down for both sides.
- What gets signed, and how: the response and the assertion, with SHA-256; and whether Salesforce signs its requests.
- Which attributes the identity provider sends, and whether Salesforce uses them (chapter 12).
- Where to look first when a login fails: Login History, and the error’s name.
- The clocks: both sides kept on the same time, automatically, and watched.
Explore
Section titled “Explore”- SAML Login Errors (opens in a new tab) (Salesforce Help, Winter ‘27; checked 2026-11-07)
- Bindings for the OASIS Security Assertion Markup Language (SAML) V2.0 (opens in a new tab), section 3.4.8, an example message exchange (OASIS Standard, 15 March 2005; checked 2026-11-07)
