Skip to content

ExScim/ex_scim

Repository files navigation

ExScim

ExScim Project

SCIM 2.0 implementation in Elixir.
Based on the official specifications:

The system is modular and adapter-based, so storage, mapping, authentication, and validation can be customized.


Quickstart

Add the dependencies you need to mix.exs:

{:ex_scim, path: "ex_scim"}
{:ex_scim_ecto, path: "ex_scim_ecto"}       # optional: Ecto storage
{:ex_scim_phoenix, path: "ex_scim_phoenix"} # optional: Phoenix endpoints
{:ex_scim_client, path: "ex_scim_client"}   # optional: HTTP client

Run the example provider app to see a working SCIM setup:

cd examples/provider
mix ecto.setup
mix phx.server

Endpoints will be available under /scim/v2.


Architecture Overview

ExScim is split into four packages:

ex_scim/          # Core SCIM logic and operations
ex_scim_ecto/     # Database persistence via Ecto
ex_scim_phoenix/  # HTTP endpoints and Phoenix integration
ex_scim_client/   # HTTP client for consuming SCIM APIs

Core Design


Package Details

ex_scim – Core Library

  • Operations for Users, Groups, and Bulk
  • Unified storage interface
  • SCIM filter/path parsers
  • Resource handling (IDs, metadata)
  • Schema validation and repository (RFC 7643 §7)
  • RFC 7644-compliant error responses (RFC 7644 §3.12)
  • Default user/group mappers

ex_scim_ecto – Database Integration

  • Ecto StorageAdapter implementation
  • Converts SCIM filters to Ecto queries
  • Works with PostgreSQL, MySQL, SQLite, etc.

ex_scim_phoenix – HTTP API

  • Controllers for Users, Groups, Me, Search, Bulk, Discovery
  • Complete SCIM 2.0 router (RFC 7644 §3)
  • Plugs for auth, content-type handling, logging
  • HTTP error ↔ SCIM error mapping

ex_scim_client – HTTP Client

  • HTTP client for consuming SCIM APIs
  • User and Group resource operations
  • Filtering, sorting, pagination support
  • Bulk operations and schema discovery
  • Request builder with authentication

Configuration Example

config :ex_scim,
  base_url: "https://your-domain.com",

  # Storage
  storage_strategy: ExScimEcto.StorageAdapter,
  storage_repo: MyApp.Repo,
  user_model: MyApp.Accounts.User,
  group_model: MyApp.Accounts.Group,

  # Resource mapping
  user_resource_mapper: MyApp.Scim.UserMapper,
  group_resource_mapper: MyApp.Scim.GroupMapper,

  # Authentication
  auth_provider_adapter: MyApp.Scim.AuthProvider,

  # Schema validation
  scim_validator: ExScim.Schema.Validator.DefaultValidator,
  scim_schema_repository: ExScim.Schema.Repository.DefaultRepository,

  # Bulk operations
  bulk_supported: true,
  bulk_max_operations: 1000,
  bulk_max_payload_size: 1_048_576

Phoenix Integration

Add SCIM routes to your Phoenix application:

defmodule MyAppWeb.Router do
  use Phoenix.Router

  pipeline :scim_api do
    plug :accepts, ["json", "scim+json"]
    plug ExScimPhoenix.Plug.ScimContentType
    plug ExScimPhoenix.Plug.ScimAuth
  end

  scope "/scim/v2" do
    pipe_through :scim_api
    use ExScimPhoenix.Router
  end
end

Custom Adapters

Storage Adapter

defmodule MyApp.CustomStorage do
  @behaviour ExScim.Storage.Adapter

  def get_user(id), do: # your implementation
  def create_user(user_data), do: # your implementation
  # ... other callbacks
end

Resource Mapper

defmodule MyApp.UserMapper do
  @behaviour ExScim.Users.Mapper.Adapter

  def from_scim(scim_data) do
    %MyApp.User{
      username: scim_data["userName"],
      email: get_primary_email(scim_data["emails"])
    }
  end

  def to_scim(%MyApp.User{} = user, _opts) do
    %{
      "schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
      "id" => user.id,
      "userName" => user.username,
      "emails" => format_emails(user.email)
    }
  end
end

Example Provider

The examples/provider app shows a complete SCIM setup:

  • Phoenix router with SCIM routes
  • Domain ↔ SCIM mappers
  • Ecto schema for User
  • SQLite database
  • Custom auth provider (demo)
  • User and Group support

Run it locally:

cd examples/provider
mix deps.get
mix ecto.setup
mix phx.server

Development

Each package can be tested independently:

cd ex_scim && mix test
cd ex_scim_ecto && mix test
cd ex_scim_phoenix && mix test
cd ex_scim_client && mix test

Provider example:

cd examples/provider
mix ecto.setup
mix phx.server

SCIM 2.0 Support

Features

Endpoints


Design Choices

  • Modular: use only the packages you need (core, ecto, phoenix)
  • Extensible: adapters for storage, mapping, auth, validation
  • Separated concerns: persistence, HTTP, business logic
  • RFC compliance: responses and errors follow spec

See the examples/provider app for a full reference implementation.