Mock a SCIM 2.0 Provider

MockServer can stand in for a SCIM 2.0 identity provider, so you can test System for Cross-domain Identity Management (SCIM) clients — user provisioning, deprovisioning, group membership sync — without a real IdP. A single control-plane call generates a fully functional provider that serves CRUD over Users and Groups plus the SCIM discovery documents, with the data held in memory.

Resources are stored and returned in SCIM shapes: every resource carries schemas, an id, and a meta object; lists are wrapped in a SCIM ListResponse envelope; errors use the SCIM Error envelope; and all responses use the application/scim+json media type.

Create a SCIM Provider

Send an empty PUT /mockserver/scim to create a provider with the default base path /scim/v2:

curl -v -X PUT "http://localhost:1080/mockserver/scim"

Or supply a configuration body to customise the base path, seed initial data, choose the id strategy, or require a bearer token:

{
    "basePath": "/scim/v2",
    "idStrategy": "UUID",
    "requireBearerToken": true,
    "expectedBearerToken": "my-test-token",
    "enforceFilter": true,
    "enforcePatch": true,
    "initialUsers": [
        { "id": "u1", "userName": "bjensen@example.com", "active": true }
    ],
    "initialGroups": [
        { "id": "g1", "displayName": "Admins", "members": [] }
    ]
}

Configuration Options

FieldDefaultDescription
basePath/scim/v2Path prefix the SCIM endpoints are served under. Must start with / and must not overlap /mockserver.
idStrategyUUIDHow server-assigned ids are generated: UUID or AUTO_INCREMENT.
initialUsers[]Users to seed the store with.
initialGroups[]Groups to seed the store with.
enforceFiltertrueWhen true, the filter query parameter is applied; when false, a filtered list returns 501 Not Implemented.
enforcePatchtrueWhen false, PATCH returns 501 Not Implemented.
requireBearerTokenfalseWhen true, resource endpoints require an Authorization: Bearer … header (discovery endpoints stay open).
expectedBearerTokennullThe exact token required; null accepts any non-empty bearer token.

Generated Endpoints

Method & PathBehaviour
GET {basePath}/UsersList users (supports ?filter, ?startIndex, ?count) — returns a ListResponse.
POST {basePath}/UsersCreate a user (userName required) — 201 with a Location header.
GET {basePath}/Users/{id}Get a user — 200 or 404 error envelope.
PUT {basePath}/Users/{id}Replace a user (preserves id and meta.created).
PATCH {basePath}/Users/{id}Apply a SCIM PatchOp.
DELETE {basePath}/Users/{id}Delete a user — 204 or 404.
The same six endpoints exist for {basePath}/Groups (displayName required on create).
GET {basePath}/ServiceProviderConfigDiscovery — advertises supported features (patch/filter reflect the config; bulk/sort/etag are false; OAuth bearer-token auth scheme).
GET {basePath}/ResourceTypesDiscovery — a ListResponse of the User and Group resource types.
GET {basePath}/SchemasDiscovery — a ListResponse of the core User and Group schema definitions.

Java Client

// default provider at /scim/v2
mockServerClient.mockScimProvider();

// or with configuration
mockServerClient.mockScimProvider(
    new ScimProviderConfiguration()
        .setBasePath("/scim/v2")
        .setRequireBearerToken(true)
        .setExpectedBearerToken("my-test-token")
);

ListResponse Envelope

{
    "schemas": [ "urn:ietf:params:scim:api:messages:2.0:ListResponse" ],
    "totalResults": 2,
    "startIndex": 1,
    "itemsPerPage": 2,
    "Resources": [ /* shaped User or Group resources */ ]
}

Error Envelope

{
    "schemas": [ "urn:ietf:params:scim:api:messages:2.0:Error" ],
    "scimType": "invalidValue",
    "detail": "userName is required",
    "status": "400"
}

Supported Filters

A single attr op "value" comparison over a top-level attribute is supported: eq (equals), co (contains), sw (starts with), and the presence operator pr. For example ?filter=userName eq "bjensen@example.com". A filter referencing an unknown attribute matches nothing. Compound expressions (and/or/not), value-paths, and the ordered operators (gt/ge/lt/le) are not yet supported.

Supported PATCH Operations

A SCIM PatchOp body (urn:ietf:params:scim:api:messages:2.0:PatchOp) with an Operations array is supported over a top-level attribute (emails) or a one-level sub-attribute (name.familyName):

  • replace with a path — set the attribute.
  • replace without a path — shallow-merge the value object.
  • add with a path — set a scalar, or append to an array attribute (e.g. emails, members).
  • add without a path — shallow-merge the value object.
  • remove with a path — delete the attribute or sub-attribute.

A malformed PatchOp returns a 400 error envelope with scimType: "invalidSyntax".