Your federated sign-in tests install an already-authenticated principal in the harness — which part of the integration stays unexercised?
answer
- the test starts too late
- everything before the principal exists
- rejection code fails silently
- authorisation covered, authentication not
- signature, audience, window, replay skipped
basics
~20 sA helper-installed principal leaves the whole validation path unexercised. The test starts after the assertion would have been parsed, its signature checked, its audience and validity window enforced and its identifier recorded — so every rejection rule the service provider owns is untested.
solid answer
~40 sA helper that installs a ready-made principal enters the system at the point where a federated login has already succeeded. Everything after that — role mapping, the session you issue, the pages the principal may see — is genuinely covered. Everything before it is not: parsing the message, verifying the signature against the identity provider's registered signing certificate, enforcing `AudienceRestriction`, enforcing the `SubjectConfirmationData` and `Conditions` `NotOnOrAfter` bounds, correlating `InResponseTo` to a request you actually issued, and refusing an assertion identifier you have already seen. That code is yours, it is the code an attacker reaches first, and a suite full of green principal-injection tests says nothing about it. Draw the line explicitly: principal injection is an authorization fixture, not an authentication test.
go deeper
Recall that signing in through a customer's identity provider has two halves: they authenticate the person, and your server checks the message before trusting it. A test that hands your code a ready-made user skips the second half entirely.
Be able to list what the skipped half does: parse, verify the signature, check the audience and the validity bounds, correlate the response to a request you made, and refuse a repeat. Explain why each needs its own test.
Show that you know rejection code fails silently, so its absence from coverage is a production risk rather than a tidiness issue. Describe the small front-door suite you would add and what each negative case asserts.
Argue where the line between the two suites sits as a standing policy: which tests may use the fast helper, which must drive the real entry point, and how you stop the fast path quietly becoming the only path as the team grows.
## What the helper actually does Almost every server framework ships a test affordance that puts an authenticated principal into the request context before the handler runs. It exists for a good reason: most tests are about what an authenticated user is allowed to do, and re-driving a full login for each of them would be slow and irrelevant. The problem is that on a **federated** integration this helper silently redefines what "the login test" means. The rota tool for a theatre chain signs its staff in through each venue operator's identity provider. When the suite installs a principal directly, the test is exercising the rota tool **after** a successful federated sign-in, and the entire body of work that decides whether a sign-in *was* successful never runs. ## Where the line falls | Step | Who owns it | Covered by principal injection? | |---|---|---| | The venue operator authenticates the person | the customer's identity provider | no, and never yours to test | | Message arrives at your `AssertionConsumerService` and is parsed | you | **no** | | Signature verified against the registered signing certificate | you | **no** | | `AudienceRestriction` checked against your own `entityID` | you | **no** | | `Conditions` and `SubjectConfirmationData` `NotOnOrAfter` enforced | you | **no** | | `InResponseTo` correlated to a request you issued | you | **no** | | Assertion identifier recorded so a second post is refused | you | **no** | | `NameID` joined onto a local account | you | **no** | | Local session issued, roles applied, pages authorised | you | yes | Everything above the last row is the half of the system this branch is about, and it is exactly the half the helper skips. ## Why that gap is dangerous rather than merely incomplete The skipped code is **rejection** code. Its whole purpose is to say no, and rejection code has a property that acceptance code does not: when it stops working, nothing visibly breaks. A verifier that quietly stops checking `AudienceRestriction` still lets every legitimate person in, every day, for months. The suite is green because the suite never asked. The failure mode is not "logins broke" — it is "an assertion minted for a different service provider is now accepted", and you find out from somebody else. This also inverts the usual testing instinct. For most features you write the happy path first and the error cases when you have time. Here the happy path is the cheap half and the negative cases are the deliverable: a wrong audience, a wrong issuer, an unsigned message, a signature over the wrong part of the document, an identifier already seen, an expired condition, a response correlating to no request you made. Each of those should be a named test asserting a **specific** rejection with a specific outcome — not merely that something failed, because "it failed" is also what a typo in the fixture produces. ## What to do instead Keep the helper — it is the right tool for the eighty tests about what a shift manager may edit. Add a second, much smaller class of test that enters through the front door: 1. Stand up a stand-in issuer the suite controls, with its own keypair, registered against a test connection as that venue's signing certificate. 2. Drive one full positive case end to end: request out, signed message posted back to your endpoint, session issued. 3. Drive the negative cases from the same builder, one mutation at a time, asserting the specific rejection each is supposed to produce. 4. Assert the replay case: post the identical accepted message a second time and require refusal. A dozen tests of that shape cover the code the other eighty cannot reach. They are slower, and that is fine, because there are a dozen of them. ## Saying it in an interview The answer an interviewer is listening for is not "we mock the identity provider". It is the ability to draw the line: *this helper starts the test after validation, so it proves authorisation and proves nothing about authentication; the validation path is our code, it fails silently when it breaks, and it needs its own tests driven through a signing stand-in.* Naming which side of the trust boundary each piece sits on — the identity provider authenticates, the service provider verifies — is what separates a candidate who has integrated once from one who has operated an integration.
- If the identity provider belongs to the customer, whose code is actually under test here?Yours. The customer's identity provider authenticates the person and mints the message; everything from the moment that message reaches your endpoint is application code you wrote and deploy — parsing, signature verification, audience and window enforcement, replay refusal, the account join and the local session. The integration is not configuration you bought; it is a feature you own and must test like one.
- Is there any part of a federated sign-in a test genuinely cannot cover?Yes: whether the venue operator's identity provider actually authenticated the human it claims to have authenticated, and how. That is behind their trust boundary and unreachable from your suite. You can assert what you do with what they assert — including refusing to trust it when the message fails a check — but not the quality of their authentication.
- The suite already has a test that posts a valid assertion and gets a session. Is that enough?No. One positive case proves the acceptance path compiles and roughly works; it cannot detect a check that has been removed, because removing a check never breaks an accepted message. Coverage of this code is carried by the negative cases, each asserting a specific rejection for a specific mutation of the same fixture.
saying these in an interview costs you the question
- Says federated login is covered because the suite signs a user in.
- Treats a helper-installed principal as an end-to-end sign-in test.
- Assumes a green suite means a wrong-audience assertion would be rejected.
- Thinks only the browser redirect is missing from the coverage.
- Calls message validation the identity provider's job rather than the service provider's.
- Writes only the happy path and leaves rejection cases to manual checks.