skip to content

What do /ServiceProviderConfig, /Schemas and /ResourceTypes tell a SCIM client, and what does over-advertising cost you?

level: seniorimportance: nice to knowfreq 18%

answer

  1. three read-only documents
  2. configuration, schema, endpoint mapping
  3. the client reads it and changes behaviour
  4. a promise to software, not to a person
  5. generated from code, not edited by hand

basics

~20 s

They are read-only discovery documents: which optional capabilities you support, the attributes of each resource, and which endpoint serves which schema. A client reads them once at setup and changes what it sends, so advertising a capability you have not built moves the failure to runtime, at one customer.

solid answer

~40 s

SCIM 2.0 gives a service provider three read-only discovery endpoints. `/ServiceProviderConfig` declares the optional capabilities — `patch`, `bulk`, `filter` with its maximum result size, `sort`, `etag`, `changePassword` — each as a supported flag, plus the `authenticationSchemes` you accept. `/Schemas` describes the attributes of each resource, including any extension schema you honour. `/ResourceTypes` says which endpoint serves which schema. Together they let a provisioning client configure itself against you instead of against a vendor-specific integration guide. The engineering point is honesty: a client that reads `patch` as supported stops sending the full-replacement path it would otherwise use. If your PATCH only handles a root-level `replace`, you have just moved a design gap into that one customer's nightly sync, where it surfaces as your product being broken.

code

json · 17 lines
json
{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"],
  "patch":          { "supported": true },
  "filter":         { "supported": true, "maxResults": 200 },
  "bulk":           { "supported": false, "maxOperations": 0, "maxPayloadSize": 0 },
  "sort":           { "supported": false },
  "etag":           { "supported": true },
  "changePassword": { "supported": false },
  "authenticationSchemes": [
    {
      "type": "oauthbearertoken",
      "name": "OAuth Bearer Token",
      "description": "Per-tenant bearer credential issued to one practice group.",
      "primary": true
    }
  ]
}

go deeper

for a junior

Recall that a SCIM service provider publishes three read-only documents describing what it supports, what its resources look like, and which endpoint serves which resource.

for a middle

Explain that a provisioning client reads the configuration document at setup and changes what it sends, so the supported flags are behavioural commitments rather than documentation.

for a senior

Show how you keep the document honest — generated from the implementing code, covered by a test per advertised capability — and why an over-claim surfaces as a runtime failure at one customer rather than at integration time.

for a principal

Treat the configuration document as a published interface contract: what you declare, you support for as long as customers run clients that read it, so narrowing it later is a migration and not a bug fix.

## Three documents that configure somebody else's software SCIM 2.0 defines three read-only endpoints alongside the resource collections, and they exist so that a provisioning client can discover what it is talking to rather than being told by a human: - **`/ServiceProviderConfig`** — a single document describing the optional parts of the protocol this service provider implements. - **`/Schemas`** — the attribute definitions for every resource you serve, including the standard User and Group schemas and any extension schema you accept. - **`/ResourceTypes`** — the mapping from endpoint to schema, saying that `/Users` serves the User schema and which extensions apply to it. For a radiography viewer bought by dental practice groups, these are what let a new customer's identity system connect without an engineer from your side on the call. They are also the only machine-readable statement you ever make about your own implementation. ## What the configuration document actually declares `/ServiceProviderConfig` is a list of capabilities, each carrying a supported flag and sometimes a parameter: | capability | what claiming it commits you to | |---|---| | `patch` | you accept a PatchOp document and apply `add`, `replace` and `remove`, including value paths | | `filter` | you evaluate filter expressions, up to a stated maximum result size | | `bulk` | you accept a batch of operations at `/Bulk`, including `bulkId` references between them | | `sort` | you order results by a requested attribute | | `etag` | you return a resource version and honour a conditional request against it | | `changePassword` | you accept a password change through this channel at all | Alongside them sits `authenticationSchemes`, which is where you say how the channel is authenticated. SCIM deliberately defines no authentication scheme of its own — RFC 7644 defers to HTTP's, and lists a bearer token among the options a service provider may accept — so this list is a statement of your choice, not a recital of the specification's. ## Why over-advertising is worse than under-advertising A provisioning client reads this document at connection setup and **changes its behaviour based on it**. That is the entire purpose, and it is also the hazard. Two examples make it concrete: 1. You declare `patch` supported because your endpoint accepts the verb, but your implementation only handles a pathless `replace`. A client that would otherwise have sent a full replacement now sends value-path operations. Every group membership change from that customer fails, at 2 a.m., with an error only their administrator sees. 2. You declare `etag` supported but return no version on the resource body. A client that begins sending conditional requests gets refusals it cannot resolve, because it has nothing valid to send. In both cases the gap existed before the document; what the document did was **move the failure from integration day to production, and from your engineers to one customer's administrator**. Declaring a capability unsupported is a narrower product — some clients will not integrate, and you will hear about it during evaluation, which is exactly when you want to hear about it. The converse discipline matters too. Leaving `filter` unsupported when you do implement an equality subset costs you integrations for no reason, because a client that believes it cannot search has no way to recover from a create conflict. Declare what is true, and make the maximum result size part of that truth. ## Practical rules for keeping them honest - **Generate the documents from the code that implements the capability**, not from a static file somebody edited during the first integration. A static file drifts the moment a feature is removed. - **Test the document against the behaviour.** A test that reads your own `/ServiceProviderConfig` and asserts that each supported capability has a passing behavioural test is cheap and catches the drift that matters. - **Decide whether these three sit behind the same credential as the resource endpoints.** They describe your implementation rather than your customers' people, so the argument is about fingerprinting your service rather than about personal data — but it is a decision to make deliberately rather than by default. - **Version them with the feature, not with the customer.** These documents are the same for every practice group; a per-customer variation is a sign that a divergence has leaked out of its normalisation layer and into your published contract. ## The interview point The question separates candidates who have read the specification from candidates who have run an integration. The first group can list the three endpoints. The second group knows that the configuration document is a **promise made to software you cannot argue with**, and that the cost of breaking it is paid by one customer at a time, in the dark, by someone who will describe it as your product not working.

  • Why does a SCIM service provider declare authenticationSchemes at all, rather than the specification fixing one?
    Because SCIM defines no authentication scheme of its own. RFC 7644 defers to HTTP's, listing a bearer token among the options a service provider may accept, so what protects the channel is genuinely your choice. The document is how that choice becomes discoverable instead of living in an integration guide, and it is where a client learns which credential to present before it sends its first write.
  • How do you stop the configuration document from drifting away from what the code does?
    Generate it from the same objects that implement the capabilities rather than serving a hand-edited file, and add a test that reads your own document and asserts a behavioural test exists and passes for each capability marked supported. The drift that hurts is not a new capability going unannounced — it is a removed one still being advertised months later.
  • Should /ServiceProviderConfig require the same credential as /Users?
    It is a deliberate decision rather than a default. The document describes your implementation, not any customer's people, so the exposure argument is about fingerprinting your service rather than about personal data. Many providers serve it openly to make integration easier; if you do, make sure nothing customer-specific has leaked into it, because it is the same document for every tenant.

It is the allergen card in a restaurant window. A narrow card costs you some diners at the door; a generous one that is not true costs you one diner, at the table, in a way nobody in the kitchen sees happen.

saying these in an interview costs you the question

  • Advertises patch as supported while only handling a pathless replace
  • Serves a hand-edited configuration file that nobody regenerates
  • Declares filter unsupported although an equality subset exists
  • Thinks the discovery documents are for humans reading integration docs
  • Varies the configuration document per customer to paper over a divergence