The Enterprise Identity Buyer's Checklist, Annotated by an Engineer

A security questionnaire is not a test. It's a transcript.

Every row in it was written by a person, usually after something went wrong — to them, to a peer company, or to an auditor's satisfaction. Row 47 asks about deprovisioning latency because someone's contractor kept API access for five weeks after the engagement ended. Row 112 asks where signing keys live because a vendor once answered "in our config repo" and meant it. The spreadsheet looks like a bureaucratic artifact, and parts of it are, but the load-bearing rows are compressed incident history.

This matters because of how these documents get answered. A 300-row questionnaire arrives, sales forwards it, and someone spends a day converting each row into Yes / No / Partial with a comment box. Most rows are genuinely boilerplate — the ones about badge access at a data center you don't operate. Six or eight rows actually describe engineering commitments that will constrain your architecture for years. They are not marked, they are not adjacent, and they are phrased in the vocabulary of the person's last compliance framework rather than yours.

What follows is the translation layer for the identity rows: what each is literally asking, what it is actually asking, and what it costs to answer honestly. The framing throughout is that you are the vendor answering — the mirror image of evaluating a vendor, and a harder position, because here your answer becomes a contractual representation rather than a purchasing opinion.

"Do you support SAML 2.0 / OIDC single sign-on with our identity provider?"

What it looks like: a protocol support question. Ship a SAML endpoint, answer Yes.

What it's asking: can we turn your login off?

That's the whole point of the row. The customer's security model rests on one assumption: that access to corporate systems flows through a chokepoint they control, where MFA is enforced, conditional access rules apply, and disabling one directory account severs everything. A product with its own password login is a hole in that model — an account that survives the chokepoint, with a credential their policy never touched.

So "do you support SAML" really means "when we're done configuring, is it impossible for our people to reach your product any other way?" Building the SAML flow is the easy half. The expensive half is enforcement:

  • Can SSO be required per tenant, so that a user in the acme.com domain cannot use the password form even if they still have a password on file?
  • What happens to the fourteen accounts that existed before, created by self-signup? Are they linked to directory identities, or do you now have two user objects for the same human — one of which the customer's IdP has never heard of and cannot disable?
  • Does enforcement cover every entry point, including your mobile app, your CLI, your API tokens, and the password reset flow? Password reset is the classic miss: a tenant with SSO enforced, whose reset email still mints a session.
  • What's the break-glass path when their IdP is down? You need one, and the honest answer names it: a specific set of local admin accounts, exempt by design, with their own MFA and their own audit stream. Say so plainly. A vendor who claims zero exceptions is either wrong or has an undocumented exception, and the reviewer has seen both.

The answer worth writing is not "Yes, SAML 2.0 and OIDC supported." It's "Yes — SSO can be enforced per verified domain, which disables password and social login for those users across web, mobile and API; two named break-glass accounts remain, hardware-key protected, with alerting on use."

That second answer takes four times as long to build and ends the conversation. The first one produces a follow-up call.

"Do you support automated provisioning and deprovisioning (SCIM 2.0)?"

What it's asking: what is the maximum time between our termination event and the death of access in your product, and will you put that number in the contract?

Provisioning is only interesting to the reviewer in one direction. Nobody has ever had an incident because an account was created too slowly. The row exists for leavers.

Two things make this expensive to answer honestly.

First, you own only one segment of the chain. HR marks the termination, the IdP picks it up on its own cycle, the IdP's SCIM connector runs on its schedule — for some IdPs that's near-immediate on a directory event, for others it's a scheduled sync every 40 minutes — and then your endpoint receives a PATCH setting active: false. Your contribution to end-to-end latency may be two seconds inside a forty-minute chain. Answer for your segment, precisely, and say where the rest of the time goes. Reviewers who own the IdP side already know this; the answer that describes it accurately reads as competence.

Second — and this is the part that turns a checkbox into an architecture review — deactivation in your database is not revocation. If your access tokens are self-contained JWTs with a one-hour lifetime and no introspection on the resource path, your true answer is "up to one hour," regardless of how fast SCIM lands. The reviewer's question is about the observable end of access, not about a row changing state. There's no configuration flag that fixes this; it's a consequence of a token design chosen years earlier, and the only real remedies are shorter lifetimes, introspection, or a revocation check on the resource server — each with a latency and availability cost you now have to defend.

