scimgateway
v5.1.8
Published
Using SCIM protocol as a gateway for user provisioning to other endpoints
Downloads
6,857
Maintainers
Readme
SCIM Gateway
Author: Jarle Elshaug
Validated through IdP's:
- Symantec/Broadcom Identity Manager
- Microsoft Entra ID
- One Identity Manager/OneLogin
- Okta
- Omada
- SailPoint/IdentityNow
Latest news:
- By configuring the chainingBaseUrl, it is now possible to chain multiple gateways in sequence, such as
gateway1->gateway2->gateway3->endpoint
. In this setup, gateway beave much like a reverse proxy, validating authorization at each step unless PassThrough mode is enabled. Chaining is also supported in stream subscriber mode - Email, onError and sendMail() supports more secure RESTful OAuth for Microsoft Exchange Online (ExO) and Google Workspace Gmail, alongside traditional SMTP Auth for all mail systems. HelperRest supports a wide range of common authentication methods, including basicAuth, bearerAuth, tokenAuth, oauth, oauthSamlBearer, oauthJwtBearer and Auth PassTrough
- Major version v5.0.0 marks a shift to native TypeScript support and prioritizes Bun over Node.js. This upgrade requires some modifications to existing plugins.
- BREAKING: SCIM Stream is the modern way of user provisioning letting clients subscribe to messages instead of traditional IGA top-down provisioning. SCIM Gateway now offers enhanced functionality with support for message subscription and automated provisioning using SCIM Stream
- Authentication PassThrough letting plugin pass authentication directly to endpoint for avoid maintaining secrets at the gateway. E.g., using Entra ID application OAuth
- Supports OAuth Client Credentials authentication
- Major version v4.0.0 getUsers() and getGroups() replacing some deprecated methods. No limitations on filtering/sorting. Admin user access can be linked to specific baseEntities. New MongoDB plugin
- ipAllowList for restricting access to allowlisted IP addresses or subnets e.g. Azure IP-range
- General LDAP plugin configured for Active Directory
- PlugSSO using SCIM Gateway
- Each authentication configuration allowing more than one admin user including option for readOnly
- Codebase moved from callback of h... to the the promise(d) land of async/await
- Supports configuration by environments and external files
- Health monitoring through "/ping" URL, and option for error notifications by email
- Entra ID user provisioning including license management e.g. Office 365, installed and configured within minutes!
- Includes API Gateway for none SCIM/provisioning - becomes what you want it to become
- Running SCIM Gateway as a Docker container
Overview
SCIM Gateway facilitates user management using the standardized REST-based SCIM 1.1 or 2.0 protocol, offering easier, more powerful, and consistent provisioning while avoiding vendor lock-in. Acting as a translator for incoming SCIM requests, the gateway seamlessly enables CRUD functionality (create, read, update, and delete) for users and groups. By implementing endpoint-specific protocols, it ensures precise and efficient provisioning across diverse destinations. With the gateway, your diverse destinations effectively become SCIM endpoints, streamlining integration and simplifying user management.
SCIM Gateway is based on popular asynchronous event driven framework Bun or Node.js using TypeScript/JavaScript. It is cloud and firewall friendly. Runs on almost all operating systems, and may load balance between hosts (horizontal) and cpu's (vertical).
Following example plugins are included:
Loki (NoSQL Document-Oriented Database)
SCIM Gateway becomes a standalone SCIM endpoint
Demonstrates user provisioning towards document-oriented database
Using LokiJS for a fast, in-memory document-oriented database (much like MongoDB/PouchDB)
Default gives two predefined test users loaded using in-memory only (no persistence)
Configuration{"persistence": true}
gives persistence file store (no test users)
Example of a fully functional SCIM Gateway pluginMongoDB (NoSQL Document-Oriented Database)
Same as plugin "Loki", but using external MongoDB
Shows how to implement a highly configurable multi tenant or multi endpoint solution throughbaseEntity
in URLSCIM (REST Webservice)
Demonstrates user provisioning towards REST-Based endpoint (type SCIM)
Using plugin Loki as SCIM endpoint through HelperRest
Can be used as SCIM version-gateway e.g. 1.1=>2.0 or 2.0=>1.1Soap (SOAP Webservice)
Demonstrates user provisioning towards SOAP-Based endpoint
Example WSDLs are included
Using endpoint "Forwardinc" as an example (comes with Symantec/Broadcom/CA IM SDK - SDKWS)
Shows how to implement a highly configurable multi tenant or multi endpoint solution throughbaseEntity
in URLMSSQL (MSSQL Database)
Demonstrates user provisioning towards MSSQL databaseSAP HANA (SAP HANA Database)
Demonstrates SAP HANA specific user provisioningEntra ID (REST Webservices)
Entra ID user provisioning including license management (App Service plans) e.g. Office 365
Using Microsoft Graph API through HelperRest
Using customized SCIM attributes according to Microsoft Graph API
Includes Symantec/Broadcom ConnectorXpress metafile for creating provisioning "Azure - ScimGateway" endpoint typeLDAP (Directory)
Fully functional LDAP plugin
Pre-configured for Microsoft Active Directory
Using endpointMapper (like plugin-entra-id) for attribute mapping flexibilityAPI (REST Webservices)
Demonstrates API Gateway/plugin functionality using post/put/patch/get/delete combined with HelperRest
None SCIM plugin, becomes what you want it to become.
Methods included can also be used in standard SCIM plugins
Endpoint complexity could be put in this plugin, and client could instead communicate through Gateway using your own simplified REST specification.
One example of usage could be creation of tickets in ServiceDesk and also the other way, closing a ticket could automatically approve/reject corresponding workflow in IdP.
Installation
Install Bun
Bun is a prerequisite and must be installed on the server.
Note, Bun installs by default in the current user’s HOMEPATH\.bun
. To install it elsewhere, set BUN_INSTALL=<install-path>
as a global or system environment variable before installing. The installation will add Bun to the current user’s path, but consider adding it to the global or system path for easier access across all users.
Install SCIM Gateway
Open a command window (run as administrator)
Create your own package directory e.g. c:\my-scimgateway and install SCIM Gateway within this package.
mkdir c:\my-scimgateway
cd c:\my-scimgateway
bun init -y
bun install scimgateway
bun pm trust scimgateway
c:\my-scimgateway will now be <package-root>
index.ts, lib and config directories containing example plugins have been copied to your package from the original scimgateway package located under node_modules. Bun requires bun pm trust scimgateway
for allowing postinstall copying these files.
If internet connection is blocked, we could install on another machine and copy the <package-root>
folder.
Startup and verify default Loki plugin
bun c:\my-scimgateway
Start a browser (note, Edge do not pop-up logon dialog box when using http)
http://localhost:8880/ping
=> Health check with a "hello" response
http://localhost:8880/Users
http://localhost:8880/Groups
=> Logon using gwadmin/password and two users and groups should be listed
http://localhost:8880/Users/bjensen
http://localhost:8880/Groups/Admins
or
http://localhost:8880/Users?filter=userName eq "bjensen"
http://localhost:8880/Groups?filter=displayName eq "Admins"
=> Lists all attributes for specified user/group
http://localhost:8880/Groups?filter=displayName eq "Admins"&excludedAttributes=members
http://localhost:8880/Groups?filter=members.value eq "bjensen"&attributes=id,displayName,members.value
http://localhost:8880/Users?filter=userName eq "bjensen"&attributes=userName,id,name.givenName
http://localhost:8880/Users?filter=meta.created ge "2010-01-01T00:00:00Z"&attributes=userName,name.familyName,meta.created
http://localhost:8880/Users?filter=emails.value co "@example.com"&attributes=userName,name.familyName,emails&sortBy=name.familyName&sortOrder=descending
=> Filtering and attribute examples
"Ctrl + c" to stop the SCIM Gateway
Tip, take a look at bun test scripts located in
node_modules\scimgateway\test\lib
If using Node.js instead of Bun, scimgateway must be downloaded from github because Node.js does not support native typescript used by modules. Startup will then be:
node --experimental-strip-types c:\my-scimgateway\index.ts
Upgrade SCIM Gateway
Not needed after a fresh install
The best and easiest way to upgrade is renaming existing scimgateway package folder, create a new one and do a fresh installation. After the installation we copy index.ts, config and lib folder
(customized plugins) from previous installation to the new installation. You should also read the version history to see if custom plugins needs to be updated.
Alternatives are:
Upgrade to latest minor version:
cd c:\my-scimgateway
bun install scimgateway
Note, always backup/copy c:\my-scimgateway before upgrading. Custom plugins and corresponding configuration files will not be affected.
To force a major upgrade (version x.*.* => y.*.*) that will brake compability with any existing custom plugins, we have to include the @latest
suffix in the install command: bun install scimgateway@latest
Avoid (re-)adding the files created during postinstall
For production we do not need example plugins to be incuded by the postinstall
job
Bun will by default exlude any postinstall
jobs unless we have trusted the scimgateway package using the bun pm trust scimgateway
that updates package.json { trustedDependencies: ["scimgateway"] }
For Node.js (and also Bun), we might set the property scimgateway_postinstall_skip = true
in .npmrc
or setting environment SCIMGATEWAY_POSTINSTALL_SKIP = true
Configuration
index.ts defines one or more plugins to be started by the const plugins
setting.
// example starting all default plugins:
// const plugins = ['loki', 'scim', 'entra-id', 'ldap', 'mssql', 'api', 'mongodb', 'saphana', 'soap']
const plugins = ['loki']
for (const plugin of plugins) {
try {
await import(`./lib/plugin-${plugin}.ts`)
} catch (err: any) {
console.error(err)
}
}
Each endpoint plugin needs a TypeScript file (.ts) and a configuration file (.json).
They both must have the same naming prefix. For SAP Hana endpoint we have:
lib\plugin-saphana.ts
config\plugin-saphana.json
Edit specific plugin configuration file according to your needs.
Below shows an example of config\plugin-saphana.json
{
"scimgateway": {
"port": 8884,
"localhostonly": false,
"chainingBaseUrl": null,
"scim": {
"version": "2.0",
"skipTypeConvert" : false,
"skipMetaLocation" false,
"groupMemberOfUser": false
"usePutSoftSync" : false
},
"log": {
"loglevel": {
"file": "debug",
"console": "error"
},
"customMasking": []
},
"auth": {
"basic": [
{
"username": "gwadmin",
"password": "password",
"readOnly": false,
"baseEntities": []
}
],
"bearerToken": [
{
"token": null,
"readOnly": false,
"baseEntities": []
}
],
"bearerJwtAzure": [
{
"tenantIdGUID": null,
"readOnly": false,
"baseEntities": []
}
],
"bearerJwt": [
{
"secret": null,
"publicKey": null,
"options": {
"issuer": null
},
"readOnly": false,
"baseEntities": []
}
],
"bearerOAuth": [
{
"clientId": null,
"clientSecret": null,
"readOnly": false,
"baseEntities": []
}
],
"passThrough": {
"enabled": false,
"readOnly": false,
"baseEntities": []
}
},
"certificate": {
"key": null,
"cert": null,
"ca": null,
"pfx": {
"bundle": null,
"password": null
}
},
"ipAllowList": [],
"email": {
"auth": {
"type": "oauth",
"options": {
"tenantIdGUID": null,
"clientId": null,
"clientSecret": null
}
},
"emailOnError": {
"enabled": false,
"from": null,
"to": null
}
},
"stream": {
"baseUrls": [],
"certificate": {
"ca": null
},
"subscriber": {
"enabled": false,
"entity": {
"undefined": {
"nats": {
"tenant": null,
"subject": null,
"jwt": null,
"secret": null
},
"deleteUserOnLastGroupRoleRemoval": false,
"convertRolesToGroups": false,
"generateUserPassword": false,
"modifyOnly": false,
"replaceDomains": []
}
}
},
"publisher": {
"enabled": false,
"entity": {
"undefined": {
"nats": {
"tenant": null,
"subject": null,
"jwt": null,
"secret": null
}
}
}
}
}
},
"endpoint": {
"host": "hostname",
"port": 30015,
"username": "username",
"password": "password",
"saml_provider": "saml_provider_name"
}
}
Configuration file have two main JSON objects: scimgateway
and endpoint
Definitions in scimgateway
object have fixed attributes, but values can be modified. Sections not used/configured can be removed. This object is used by the core functionality of the SCIM Gateway.
Definitions in endpoint
object are customized according to our plugin code. Plugin typically need this information for communicating with endpoint
port - Gateway will listen on this port number. Clients (e.g. Provisioning Server) will be using this port number for communicating with the gateway
localhostonly - true or false. False means gateway accepts incoming requests from all clients. True means traffic from only localhost (127.0.0.1) is accepted.
chainingBaseUrl - baseUrl for chaining anohter gateway, syntax:
http(s)://host:port
. If defined, gateway beave much like a reverse proxy, validating authorization unless PassThrough mode is enabled. SeeConfiguration notes
for detailsidleTimeout - default 120, sets the the number of seconds to wait before timing out a connection due to inactivity
scim.version - "1.1" or "2.0". Default is "2.0".
scim.skipTypeConvert - true or false, default false. Multivalue attributes supporting types e.g. emails, phoneNumbers, ims, photos, addresses, entitlements and x509Certificates (but not roles, groups and members) will be become "type converted objects" when sent to modifyUser and createUser. This for simplicity of checking attributes included and also for the endpointMapper method (used by plugin-ldap and plugin-entra-id), e.g.:
"emails": { "work": {"value": "[email protected]", "type": "work"}, "home": {"value": "", "type": "home", "operation": "delete"}, "undefined": {"value": "[email protected]"} } skipTypeConvert set to true gives attribute "as-is": array, allow duplicate types including blank, but values to be deleted have been marked with "operation": "delete" "emails": [ {"value": "[email protected]", "type": "work"}, {"value": "john.smith.org", "type": "home", "operation": "delete"}, {"value": "[email protected]"} ]
scim.skipMetaLocation - true or false, default false. If set to true,
meta.location
which contains protocol and hostname from request-url, will be excluded from response e.g."{...,meta":{"location":"https://my-company.com/<...>"}}
. If using reverse proxy and not including headersX-Forwarded-Proto
andX-Forwarded-Host
, originator will be the proxy and we might not want to expose internal protocol and hostname being used by the proxy request.scim.groupMemberOfUser - true or false, default false. If body contains groups and groupMemberOfUser=true, groups attribute will remain at user object (groups are member of user) instead of default user member of groups that will use modifyGroup method for maintaining group members.
scim.usePutSoftSync - true or false, default false.
PUT /Users/bjensen
will replace the user bjensen with body content. If set totrue
, only PUT body content will be replaced. Any additional existing user attributes and groups supported by plugin will remain as-is.log.loglevel.file - off, error, info, or debug. Output to plugin-logfile e.g.
logs\plugin-saphana.log
log.loglevel.console - off, error, info, or debug. Output to stdout and errors to stderr.
log.customMasking - array of attributes to be masked e.g.
"customMasking": ["SSN", "weight"]
. By default SCIM Gateway includes masking of some standard attributes like password.auth - Contains one or more authentication/authorization methods used by clients for accessing gateway - may also include:
- auth.xx.readOnly - true/false, true gives read only access - only allowing
GET
requests for corresponding admin user - auth.xx.baseEntities - array containing one or more
baseEntity
allowed for this user e.g. ["client-a"] - empty array allowing all.
Methods are disabled by setting corresponding admin user to null or remove methods not used
- auth.xx.readOnly - true/false, true gives read only access - only allowing
auth.basic - Array of one ore more basic authentication objects - Basic Authentication with username/password. Note, we set a clear text password that will become encrypted when gateway is started.
auth.bearerToken - Array of one or more bearer token objects - Shared token/secret (supported by Entra ID). Clear text value will become encrypted when gateway is started.
auth.bearerJwtAzure - Array of one or more JWT used by Azure SyncFabric. tenantIdGUID must be set to Entra ID Tenant ID.
auth.bearerJwt - Array of one or more standard JWT objects. Using secret or publicKey for signature verification. publicKey should be set to the filename of public key or certificate pem-file located in
<package-root>\config\certs
or absolute path being used. Clear text secret will become encrypted when gateway is started. options.issuer is mandatory. Other options may also be included according to jsonwebtoken npm package definition.auth.bearerOAuth - Array of one or more Client Credentials OAuth configuration objects.
clientId
andclientSecret
are mandatory. clientSecret value will become encrypted when gateway is started. OAuth token request url is /oauth/token e.g.http://localhost:8880/oauth/token
auth.passThrough - Setting auth.passThrough.enabled=true will bypass SCIM Gateway authentication. Gateway will instead pass ctx containing authentication header to the plugin. Plugin could then use this information for endpoint authentication and we don't have any password/token stored at the gateway. Note, this also requires plugin binary having
scimgateway.authPassThroughAllowed = true
and endpoint logic for handling/passing ctx.request.header.authorizationcertificate - If not using TLS certificate, set "key", "cert" and "ca" to null. When using TLS, "key" and "cert" have to be defined with the filename corresponding to the primary-key and public-certificate. Both files must be located in the
<package-root>\config\certs
directory unless absolute path being defined e.g:"certificate": { "key": "key.pem", "cert": "cert.pem", "ca": "ca.pem" // if several: "ca": ["ca1.pem", "ca2.pem"] }
Example of how to make a self signed certificate:
openssl.exe req -nodes -newkey rsa:2048 -x509 -sha256 -days 3650 -keyout key.pem -out cert.pem -subj "/O=My Company/OU=Application/CN=SCIM Gateway" -addext "subjectAltName=DNS:localhost,DNS:127.0.0.1,DNS:*.mycompany.com" -addext "extendedKeyUsage=serverAuth" -addext "keyUsage=digitalSignature"
Note, when using Symantec/Broadcom Provisioning, the "certificate authority - CA" also must be imported on the Connector Server. For self-signed certificate, CA and the certificate (public key) is the same.
PFX / PKCS#12 bundle can be used instead of key/cert/ca e.g:
"pfx": { "bundle": "certbundle.pfx", "password": "password" }
Note, we should normally use certificate (https) for communicating with SCIM Gateway unless we install gateway locally on the manager (e.g. on the provisioning Connector Server). When installed on the manager, we could use
http://localhost:port
orhttp://127.0.0.1:port
which will not be passed down to the data link layer for transmission. We could then also set {"localhostonly": true}ipAllowList - Array of one or more IPv4/IPv6 subnets (CIDR) allowed for incoming traffic. E.g. using Entra ID as IdP, we would like to restrict access to IP addresses used by Azure. Azure IP-range can be downloaded from: https://azureipranges.azurewebsites.net, enter AzureActiveDirectory in the search list and select JSON download. Copy the "addressPrefixes" array content and paste into ipAllowList array. CIDR single IP-host syntax is a.b.c.d/32. Note, front-end HTTP proxy or a load balancer must include client IP-address in the X-Forwarded-For header. Configuration example:
"ipAllowList": [ "13.64.151.161/32", "13.66.141.64/27", ... "2603:1056:2000::/48", "2603:1057:2::/48" ]
email - Sending email from plugin or automated error notifications emailOnError. For emailOnError only the first error will be sent until sendInterval have passed. Supporting both SMTP Auth and modern REST OAuth. For OAuth, currently Microsoft Exchange Online (ExO) and Google Workspace Gmail are supported - see configuration notes
email.auth - Authentication configuration
email.auth.type -
oauth
orsmtp
email.auth.options - Authentication options - note, different options for type oauth and smtp
email.auth.options.tenantIdGUID (oauth/ExO) - Entra tenant id or domain name
email.auth.options.clientId (oauth/ExO) - Entra OAuth application Client ID
email.auth.options.clientSecret (oauth/ExO) - Entra OAuth application Client Secret
email.auth.options.serviceAccountKeyFile (oauth/Gmail) - Google Service Account key json-file name located in the
package-root>\config\certs
directory unless absolute path being definedemail.auth.options.host (smtp) - Mailserver e.g. "smtp.gmail.com" - mandatory for smtp
email.auth.options.port (smtp) - Port used by mailserver e.g. 587, 25 or 465 - mandatory for smtp
email.auth.options.username (smtp) - Mail account for authentication normally same as sender of the email, e.g. "[email protected]"
email.auth.options.password (smtp) - Mail account password
email.proxy - Proxy configuration if using mailproxy
email.proxy.host - Proxy host e.g.
http://proxy-host:1234
email.proxy.username - username if authentication is required
email.proxy.password - password if authentication is required
email.emailOnError - Contains configuration for sending error notifications by email. Note, only the first error will be sent until sendInterval have passed
email.emailOnError.enabled - true or false, value set to true will enable email notifications
email.emailOnError.sendInterval - Default 15. Mail notifications on error are deferred until sendInterval minutes have passed since the last notification.
email.emailOnError.from - Sender email addresses e.g: "[email protected]". Mandatory for oauth. For smtp email.auth.options.username will be used
email.emailOnError.to - Comma separated list of recipients email addresses e.g: "[email protected]"
email.emailOnError.cc - Optional comma separated list of cc mail addresses
email.emailOnError.subject - Optional mail subject, default
SCIM Gateway error message
stream - See SCIM Stream for configuration details
endpoint - Contains endpoint specific configuration according to customized plugin code.
Configuration notes - general
Custom Schemas, ServiceProviderConfig and ResourceType can be used if
./lib/scimdef-v2.json or scimdef-v1.json
exists. Original scimdef-v2.json/scimdef-v1.json can be copied from node_modules/scimgateway/lib to your plugin/lib and customized.Using reverse proxy and we want ipAllowList and correct meta.location response, following headers must be set by proxy:
X-Forwarded-For
,X-Forwarded-Proto
andX-Forwarded-Host
Setting environment variable
SEED
with some random characters will override default password seeding logic. This also allow copying configuration file with encrypted secrets from one machine to another.All configuration can be set based on environment variables. Syntax will then be
"process.env.<ENVIRONMENT>"
where<ENVIRONMENT>
is the environment variable used. E.g. scimgateway.port could have value "process.env.PORT", then using environment variable PORT.All configuration values can be moved to a single external file having JSON dot notation content with plugin name as parent JSON object. Syntax in original configuration file used by the gateway will then be
"process.file.<path>"
where<path>
is the file used. E.g. key endpoint.password could have value "process.file./var/run/vault/secrets.json"All configuration values can be moved to multiple external files, each file containing one single value. Syntax in original configuration file used by the gateway will then be
"process.text.<path>"
where<path>
is the file which contains raw (UTF-8
) character value. E.g. key endpoint.password could have value "process.text./var/run/vault/endpoint.password".Example:
{ "scimgateway": { ... "port": "process.env.PORT", ... "loglevel": { "file": "process.env.LOG_LEVEL_FILE", ... "auth": { "basic": [ { "username": "process.file./var/run/vault/secrets.json", "password": "process.file./var/run/vault/secrets.json" }, ... ], "bearerJwt": [ "secret": "process.text./var/run/vault/jwt.secret", "publicKey": "process.text./var/run/vault/jwt.pub", ... ], ... }, "endpoint": { ... "username": "process.file./var/run/vault/secrets.json", "password": "process.file./var/run/vault/secrets.json", ... } }
jwt.secret file content example:
thisIsSecret
secrets.json file content example for plugin-soap:
{ "plugin-soap.scimgateway.auth.basic[0].username": "gwadmin", "plugin-soap.scimgateway.auth.basic[0].password": "password", "plugin-soap.endpoint.username": "superuser", "plugin-soap.endpoint.password": "secret" }
Configuration notes - Email, using Microsoft Exchange Online (ExO)
Entra ID application must have application permissions
Mail.Send
To prevent the sending of emails from any defined mailboxes, an ExO
ApplicationAccessPolicy
must be defined through PowerShell.First create a mail-enabled security-group that only includes those users (mailboxes) the application is allowed to send from
Note,mail enabled security group
cannot be created from portal, only from admin or admin.exchange console##Connect to Exchange Install-Module -Name ExchangeOnlineManagement Connect-ExchangeOnline ##Create ApplicationAccessPolicy New-ApplicationAccessPolicy -AppId <AppClientID> -PolicyScopeGroupId <MailEnabledSecurityGrpId> -AccessRight RestrictAccess -Description "Restrict app to specific mailboxes"
Configuration notes - Email, using Google Workspace Gmail
https://console.cloud.google.com
- IAM & Admin > Service Accounts > Create Service Account
- Name=email-sender
- Create and Continue
- Grant this service account access to project - not needed
- Grant users access to this service - not needed
- IAM & Admin > Service Accounts > "email-sender" account > Keys
- Add Key > Create new key > JSON
- download json Service Account Key file, refere to configuration
email.auth.options.serviceAccountKeyFile
- IAM & Admin > Service Accounts > Create Service Account
https://admin.google.com
- Security > Access and data control > API controls
- Manage Domain Wide Delegation > Add new
- Client ID = id of service account created
- OAuth scope =
https://www.googleapis.com/auth/gmail.send
- Security > Access and data control > API controls
https://admin.google.com
- Billing > Subscriptions - verify Google Workspace license
- Directory > Users > "user"
- Licenses > Edit > enable Google Workspace license
email.emailOnError.from
mail address must have Google Workspace license
Configuration notes - Gateway chainging and chainingBaseUrl
By configuring the chainingBaseUrl
, it is possible to chain multiple gateways in sequence, such as gateway1->gateway2->gateway3->endpoint
. In this setup, gateway behave much like a reverse proxy, validating authorization at each step unless PassThrough mode is enabled. Chaining is also supported in stream subscriber mode
{
"scimgateway": {
...
"chainingBaseUrl": "https:\\gateway2:8880",
...
"auth": {
...
"passThrough": {
"enabled": false,
"readOnly": false,
"baseEntities": []
}
...
}
},
...
}
Using above configuration example on gateway1, incoming requests will be routed to https:\\gateway2:8880
The plugin and its associated authentication configuration can mirror the setup running on the final gateway. However, in chaining mode, the plugin binary is used solely for initializing and configuring the gateway. This allows for the use of a simplified plugin-<name>.ts
binary containing only the essential mandatory components:
// start - mandatory plugin initialization
const ScimGateway: typeof import('scimgateway').ScimGateway = await (async () => {
try {
return (await import('scimgateway')).ScimGateway
} catch (err) {
const source = './scimgateway.ts'
return (await import(source)).ScimGateway
}
})()
const scimgateway = new ScimGateway()
const config = scimgateway.getConfig()
scimgateway.authPassThroughAllowed = false
// end - mandatory plugin initialization
Using scimgateway.authPassThroughAllowed = true
and plugin-<name>.json
configuration scimgateway.auth.passThrough=true
enables Authentication PassTrhough
Configuration notes - HelperRest used by plugins
For REST endpoints, plugins may use HelperRest to simplify authentication and communication
doRequest() executes REST request and return responsedoRequest(<baseEntity>, <method>, <path>, <body>, <ctx>, <options>)
- baseEntity - 'undefined' if not used and must correspond with endpoint configuration that defines baseUrls and connection options.
- method - GET, PATCH, PUT, DELETE
- path - either full url or just the path that will be added to baseUrl. Using full url will override baseUrl. Using path is preferred because of auth caching logic and simplicity
- body - optional body to be used
- ctx - optional, passing authorization header if Auth PassThrough is enabled
- opt - optional, connection options that will extend/override any endpoint.entity.undefined.connection definitions
Configuration showing connection settings:
{
"scimgateway": {
...
}
"endpoint": {
"entity": {
"undefined": {
"connection": {
"baseUrls": [],
"auth": {
"type": "xxx",
"options": {
...
"jwtPayload": {},
"samlPayload": {},
"tls": {} // files located in ./config/certs
}
},
"options": {
"headers": {},
"tls": {} // files located in ./config/certs
},
"proxy": {}
}
}
}
}
}
- baseUrls - Endpoint URL. Several may be defined for failower. There are retry logic on connection failures
- auth.type - defines authentication being used:
basic
,oauth
,token
,bearer
,oauthSamlBearer
oroauthJwtBearer
- auth.options - for each valid type there are different options. tenantIdGUID is special for Entra ID and serviceAccountKeyFile is special for Google. Using these will simplify and reduce options to be included. Also note we do not need to include baseUrls when using tenantIdGUID/serviceAccountKeyFile as long as endpoint is Entra ID (Microsoft Graph) or Google.
Example using basic auth:
"connection": {
"baseUrls": [
"https://localhost:8880"
],
"auth": {
"type": "basic",
"options": {
"username": "gwadmin",
"password": "password"
}
},
"options": {
"tls": {
"rejectUnauthorized": false,
"ca": "ca.pem"
}
}
}
Example Entra ID (plugin-entra-id) using clientId/clientSecret:
"connection": {
"baseUrls": [],
"auth": {
"type": "oauth",
"options": {
"tenantIdGUID": "<tenantId>",
"clientId": "<clientId",
"clientSecret": "<clientSecret>"
}
}
}
Example Entra ID (plugin-entra-id) using certificate secret:
"connection": {
"baseUrls": [],
"auth": {
"type": "oauth",
"options": {
"tenantIdGUID": "<tenantId>",
"clientId": "<clientId",
"tls": {
"key": "key.pem",
"cert": "cert.pem"
}
}
}
}
Example using general OAuth:
"connection": {
"baseUrls": [<"endpointUrl">],
"auth": {
"type": "oauth",
"options": {
"tokenUrl": "<tokenUrl>"
"clientId": "<clientId",
"clientSecret": "<clientSecret>"
}
}
}
Please see code editor method HelperRest doRequest() IntelliSense for type and option details
Manual startup
Gateway can be started from a command window running in administrative mode
3 ways to start:
bun c:\my-scimgateway
bun c:\my-scimgateway\index.ts
<package-root>bun .
Ctrl+c to stop
Automatic startup - Windows Task Scheduler
Start Windows Task Scheduler (taskschd.msc), right click on "Task Scheduler Library" and choose "Create Task"
General tab:
-----------
Name = SCIM Gateway
User account = SYSTEM
Run with highest privileges
Triggers tab:
-------------
Begin the task = At startup
Actions tab:
------------
Action = Start a program
Program/script = <install path>\bun.exe
Arguments = c:\my-scimgateway
Settings - tab:
---------------
Stop the task if runs longer than = Disabled (greyed out)
Verification:
- Right click task - Run, verify process node.exe (SCIM Gateway) can be found in the task manager (not the same as task scheduler). Also verify logfiles
<pakage-root>\logs
- Right click task - End, verify process node.exe have been terminated and disappeared from task manager
- Reboot server and verify SCIM Gateway have been automatically started
Running as a isolated virtual Docker container
On Linux systems we may also run SCIM Gateway as a Docker image (using docker-compose)
- Docker Pre-requisites:
docker-ce
docker-compose
Install SCIM Gateway within your own package and copy provided docker files:
mkdir /opt/my-scimgateway cd /opt/my-scimgateway bun init -y bun install scimgateway bun pm trust scimgateway cp ./config/docker/* .
docker-compose.yml <== Here is where you would set the exposed port and environment
Dockerfile <== Main dockerfile
DataDockerfile <== Handles volume mapping
docker-compose-debug.yml <== Debugging
docker-compose-mssql.yml <== Example including MSSQL docker imageCreate a scimgateway user on your Linux VM.
adduser scimgateway
Create a directory on your VM host for the scimgateway configs:
mkdir /home/scimgateway/config
Copy your updated configuration file e.g. /opt/my-scimgateway/config/plugin-loki.json to /home/scimgateway/config. Use scp to perform the copy.
NOTE: /home/scimgateway/config is where all important configuration and loki datastore will reside outside of the running docker container. If you upgrade scimgateway you won't lose your configurations and data.
Build docker images and start it up
docker-compose up --build -d
NOTE: Add the -d flag to run the command above detached.
Be sure to confirm that port 8880 is available with a simple http request
If using default plugin-loki and we have configured
{"persistence": true}
, we could confirm scimgateway created loki.db:su scimgateway cd /home/scimgateway/config ls loki.db
To list running containers information:docker ps
To list available images:docker images
To view the logs:docker logs scimgateway
To execute command within your running container:docker exec scimgateway <bash command>
To stop scimgateway:docker-compose stop
To restart scimgateway:docker-compose start
To debug running container (using Visual Studio Code):docker-compose -f docker-compose.yml -f docker-compose-debug.yml up -d
Start Visual Studio Code and follow these debugging instructions
To upgrade scimgateway docker image (remove the old stuff before running docker-compose up --build):
docker rm scimgateway
docker rm $(docker ps -a -q); docker rmi $(docker images -q -f "dangling=true")
Entra ID as IdP using SCIM Gateway
Entra ID could do automatic user provisioning by synchronizing users towards SCIM Gateway, and gateway plugins will update endpoints.
Plugin configuration file must include SCIM Version "2.0" (scimgateway.scim.version) and either Bearer Token (scimgateway.auth.bearerToken[x].token) or Entra ID Tenant ID GUID (scimgateway.auth.bearerJwtAzure[x].tenantIdGUID) or both:
scimgateway: {
"scim": {
"version": "2.0",
...
},
...
"auth": {
"bearerToken": [
{
"token": "shared-secret"
}
],
"bearerJwtAzure": [
{
"tenantIdGUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
]
}
...
}
token
configuration must correspond with "Secret Token" defined in Entra IDtenantIdGUID
configuration must correspond with Entra ID Tenant ID
In Azure Portal:
Azure-Microsoft Entra ID-Enterprise Application-<My Application>-Provisioning-Secret Token
Note, when "Secret Token" is left blank, Azure will use JWT (tenantIdGUID)
Azure-Microsoft Entra ID-Overview-Tenant ID
User mappings attributes between AD and SCIM also needs to be configured
Azure-Microsoft Entra ID-Enterprise Application-<My Application>-Provisioning-Edit attribute mappings-Mappings
Entra ID default SCIM attribute mapping for USER must have:
userPrincipalName mapped to userName (matching precedence #1)
Entra ID default SCIM attribute mapping for GROUP must have:
displayName mapped to displayName (matching precedence #1)
members mapped to members
Some notes related to Entra ID:
Entra ID SCIM documentation
For using OAuth/JWT credentials, Entra ID configuration "Secret Token" (bearer token) should be blank. Plugin configuration must then include bearerJwtAzure.tenantIdGUID. Click "Test Connection" in Azure to verify
Entra ID do a regular check for a "non" existing user/group. This check seems to be a "keep alive" to verify connection.
Entra ID first checks if user/group exists, if not exist they will be created (no explore of all users like CA Identity Manager)
Deleting a user in Entra ID sends a modify user
{"active":"False"}
which means user should be disabled. This logic is default set in attribute mappings expression ruleSwitch([IsSoftDeleted], , "False", "True", "True", "False")
. Standard SCIM "DELETE" method seems not to be used.
Symantec Identity Manager as IdP using SCIM Gateway
Using Symantec/Broadcom Identity Manger, plugin configuration must use SCIM Version "1.1" (scimgateway.scim.version).
In the Provisioning Manager we could use Endpoint type = SCIM (DYN Endpoint)
or create our own custom endpoint type based on this one
SCIM endpoint configuration example for Loki plugin (plugin-loki)
Endpoint Name = Loki-8880
User Name = gwadmin
Password = password
SCIM Authentication Method = HTTP Basic Authentication
SCIM Based URL = http://localhost:8880
or:
SCIM Based URL = http://localhost:8880/<baseEntity>
Username, password and port must correspond with plugin configuration file. For "Loki" plugin it will be config\plugin-loki.json
"SCIM Based URL" refer to the FQDN (or localhost) having SCIM Gateway installed. Portnumber must be included. Use HTTPS instead of HTTP if SCIM Gateway configuration includes certificates.
"baseEntity" is optional. This is a parameter used for multi tenant or multi endpoint solutions. We could create several endpoints having same base url with unique baseEntity. e.g:
http://localhost:8880/client-a
http://localhost:8880/client-b
Each baseEntity should then be defined in the plugin configuration file with custom attributes needed. Please see examples in plugin-soap.json
Entra ID provisioning
Using plugin-entra-id we could do user provisioning towards Entra ID
For testing purposes we could get an Azure free account
Entra ID configuration
- Logon to Azure as global administrator
- Microsoft Entra ID - App registrations
- Click "New registration"
- Name = SCIM Gateway Inbound
- Select: Accounts in this organizational directory only
- Click "Register"
- Overview:
- Copy "Application (client) ID"
- Copy "Directory (tentant) ID"
- Certificates & secrets:
- Click "New client secret"
- Description = SCIM Gateway Inbound secret#1
- Select an appropriate "Expires"
- Click "Add"
- Copy "Value" of the new secret that was created
- API permissions: - Add a permission - Microsoft Graph - Application permissions
- Optionally remove any defaults included e.g. User.Read
- Click "Add a permission"
- Microsoft Graph
- Application permissions
- Directory - Directory.ReadWriteAll
- Organization - Organization.ReadWrite.All
- Click "Add permissions"
- API permissions: - Grant Admin consent
Or we could go to Enterprise application to grant these consents:- Microsoft Entra ID - Enterprise applications - SCIM Gateway Inbound
- Permissions:
- Click "Grant admin consent for [tenant name]"
- In the logon dialog, logon as global administrator
- In permissions request dialog, click "Accept"
- Click "Refresh", directory and organization permissions are now listed and OK
- Permissions:
- Microsoft Entra ID - Enterprise applications - SCIM Gateway Inbound
Seems Application needs to be member of "User administrator" for having privileges to manage office/mobile phone on users that is member of any administrator roles
Also note, enable/disable user (accountEnabled - through Graph API) will fail if user have an "Administrator" role other than above mentioned "User Administrator" e.g. "Group Administrator"/"Application Administrator". To be sure we can enable/disable all users, application needs to be member of "Global administrator" - 62e90394-69f5-4237-9190-012177145e10.
- Microsoft Entra ID - Manage - Roles and administrators
- Search: User administrator
- Click on role User administrator
- Click "Add assignments"
- Click "No member selected" to add members
- Search: SCIM Gateway Inbound (name of the application we have created)
- Select the application name that shows up and click "Add"
- Click Next
- Assignment type=Active and enable "Permanent assigned", add some justification text and click "Assign"
SCIM Gateway configuration
Edit index.ts
Set plugin to be started to entra-id
const plugins = ['entra-id']
Edit plugin-entra-id.json
Note, for Symantec/Broadcom Provisioning we must use SCIM version 1.1
scimgateway: {
"scim": {
"version": "1.1"
},
username
and password
used to connect the SCIM Gateway must be defined.
"auth": {
"basic": [
{
"username": "gwadmin",
"password": "password",
"readOnly": false,
"baseEntities": []
}
],
Update tenantIdGUID
, clientID
and clientSecret
according to what you copied from the previous Entra ID configuration.
If using proxy, set proxy.host to "http://<FQDN-ProxyHost>:<port>"
e.g "http://proxy.mycompany.com:3128"
"endpoint": {
"entity": {
"undefined": {
"connection": {
"baseUrls": [
"not in use for Entra ID when tenantIdGUID is defined"
],
"auth": {
"type": "oauth",
"options": {
"tokenUrl": "oauth token_url - not in use when tenantIdGUID is defined",
"tenantIdGUID": "Entra ID Tenant ID (GUID) or Primary domain name - only used by plugin-entra-id",
"clientId": "oauth client_id - Entra ID: Application ID",
"clientSecret": "oauth client_secret - Entra ID: generated application secret value"
}
},
"proxy": {
"host": null,
"username": null,
"password": null
}
}
}
},
"map": {
...
}
}
Note, clientSecret and any proxy.password will become encrypted in this file on the first Azure connection.
For multi-tenant or multi-endpoint support, we may add several entities:
"endpoint": {
"entity": {
"undefined": {
...
},
"client-a": {
...
},
"client-b": {
...
}
}
}
For additional details, see baseEntity description.
Note, we should normally use certificate (https) for communicating with SCIM Gateway unless we install gateway locally on the manager (e.g. on the CA Connector Server). When installed on the manager, we could use http://localhost:port
or http://127.0.0.1:port
which will not be passed down to the data link layer for transmission. We could then also set {"localhostonly": true}
Using Symantec/Broadcom Provisioning
Create a new endpoint type "Azure - ScimGateway"
- Start SCIM Gateway
- Using plugin-entra-id:
const plugins = ['entra-id']
inindex.ts
- username, password and port defined in
plugin-entra-id.json
must also be known
- Using plugin-entra-id:
- Start ConnectorXpress
- Setup Data Sources
- Add
- Layer7 (this is SCIM)
- Name = SCIM Gateway-8881
- Base URL = http://localhost:8881 (SCIM Gateway installed locally on Connector Server)
- Add the new "Azure - ScimGateway" endpoint type
- Metadata - Import - "my-scimgateway\node_modules\scimgateway\config\resources\Azure - ScimGateway.xml"
- Select the datasource we created - SCIM Gateway-8881
- Enter password for the user defined in datasource (e.g. gwadmin/password)
- On the right - expand Provisioning Servers - your server - and logon
- Right Click "Endpoint Types", Create New Endpoint Type
- You may use default name "Azure - ScimGateway" and click "OK" to create endpoint
Note, metafile "Azure - ScimGateway.xml" is based on CA "Azure - WSL7" with some minor adjustments like using Microsoft Graph API attributes instead of Azure AD Graph attributes.
Provisioning Manager configuration
Endpoint type = Azure - ScimGateway (DYN Endpoint)
Endpoint configuration example:
Endpoint Name = AzureAD-8881
User Name = gwadmin
Password = password
SCIM Authentication Method = HTTP Basic Authentication
SCIM Based URL = http://localhost:8881
or
SCIM Based URL = http://localhost:8881/<baseEntity>
For details, please see section "CA Identity Manager as IdP using SCIM Gateway"
SCIM Gateway REST API
Create = POST http://localhost:8880/Users
(body contains the user information)
Update = PATCH http://localhost:8880/Users/<id>
(body contains the attributes to be updated)
Search/Read = GET http://localhost:8880/Users?userName eq
"userID"&attributes=<comma separated list of scim-schema defined attributes>
Search/explore all users:
GET http://localhost:8880/Users?attributes=userName
Delete = DELETE http://localhost:8880/Users/<id>
Discovery:
GET http://localhost:8880/ServiceProviderConfigs
Specification compliance, authentication schemes, data models.
GET http://localhost:8880/Schemas
Introspect resources and attribute extensions.
Note:
- userName (mandatory) = UserID
- id (mandatory) = Unique id. Could be set to the same as UserID but don't have to.
API Gateway
SCIM Gateway also works as an API Gateway when using url /api
or /<baseEntity>/api
Following methods for the none SCIM based api-plugin are supported:
GET /api
GET /api?queries
GET /api/{id}
POST /api + body
PUT /api/{id} + body
PATCH /api/{id} + body
DELETE /api/{id}
These methods can also be used in standard SCIM plugins
Please see example plugin: plugin-api.ts
How to build your own plugins
For JavaScript coding editor you may use Visual Studio Code
Preparation:
- Copy "best matching" example plugin e.g.
lib\plugin-mssql.ts
andconfig\plugin-mssql.json
and rename both copies to your plugin name prefix e.g. plugin-mine.ts and plugin-mine.json - Edit plugin-mine.json and define a unique port number for the gateway setting
- Edit index.ts and include your plugin in the startup e.g.
const plugins = ['mine']');
- Start SCIM Gateway and verify using using your own SCIM API requests or your IdP/IGA system.
Now we are ready for custom coding by editing plugin-mine.ts Coding should be done step by step and each step should be verified and tested before starting the next
- Turn off group functionality - getGroups to return empty response (gateway automatically use getGroups for some of the methods if groups not included)
Please see plugin-saphana that do not use groups. - getUsers (test provisioning retrieve all accounts and single account)
- createUser (test provisioning new account)
- deleteUser (test provisioning delete account)
- modifyUser (test provisioning modify account)
- Turn on group functionality - getGroups having logic for returning groups if groups are supported
- getGroups (test provisioning retrieve groups)
- modifyGroup (test provisioning modify group members)
- createGroup (test provisioning new group)
- deleteGroup (test provisioning delete account)
Template used by CA Provisioning role should only include endpoint supported attributes defined in our plugin. Template should therefore have no links to global user for none supported attributes (e.g. remove %UT% from "Job Title" if our endpoint/code do not support title)
CA Provisioning using default SCIM endpoint do not support SCIM Enterprise User Schema Extension (having attributes like employeeNumber, costCenter, organization, division, department and manager). If we need these or other attributes not found in CA Provisioning, we could define our own by using the free-text "type" definition in the multivalue entitlements or roles attribute. In the template entitlements definition, we could for example define type=Company and set value to %UCOMP%. Please see plugin-soap.ts using Company as a multivalue "type" definition.
Using CA Connector Xpress we could create a new SCIM endpoint type based on the original SCIM. We could then add/remove attributes and change from default assign "user to groups" to assign "groups to user". There are also other predefined endpoints based on the original SCIM. You may take a look at "ServiceNow - WSL7" and "Zendesk - WSL7".
For project setup:
- Datasource = Layer7 (CA API) - this is SCIM
- Layer7 Base URL = SCIM Gateway url and port (SCIM Base URL)
- Authentication = Basic Authentication
(connect using gwadmin/password defined in plugin config-file)
How to change "user member of groups" to "group member of users"
Using Connector Xpress based on the original SCIM endpoint.
Delete defaults:
Group - Associations - with User Account
Group - Attributes - members
User Account - Attributes - Group Membership
Create new attribute:
User Account - Attributes: Groups - Flexi DN - Multivalue - groups
Create User - Group associations:
User Account - Accociations - Direct association with = Group
User Account - Accociations - with Group
Note, "Include a Reverse Association" - not needed if we don't need Group object functionality e.g list/add/remove group members
User Attribute = Physical Attribute = Groups
Match Group = By Attribute = ID
Objects Must Exist
Use DNs in Attribute = activated (toggled on)
Include a Reverse Association (if needed)
Group Attribute = Virtual Attribute = User Membership
Match User Account = By Attribute = User Name
Note, groups should be capability attribute (updated when account is synchronized with template):
advanced options - Synchronized = enabled (toggled on)
Methods
Plugins should have following initialization:
// start - mandatory plugin initialization
const ScimGateway: typeof import('scimgateway').ScimGateway = await (async () => {
try {
return (await import('scimgateway')).ScimGateway
} catch (err) {
const source = './scimgateway.ts'
return (await import(source)).ScimGateway
}
})()
const scimgateway = new ScimGateway()
const config = scimgateway.getConfig()
scimgateway.authPassThroughAllowed = false
// end - mandatory plugin initialization
If using REST, we could also include the HelperRest:
// start - mandatory plugin initialization
...
const HelperRest: typeof import('scimgateway').HelperRest = await (async () => {
try {
return (await import('scimgateway')).HelperRest
} catch (err) {
const source = './scimgateway.ts'
return (await import(source)).HelperRest
}
})()
...
// end - mandatory plugin initialization
Plugins should include following SCIM Gateway methods:
- scimgateway.getUsers()
- scimgateway.createUser()
- scimgateway.deleteUser()
- scimgateway.modifyUser()
- scimgateway.getGroups()
- scimgateway.createGroup()
- scimgateway.deleteGroup()
- scimgateway.modifyGroup()
In addition following general API methods are available for use:
- scimgateway.postApi()
- scimgateway.putApi()
- scimgateway.patchApi()
- scimgateway.getApi()
- scimgateway.deleteApi()
In code editor (e.g., Visual Studio Code), method details and documentation are shown by IntelliSense
License
MIT © Jarle Elshaug
Change log
v5.1.8
[Fixed]
- plugin-ldap, dn that includes double underscore
__
not correctly handled
v5.1.7
[Fixed]
- Using gateway certificate CA, the CA did not load correctly. It now also supports an array of multiple CAs.
[Improved]
- Dependencies bump
v5.1.6
[Improved]
- HelperRest, payload/claims configuration now defined in auth.options.jwtPayload and auth.options.samlPayload. Previously all was defiend in auth.options
- README configuration notes updated
v5.1.5
[Improved]
- 404 NOT_FOUND is now logged as a warning instead of error
v5.1.4
[Fixed]
- Postinstall failed using the new Bun v1.2.0
v5.1.3
[Fixed]
HelperRest, auth.type=
oauthJwtBearer
and auth.options=tenantIdGUID
Configuration example using Entra ID application having uploaded cert.pem as certificate secret:
"endpoint": { "entity": { "undefined": { "connection": { "baseUrls": [], "auth": { "type": "oauthJwtBearer", "options": { "tenantIdGUID": "Entra ID Tenant ID (GUID)", "clientId": "<application clientId>", "tls": { // files located in ./config/certs "key": "key.pem", "cert": "cert.pem" } } } } } } }
Please see code editor method HelperRest doRequest() IntelliSense for details
Note, this fix may break
plugin-entra-id
if baseUrls configuration not empty. If baseUrl not empty, it will be used. If empty, baseUrl will automatically be set according to graph api when using tenantIdGUID definition
v5.1.2
[Improved]
- Simplified some initialization logic
v5.1.1
[Fixed]
- SCIM Gateway failed to start on linux using Bun >= v1.1.43
v5.1.0
[Improved]
By configuring the
chainingBaseUrl
, it is now possible to chain multiple gateways in sequence, such asgateway1->gateway2->gateway3->endpoint
. In this setup, gateway beave much like a reverse proxy, validating authorization at each step unless PassThrough mode is enabled. Chaining is also supported in stream subscriber modePlease see
Configuration notes
for details
v5.0.15
[Improved]
- HelperRest, auth.type=oauthSamlAssertion and auth.type=oauthJwtAssertion have been updated to
oauthSamlBearer
andoauthJwtBearer
for consistency
v5.0.14
[Improved]
- email now supports Google Workspace Gmail using REST OAuth
- email workaround for ExO national characters introduced in v5.0.7 not needed anymore - ExO/GraphApi seems to have been fixed
- some minor cosmetics on email message layout formatting when using plain text message
- HelperRest now includes authentication type
oauthJwtAssertion
v5.0.13
[Improved]
- scim-stream, using the new reorganized nats.js v3 client library
- cosmetics,
use strict
not needed and removed because ES modules are always strict mode
v5.0.12
[Fixed]
- HelperRest doRequest() incorrect Auth PassThrough handling
[Improved]
- Dependencies bump
v5.0.11
[Fixed]
- OAuth token response on error missing error_description in v5
- HelperRest doRequest() now also includes retry logic on invalid token that has not expired - will renew token
v5.0.10
[Improved]
- OAuth token request now accept missing or invalid Content-Type header
v5.0.9
[Improved]
- HelperRest doRequest() now support configuration auth type
oauthSamlAssertion
for OAuth SAML token assertion. Please see code editor method IntelliSense for details
v5.0.8
[Fixed]
- Ensure Bun compatibility with Azure Reverse Proxy for large and long running response
- HelperRest was not compatible with Node.js
- plugin-mssql, some error handling should not throw an error
- Configuration files updated according to the v5 configuration syntax of
scimgateway.auth.bearerOAuth
-clientId/clientSecret
now replacing deprecatedclient_id/client_secret
v5.0.7
[Improved]
- plugin-mssql all methods now implemented, also includes docker and dbinit configuration, thanks to @Peter Havekes and @mrvanes
[Fixed]
- mail sending option introduced in v5.0.6 did not fully support national special charcters when using Microsoft Exchange Online and html formatted email
v5.0.6
[Improved]
- new configuration option:
scimgateway.idleTimeout
default 120, sets the the number of seconds to wait before timing out a connection due to inactivity - deprecated configuration option:
scimgateway.payloadSize
Bun using default maxRequestBodySize 128MB - new configuration option:
scimgateway.email
replacing legacyscimgateway.emailOnError
(legacy still supported). Email now support oauth authentication
old configuration:
{
"scimgateway": {
...
"emailOnError": {
"smtp": {
"enabled": false,
"host": null,
"port": 587,
"proxy": null,
"authenticate": true,
"username": null,
"password": null,
"sendInterval": 15,
"to": null,
"cc": null
}
},
...
},
...
}
new configuration:
Using Microsoft Exchange Online and oauth authencation which also is default and recommended by Microsoft. For other mail servers and options like SMTP AUTH (basic/oauth), please see configuration description. Plugin may also send mail using method scimgateway.sendMail()
{
"scimgateway": {
...
"email": {
"auth": {
"type": "oauth",
"options": {
"tenantIdGUID": null,
"clientId": null,
"clientSecret": null
}
},
"emailOnError": {
"enabled": false,
"from": null,
"to": null
}
},
...
},
...
}
Configuration notes when using oauth and tenantIdGUID - Microsoft Exchange Online (ExO):
Entra ID application must have application permissions
Mail.Send
To prevent the sending of emails from any defined mailboxes, an ExO
ApplicationAccessPolicy
must be defined through PowerShell.First create a mail-enabled security-group that only includes those users (mailboxes) the application is allowed to send from
Note,mail enabled security group
cannot be created from portal, only from admin or admin.exchange console##Connect to Exchange Install-Module -Name ExchangeOnlineManagement Connect-ExchangeOnline ##Create ApplicationAccessPolicy New-ApplicationAccessPolicy -AppId <AppClientID> -PolicyScopeGroupId <MailEnabledSecurityGrpId> -AccessRight RestrictAccess -Description "Restrict app to specific mailboxes"
v5.0.5
[Fixed]
- plugin-ldap, dn special character not correct for ascii code 128(dec)/80(hex)
v5.0.4
[Improved]
- minor type definition cosmetics
v5.0.3
[Fixed]
- unauthorized connection when using configuration bearerJwtAzure
[Improved]
- minor type definition cosmetics
v5.0.2
[Improved]
- minor cosmetics readme updates
v5.0.1
[Fixed]
- postinstall did not update index.ts when default bun index.ts did exist
v5.0.0
[MAJOR]
Major version v5.0.0 marks a shift to