
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
scimgateway
Advanced tools
Author: Jarle Elshaug
Validated on:
With ScimGateway we could do user management by using REST based SCIM protocol, and the gateway will translate and communicate towards destinations using endpoint specific protocols.
ScimGateway is a standalone product, however this document shows how the gateway could be used by products like CA Identity Manager.
Using CA Identity Manager, we could setup one or more endpoints of type SCIM pointing to the gateway. Specific ports could then be used for each type of endpoint, and the ScimGateway would work like a "CA Connector Server" communicating with endpoints.
Instead of using IM-SDK for building our own integration for none supported endpoints, we can now build new integration based on ScimGateway plugins. ScimGateway works with IM as long as IM supports SCIM.
ScimGateway is based on the popular asynchronous event driven framework Node.js using javascripts. It is firewall friendly using REST webservices. Runs on almost all operating systems, and may loadbalance between hosts (horizontal) and cpu's (vertical). Could even be uploaded and run as a cloud application.
Following example plugins are included:
Loki (NoSQL Document-Oriented Database)
Gives a SCIM endpoint located on ScimGateway
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)
Setting {"persistence": true} gives persistence file store (no test users)
Supporting explore, create, delete, modify and list users (including groups)
Example of a fully functional ScimGateway plugin
RESTful (REST Webservice)
Demonstrates user provisioning towards a REST-Based endpoint
Using plugin "Loki" as a REST endpoint
Forwardinc (SOAP Webservice)
Demonstrates user provisioning towards SOAP-Based endpoint
Using endpoint Forwardinc that comes with CA IM SDK (SDKWS) - please see wiki.ca.com
Includes examples using signed SAML assertion for authentication or token request towards a Security Token Service
Shows how to implement a higly configurable multi tenant or multi endpoint solution using "baseEntity" parameter
MSSQL (MSSQL Database)
Demonstrates user provisioning towards MSSQL database
SAP HANA (SAP HANA Database)
Demonstrates SAP HANA specific user provisioning
Node.js is a prerequisite and have to be installed on the server.
Download the windows installer (.msi 64-bit) and install using default options.
Open a command window (run as administrator)
Create a directory for installation e.g. C:\CA\scimgateway and install in this directory
cd C:\CA\scimgateway
npm install scimgateway
Please ignore any error messages unless soap WSSecurityCert functionality is needed in your custom plugin code. Module soap installation of optional dependency 'ursa' that also includes 'node-gyp' then needs misc. prerequisites to bee manually be installed.
C:\CA\scimgateway will now be <package-root>
index.js, lib and config directories containing example plugins have been copied from the original scimgateway package located under node_modules.
If internet connection is blocked, we could install on another machine and copy the scimgateway folder.
node C:\CA\scimgateway
Start a browser
http://localhost:8880/Users?attributes=userName
Logon using gwadmin/password and two users should be listed
http://localhost:8880/Users/bjensen
Lists all user attributes for specified user
"Ctrl + c" to stop the scimgateway
For more functionality using browser (post/patch/delete) a REST extension/add-on is needed.
Not needed after a fresh install
Check if newer versions are available:
cd C:\CA\scimgateway
npm outdated
Lists current, wanted and latest version. No output on screen means we are running the latest version.
Upgrade to latest version:
cd C:\CA\scimgateway
npm update scimgateway
Note, always backup/copy C:\CA\scimgateway before update/install. Custom plugins and corresponding configuration files will not be affected.
index.js defines one or more plugins to be started. We could comment out those we do not need. Default configuration only starts the loki plugin.
var loki = require('./lib/plugin-loki');
// var restful = require('./lib/plugin-restful');
// var forwardinc = require('./lib/plugin-forwardinc');
// var mssql = require('./lib/plugin-mssql');
// var saphana = require('./lib/plugin-saphana');
Each endpoint plugin needs a javascript file (.js) and a configuration file (.json). They both must have the same naming suffix. For SAP Hana endpoint we have:
lib\plugin-saphana.js
config\plugin-saphana.json
Edit specific plugin configuration file according to your needs.
Below shows an example of config\plugin-saphana.json
{
"scimgateway": {
"scimversion": "1.1",
"loglevel": "error",
"localhostonly": false,
"port": 8884,
"username": "gwadmin",
"password": "password",
"oauth": {
"accesstoken": null
},
"certificate": {
"key": null,
"cert": null,
"ca": null,
"pfx": {
"bundle": null,
"password": null
}
}
},
"endpoint": {
"host": "hostname",
"port": 30015,
"username": "username",
"password": "password",
"saml_provider": "saml_provider_name"
}
}
Attribute explanation:
Definitions under "scimgateway" have fixed attributes but we can change the values. This section is used by the core functionality of the ScimGateway.
Definitions under "endpoint" are used by endpoint plugin for communicating with endpoint and needs to be defined according to our code.
scimversion - 1.1 or 2.0. Default is 1.1. For Azure AD 2.0 should be used.
loglevel - error or debug. Output to console and logfile logs\plugin-saphana.log
(debug not sent to console)
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 (gateway must then be installed on the CA Connector Server).
port - (**) Gateway will listen on this port number. Clients (e.g. Provisioning Server) will be using this port number for communicating with the gateway. For endpoint the port is the port number used by plugin for communicating with SAP Hana
username - username used by clients for gateway authentication. For endpoint the username refers to endpoint authentication.
password - (**) password used by clients for gateway authentication. For endpoint the password refers to endpoint authentication. Note, we set a clear text password and when gateway is started this password will become encrypted and updated in the configuration file.
oauth - For Azure AD, define access token for OAuth2 bearer token (access token). This will be the password accepted by ScimGateway. Using standard OAuth key/secret/endpoints is not supported.
certificate - If not using SSL/TLS certificate, set "key", "cert" and "ca" to null. When using SSL/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 e.g:
"certificate": {
"key": "key.pem",
"cert": "cert.pem",
"ca": null
}
Example of how to make a self signed certificate:
openssl req -nodes -newkey rsa:2048 -x509 -sha256 -days 3650 -keyout key.pem -out cert.pem -subj "/O=Testing/OU=ScimGateway/CN=<FQDN>"
<FQDN>
is Fully Qualified Domain Name of the host having ScimGateway installed
Note, when using CA Provisioning, the "certificate authority - CA" also have to 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"
}
samlprovider - SAP Hana specific saml provider name. Users created in SAP Hana needs to have a saml provider defined.
Both port number and password encryption seed may be overridden by setting environment variables before starting the gateway. Setting environment variable SEED
will override default password seed. Setting the ScimGateway port in the configuartion file to "process.env.XXX"
where XXX is the environment variable let gateway use environment variable for port configuration. This could be useful in cloud systems e.g:
"scimgateway": {
...
"port": "process.env.PORT",
...
}
Gateway can now be started from a command window running in administrative mode
3 ways to start:
node C:\CA\scimgateway
node C:\CA\scimgateway\index.js
<package-root>node .
Ctrl+c to to stop
Start Windows Task Scheduler (taskschd.msc), right click on "Task Scheduler Library" and choose "Create Task"
General tab:
-----------
Name = ScimGateway
User account = SYSTEM
Run with highest privileges
Triggers tab:
-------------
Begin the task = At startup
Actions tab:
------------
Action = Start a program
Program/script = C:\Program Files\nodejs\node.exe
Arguments = C:\CA\scimgateway
Settings - tab:
---------------
Stop the task if runs longer than = Disabled (greyed out)
Verification:
<pakage-root>\logs
Using the CA Provisioning Manager we have to configure
Endpoint type = SCIM (DYN Endpoint)
SCIM endpoint configuration example for Loki plugin (plugin-loki)
Endpoint Name = Loki
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 ScimGateway installed. Portnumber must be included. Use HTTPS instead of HTTP if ScimGateway-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/clientA
http://localhost:8880/clientB
Each baseEntity should then be defined in the plugin configuration file with custom attributes needed. Please see examples in plugin-forwardinc.
IM 12.6 SP7 (and above) also supports pagination for SCIM endpoint (data transferred in bulks - endpoint explore of users). Loki plugin supports pagination. Other plugin may ignore this setting.
Create = POST http://example.com:8880/Users
(body contains the user information)
Update = PATCH http://example.com:8880/Users/<id>
(body contains the attributes to be updated)
Search/Read = GET http://example.com:8880/Users?userName eq
"userID"&attributes=<comma separated list of scim-schema defined attributes>
Search/explore all users:
GET http://example.com:8880/Users?attributes=userName
Delete = DELETE http://example.com:8880/Users/<id>
Discovery:
GET http://example.com:8880/ServiceProviderConfigs
Specification compliance, authentication schemes, data models.
GET http://example.com:8880/Schemas
Introspect resources and attribute extensions.
Note:
Get all users (explore):
select USER_NAME from SYS.USERS where IS_SAML_ENABLED like 'TRUE';
Get a specific user:
select USER_NAME, USER_DEACTIVATED from SYS.USERS where USER_NAME like '<UserID>';
Create User:
CREATE USER <UserID> WITH IDENTITY '<UserID>' FOR SAML PROVIDER <SamlProvider>;
Delete user:
DROP USER <UserID>;
Modify user (enable user):
ALTER USER <UserID> ACTIVATE;
Modify user (disable user):
ALTER USER <UserID> DEACTIVATE;
Only SAML users will be explored and managed
Supported template attributes:
Currently no other attributes needed. Trying to update other attributes will then give an error message. The SCIM Provisioning template should therefore not include any other global user attribute references.
SAP Hana converts UserID to uppercase. Provisioning use default lowercase. Provisioning template should therefore also convert to uppercase.
User Name = %$$TOUPPER(%AC%)%
"Early Stage Code"
Plugin configuration file must include:
"scimversion": "2.0",
"oauth": {
"accesstoken": "<password>"
},
Access token password must correspond with "Secret Token" defined in Azure AD
Azure-Azure Active Directory-Enterprise Application-<My Application>-Provisioning-Secret Token
User mappings attributes between AD and SCIM also needs to be configured
Azure-Azure Active Directory-Enterprise Application-<My Application>-Provisioning-Mappings
Azure AD default SCIM attribute mapping for USER have:
externalId mapped to mailNickname (matching precedence #1)
userName mapped to userPrincipalName
ScimGateway accepts externalId (as matching precedence) instead of userName, but userName and externalId must be mapped to the same AD attribute
e.g:
externalId mapped to mailNickname (matching precedence #1)
userName mapped to mailNickname
or:
externalId mapped to userPrincipalName (matching precedence #1)
userName mapped to userPrincipalName
Azure AD default SCIM attribute mapping for GROUP have:
externalId mapped to displayName (matching precedence #1)
displayName mapped to mailNickname
ScimGateway accepts externalId (as matching precedence) instead of displayName, but displayName and externalId must then be mapped to the same AD attribute
e.g:
externalId mapped to displayName (matching precedence #1)
displayName mapped to displayName
Some notes related to Azure AD:
Azure AD do a regular check for a "none" existing user/group. This check seems to be a "keep alive" to verify connection.
Azure AD 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 i Azure AD sends a modify user {"active":"False"}
which means user should be disabled. This logic is configured in attribute mappings. Standard SCIM "DELETE" method is not used.
For javascript coding editor you may use Visual Studio Code
Preparation:
lib\plugin-loki.js
and config\plugin-loki.json
and rename both copies to your plugin name prefix e.g. plugin-mine.js and plugin-mine.json (for SOAP Webservice endpoint we might use plugin-forwardinc as a template)var mine = require('./lib/plugin-mine');
Now we are ready for custom coding by editing plugin-mine.js Coding should be done step by step and each step should be verified and tested before starting the next (they are all highlighted by comments in existing code).
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-forwardinc.js 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:
Using Connector Xpress based on the original SCIM endpoint.
Delete defaults:
Group - Associations - with User Account
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 = Name
Objects Must Exist
Use DNs in Attribute = deactivated (toggled off)
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)
Plugins should have following initialization:
// mandatory plugin initialization - start
const path = require('path');
let ScimGateway = null;
try {
ScimGateway = require('scimgateway');
} catch (err) {
ScimGateway = require('./scimgateway');
}
let scimgateway = new ScimGateway();
let pluginName = path.basename(__filename, '.js');
let configDir = path.join(__dirname, '..', 'config');
let configFile = path.join(`${configDir}`, `${pluginName}.json`);
let config = require(configFile).endpoint;
let validScimAttr = []; // empty array - all attrbutes are supported by endpoint
// mandatory plugin initialization - end
scimgateway.on('exploreUsers', function (baseEntity, startIndex, count, callback) {
var ret = {
"Resources": [],
"totalResults": null
};
...
callback(error, ret);
});
<baseurl>/client1
gives baseEntity=client1)scimgateway.on('exploreGroups', function (baseEntity, startIndex, count, callback) {
var ret = {
"Resources": [],
"totalResults": null
};
...
callback(error, ret);
});
scimgateway.on('getUser', function (baseEntity, userName, attributes, callback) {
...
callback(error, userObj);
});
Note, CA Provisioning use two types of "getUser"
scimgateway.on('createUser', function (baseEntity, userObj, callback) {
...
callback(error);
});
scimgateway.on('deleteUser', function (baseEntity, id, callback) {
...
callback(error);
});
scimgateway.on('modifyUser', function (baseEntity, id, attrObj, callback) {
...
callback(error);
});
scimgateway.on('getGroup', function (baseEntity, displayName, attributes, callback) {
...
callback(error, retObj);
});
displayName = group name
attributes = scim attributes to be returned in callback (displayName and members is mandatory)
callback(error, retObj): retObj containing group displayName and id (+ members if using default "users are member of group")
eg. using default "users are member of group":
{"displayName":"Admins","id":"Admins","members":[{"value":"bjensen","display":"bjensen"]}
eg. using "groups are member of user":
{"displayName":"Admins","id":"Admins"}
If we do not support groups, callback(null, null)
scimgateway.on('getGroupMembers', function (baseEntity, id, attributes, startIndex, count, callback) {
var ret = {
"Resources": [],
"totalResults": null
};
...
callback(error, ret);
});
Retrieve all users for a spesific group WHEN "user member of group". This setting is CA IM default scim endpoint configuration. This means Group having multivalue attribute members containing userName.
id = user id (eg. bjensen)
attributes = attributes to be returned in callback (we only return the name of groups - displayName and current user as member)
startIndex = Pagination - The 1-based index of the first result in the current set of search results
count = Pagination - Number of elements to be returned in the current set of search results
callback(error, ret):
ret.Resources = array to be filled with objects containing groups with current user as member
e.g [{"displayName":"Admins","members": [{ "value": bjensen}]}, {"displayName":"Employees", "members": [{ "value": bjensen}]}]
ret.totalResults = if supporting pagination attribute should be set to the total numbers of elements (group members) at the endpoint else set to null
If we do not support groups (or "user member of group"), callback(null, [])
scimgateway.on('getGroupUsers', function (baseEntity, groupName, attributes, callback) {
var arrRet = [];
...
callback(error, arrRet);
});
Retrieve all users for a spesific group WHEN "group member of user". This means user having multivalue attribute groups containing value GroupName
groupName = group name (eg. UserGroup-1)
attributes = scim attributes to be returned in callback
callback(error, arrRet): arrRet = array containing the userName's' eg: [{"userName", "bjensen"}, {"userName", "jsmith"}]
If we do not support groups (or "group member of user"), callback(null, [])
scimgateway.on('createGroup', function (baseEntity, groupObj, callback) {
...
return callback(error);
});
scimgateway.on('modifyGroupMembers', function (baseEntity, id, members, callback) {
...
return callback(error);
});
Installation gives error messages related to the module soap optional dependency to 'ursa' that also includes 'node-gyp'. These error messages can be ingnored unless soap WSSecurityCert functionality is needed in custom plugin code.
Importing "certificate authority - CA" on the CA Connector Server gives a "Failure" message. Restarting connector shows certificate have been installed and HTTPS communication works fine.
Using HTTPS seems to slow down the CA Provisioning - ScimGateway communication. Example: Using Provisioning Manager UI and retrieving an account takes approx. 0.5 sec with HTTP, but same operation with HTTPS takes approx. 1.5 sec. (tested both self-signed and Active Directory signed certificate).
Delete groups not supported
MIT
[ENHANCEMENT]
SEED
overrides default password seeding"process.env.XXX"
lets environment variable XXX define the port[UPGRADE]
config/plugin-xxx.json
needs to be updated:
[ENHANCEMENT]
plugin-loki
plugin-testmode
[UPGRADE]
lib/plugin-testmode.js
and config/plugin-testmode.json
[Fix]
[ENHANCEMENT]
[Fix]
[ENHANCEMENT]
[UPGRADE]
[Fix]
[ENHANCEMENT]
[ENHANCEMENT]
[UPGRADE]
scimgateway.on('createGroup',...
Please see example plugins for details.[Fix]
[ENHANCEMENT]
plugin-mssql
scimgateway.getArrayObject
[Fix]
[Fix]
[UPGRADE]
scimgateway.on('getGroupMembers',...
New arguments have been added "startIndex" and "count". Also a new return variable "ret". Please see example plugins for details.[Fix]
[ENHANCEMENT]
plugin-restful
[ENHANCEMENT]
<Base URL>/[baseEntity]
for multi tenant or multi endpoint flexibility[UPGRADE]
[Doc]
[Fix]
Initial version
FAQs
Using SCIM protocol as a gateway for user provisioning to other endpoints
The npm package scimgateway receives a total of 1,499 weekly downloads. As such, scimgateway popularity was classified as popular.
We found that scimgateway demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.