So the honest answer has two numbers in it: the time to process a SCIM deactivate (measured, at p99, not aspirational), and the worst-case time until an already-issued token stops working. Publishing the second number is unusual enough that it functions as a differentiator.

"Describe your session timeout policy, including idle timeout, and whether it is configurable per customer."

What it's asking: the shared workstation and the stolen laptop.

Two distinct threats sit behind this row. A clinical workstation or a warehouse terminal where the previous user walked away — that's idle timeout. A device that leaves the building with a live session on it — that's absolute session lifetime plus the ability to kill sessions centrally, right now, for one user.

The engineering subtlety almost nobody discloses: most products cannot actually measure idleness. A modern single-page app polls for notifications, refreshes tokens on a timer, and reconnects a websocket — all of which look like activity to a naive implementation. If your idle timer resets on any authenticated request, your 15-minute idle timeout is a 15-minute timeout that never fires, and the customer's control is decorative. Defining idleness in terms of user-initiated interaction, and propagating that definition to every client you ship, is real work. Very few teams have done it; almost all answer this row as though they have.

The second subtlety is that "configurable per customer" turns a constant into per-tenant policy state on the critical path of every request, which is a larger commitment than it appears — see why that's an architectural change rather than a setting.

One row here is worth pushing back on: concurrent session limits. It's frequently inherited from a mainframe-era control, and implementing it requires a globally consistent session index — an availability liability sitting in front of every login, protecting against a threat that per-device session listing and revocation handles better. "No, and here's what we do instead" is a legitimate answer, and a well-argued one lands better than a grudging yes that ships a fragile counter.

"Are audit logs immutable, retained for N years, and exportable to our SIEM?"

What it's asking: can we run our own detection on your data, and can we reconstruct a decision eleven months later?

Three separate commitments wear one row's clothing.

Immutable means append-only with no privileged path to edit — including for your own engineers during an incident. If the same database credential that serves reads can update the audit table, the honest answer is "logically append-only, no application path to modify, storage-layer access is possible for named operators and is itself audited." Say the real thing. Reviewers grade honesty here more than they grade the property.

Retained for N years collides with the erasure row that appears elsewhere in the same spreadsheet, usually under privacy. The two are in direct tension and the questionnaire never acknowledges it. You need a stated position — typically that audit records are retained under a legal-basis exemption, with the identifiers pseudonymized rather than removed. Have that written down before you're asked, because the person asking about erasure and the person asking about retention are often different people at the same customer.

Exportable to our SIEM is the row with the highest hidden cost. It reads like a query feature; it is a durable per-tenant delivery pipeline. Your audit stream is multi-tenant, and their export must contain exactly their tenant's events, with no gaps and no duplicates, resumable after their collector is down for a weekend, and backpressure-tolerant when one tenant runs a 40,000-user directory sync. That's a cursor per subscription and an at-least-once contract with a documented deduplication key — not a SELECT with a date range. Teams that build it as a query discover the difference during the customer's first outage, which they will notice, because gaps in an audit feed are exactly what their tooling alerts on. (The ongoing cost of that pipeline is its own subject.)

The reconstruct-a-decision half is the one that cannot be retrofitted. Recording that access was granted is a log line; recording which policy version and which group membership produced the grant is a schema decision. You can add logging later. You cannot add the past.

"Will you notify us of a security incident affecting our data within 24 hours?"

What it's asking: we have a 72-hour regulatory clock, and you sit upstream of it.

Under GDPR the controller must notify a supervisory authority within 72 hours of becoming aware of a personal data breach. If your customer is the controller and you're the processor, their clock cannot start until yours does. The 24-hour figure isn't arbitrary hostility; it's them reserving 48 hours for their own assessment.

Here's what makes this row an engineering commitment rather than a legal one. The clock starts at your awareness, so agreeing to 24 hours is agreeing to two capabilities you may not have:

flowchart LR
    A[Event occurs] -->|unbounded, invisible<br/>in the contract| B[Detection]
    B -->|clock starts here| C[Triage:<br/>is it an incident?<br/>which tenants?]
    C -->|contractual deadline| D[Per-tenant<br/>notification]

The gap between the event and detection is unbounded and invisible in the contract — which is why the mature move is to also answer the detection question, unasked. And the triage box is where identity vendors get hurt: "which tenants were affected" has to be answerable in hours. If your logs, your object storage keys, your caches and your incident tooling aren't tenant-tagged end to end, the only honest answer during a real incident is "all of them," and you will notify 900 customers about an event that touched three. That is a tenancy design requirement arriving disguised as a legal deadline.

Two more things worth getting right before signing: define "incident" precisely (a blocked scan attempt is not one, and without a definition you're committing to a notification treadmill that trains your customers to ignore you), and confirm you can actually reach every tenant's security contact — which means collecting that contact at onboarding, not looking for it at 2 a.m.

"Where are signing keys stored, who can access them, and do you support customer-managed keys?"

What it's asking: can one of your employees mint a token that impersonates our CEO?

For most vendors, key custody is about data at rest. For an identity vendor it's categorically different: the signing key is the security boundary. Possession of it is the ability to forge any identity in the tenant, silently, with no login event and nothing in the audit trail to distinguish it from a legitimate session. There's no equivalent in a storage product, and reviewers who understand your category ask this row much harder than the rest.

The answers that matter:

  • Non-exportable is the property, not encrypted-at-rest. Keys generated in an HSM or KMS where the private material never leaves, and signing is an API call, beats keys "encrypted with a KEK" — because the second architecture always has a code path that decrypts them, and that path is reachable by whoever can run code in production.
  • Blast radius is a per-tenant question. One global signing key across all tenants means a single compromise forges every customer's identities. Per-tenant issuers with per-tenant keys convert a platform-wide catastrophe into a single-tenant one — and make the answer to "can you rotate ours without affecting anyone else" a straightforward yes.
  • Rotation is the follow-up, always. Overlapping validity, both kids published in JWKS throughout, no maintenance window, customer-initiable. A platform whose rotation procedure is a support ticket will be asked to rotate the week after a compliance finding, and that conversation goes badly.

Then there's BYOK. For encryption at rest, customer-managed keys are coherent and increasingly expected. For signing keys in an identity platform, they're mostly not: every single login would depend on a synchronous call into infrastructure the customer controls, which imports their availability and their latency into your auth path, and hands them an accidental kill switch on their own workforce. "No, and here is the reasoning, and here is what we do instead" is the right answer — per-tenant non-exportable keys, customer-initiated rotation, and audited access to the signing service. I work on a platform that made exactly this call, so weigh it accordingly; but the reasoning stands independently of who's making it, and reviewers who've thought about the failure mode tend to arrive at the same place.

How the four answers actually read

The scoring is not what most teams assume. Reviewers are pattern-matching for whether you understand your own system:

Your answer How it's read
Unqualified "Yes" to a nuanced row You haven't been asked this by anyone serious yet
"Yes" with a number and a stated limit You've operated this
"No, here's the compensating control" Credible; usually accepted
"No, shipping in Q3" Fine — and now it's a contractual date

The dangerous cell is the first, not the third. A hedged yes survives the spreadsheet and fails on the technical call, where a security engineer asks the follow-up question and discovers the gap themselves — which converts a capability gap into a trust problem, a much worse category.

And one rule that saves real pain: never answer a capability question in the present tense about a roadmap item. The spreadsheet is transcribed into a contract by someone who will never read your issue tracker, and "supported" in a signed DPA is a representation, not an aspiration. A dated "no" and an optimistic "yes" cost the same deal-wise about half the time; only one of them is a breach.

The useful reframe

Handle enough of these and the shape becomes obvious: strip the compliance vocabulary and the identity rows converge on the same six requirements, phrased six ways by six frameworks. A chokepoint you can enforce. A revocation guarantee with a number attached. Per-tenant policy. An audit stream that reconstructs decisions and can be delivered elsewhere without gaps. Tenant-scoped incident awareness. A signing key nobody at your company can extract.

Which means the questionnaire is a design document that your prospects wrote for you, for free, out of their own scar tissue. The teams that treat it as a document to be passed end up with six features that each behave slightly differently and a spreadsheet answered optimistically once a quarter. The teams that treat it as a backlog end up not needing to think about the questionnaire at all — they answer it in an afternoon, in the present tense, with numbers.