SCIM logging
The log file that a USoft SCIM server writes, its structure, and how to use it as an audit trail of SCIM activity. For configuring the server itself, see How to set up USoft as a SCIM server.
Log file location
When a SCIM server starts, it creates a log file named SCIM-<portnr>.log, where <portnr> is the Server Portnumber configured for it. This file is separate from the general Rules Service log, but is written to the same location: the usoft_logs folder set up for the Rules Service. See Log files and temporary files for how that central logging location is organised and configured.
The Logging row on the Rules Service gives access to the Rules Service's own logfile. Clicking the logfile link opens the Rules Service logfile. It is not the same file as SCIM-<portnr>.log, which records the SCIM server's request traffic once it is started.
Log format
Every line follows the same pattern:
<timestamp> [<thread>] <LEVEL> [<component>] - <message>
| Part | Description |
|---|---|
timestamp | ISO 8601, with a comma before the milliseconds, e.g. 2026-08-13T15:55:29,159. |
thread | The thread that produced the line. main during startup; grizzly-http-server-<n> while handling requests. |
LEVEL | INFO, WARN or ERROR. See Log levels used. |
component | The internal component that logged the line, for example RequestInfoFilter, ScimEngine or ResponseInfoFilter. |
message | Free-form text specific to the component. For ScimEngine, this is a SQL statement or a map of named parameters. For the *InfoFilter components, it is a tab-separated list of key:value pairs. |
The file is plain text, and an entry is not always a single physical line: a ScimEngine SQL Query message reproduces the statement as the USoft platform formats it internally, indented across several lines. Only the first line of an entry carries the <timestamp> [<thread>] <LEVEL> [<component>] - prefix; the lines that follow, up to the next line that starts with a timestamp, belong to that same entry. A tool scanning the file for individual entries must account for this rather than assume one line per entry.
Startup entries
When the SCIM server starts, it logs the certificate lookup (if HTTPS is configured), the base URI it is listening on, and the resources it advertises:
2026-08-13T15:53:18,094 [main] INFO [Main] - Starting server 'SCIM'
2026-08-13T15:53:18,160 [main] INFO [UServiceConfig] - SQL Query: SELECT APP_NAME, HOST_NAME, CERTIFICATE, PASSWORD, CERT_TYPE, VALID_FROM, VALID_UNTIL FROM T_AUTH_CERT WHERE APP_NAME = :applicationName AND HTTPS_USE = 'Y' AND FRIENDLY_NAME=:certName
2026-08-13T15:53:18,161 [main] INFO [UServiceConfig] - Parameters: {applicationName: MYAPP, certName: USoft}
2026-08-13T15:53:18,181 [main] INFO [UServiceConfig] - Base URI: https://0.0.0.0:40506
2026-08-13T15:53:18,194 [main] INFO [DynamicService] - No active service classes found
2026-08-13T15:53:18,244 [main] INFO [AppResourceConfig] - Advertising: HealthCheckResource
2026-08-13T15:53:18,259 [main] INFO [AppResourceConfig] - Advertising: ScimResource
2026-08-13T15:53:18,263 [main] WARN [Server] - keystoreKeyAlias not specified, reverting to .* (i.e. the first key)
2026-08-13T15:53:18,288 [main] INFO [Server] - using key: te-cf7039c6-119c-4231-99f6-90a422670399 from MIITEgIBAzCCEs4GCSqGSIb3DQEHAaCCEr8EghK7MIIStzCCCpsGCSqGSIb3DQEHAaCCCowEggqIMIIKhDCCCoAGCyqGSIb3D... matched by: .*
2026-08-13T15:53:19,345 [main] INFO [Server] - Server request throttling not enabled.
2026-08-13T15:53:19,468 [main] INFO [NetworkListener] - Started listener bound to [0.0.0.0:40506]
2026-08-13T15:53:19,470 [main] INFO [HttpServer] - [HttpServer] Started.
When the SCIM server is configured for HTTPS, the [Server] - using key: line includes a fragment of the certificate's key material. Protect the SCIM-<portnr>.log file with the same care as the certificate itself.
Per-request entries
Every SCIM request produces one block of log lines, opened by RequestInfoFilter and closed by ResponseInfoFilter. In between, the components appear in this order:
| Order | Component | Logged |
|---|---|---|
| 1 | RequestInfoFilter | The incoming HTTP request, before it is handled: server-ip, method, uri, query, server-port, client-ip, client-user-agent, client-referer. |
| 2 | SessionManager | The result of authenticating the request: session-id, session-name, session-protocol, authenticated, user-name. Logged once after authentication and again just before the response. |
| 3 | ScimResource | The method and full URL, with the request body for POST, PUT and PATCH. On success, a confirmation message and the resulting resource as JSON follow later in the block. |
| 4 | ScimEngine | One SQL Query / Named Parameters pair per database statement the request causes, in execution order — SELECT statements first, then any INSERT, UPDATE or DELETE. |
| 5 | ScimException | Present only when the request fails: Error: [<HTTP status>] <status text>: <detail>. |
| 6 | ResponseInfoFilter | The HTTP response: status-code, client-ip, method, uri, content-media-type, time-taken (in milliseconds). A status-string field is added when the response is not a success. |
The user-name reported by SessionManager is the account that authenticated the SCIM connection — the Authorizer User configured for the SCIM server (or the identity behind the bearer token). It identifies which SCIM client connection made the request, not which individual end user or process on the identity provider's side triggered it.
Log levels used
RequestInfoFilter, SessionManager, ScimResource and ScimEngine log at INFO. ResponseInfoFilter logs at INFO for a successful response and at WARN for an error response. ScimException logs at ERROR.
Examples
A successful request
A SCIM client adds a user to a group with PATCH /Groups/{id}:
2026-08-13T15:55:29,142 [grizzly-http-server-0] INFO [RequestInfoFilter] - server-ip:10.0.0.5 method:PATCH uri:/scim/v2/Groups/ad86835a4c084bd4b959e3d3ed4afc11 query:- server-port:40506 client-ip:10.0.0.5 client-user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 client-referer:https://localhost:40506/scim/v2/Groups/ad86835a4c084bd4b959e3d3ed4afc11
2026-08-13T15:55:29,150 [grizzly-http-server-0] INFO [SessionManager] - Session identified: session-id=7466b5a0-c9d7-4d05-a45b-80d061abc47d session-name=auth session-protocol=USOFT authenticated=yes user-name=MYAPP
2026-08-13T15:55:29,159 [grizzly-http-server-0] INFO [ScimResource] - PATCH https://localhost:40506/scim/v2/Groups/ad86835a4c084bd4b959e3d3ed4afc11: {"Operations":[{"path":"members","value":"3836971057594f369d03ec34151a5552","op":"add"}],"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"]}
2026-08-13T15:55:29,179 [grizzly-http-server-0] INFO [ScimEngine] - SQL Query: SELECT
SCHEMA_DEF AS "schema_def"
, NAME AS "name"
, USFormat.DateToChar(CHANGED_ON, 'YYYY-MM-DDTHH24:MI:SS') AS "changed_on"
, USFormat.DateToChar(CREATED_ON, 'YYYY-MM-DDTHH24:MI:SS') AS "created_on"
FROM
T_AUTH_SCHEMA
WHERE
PROTOCOL_TYPE = 'SCIM'
AND
CONTEXT = :context
2026-08-13T15:55:29,182 [grizzly-http-server-0] INFO [ScimEngine] - Named Parameters: {context=R}
2026-08-13T15:55:29,193 [grizzly-http-server-0] INFO [ScimEngine] - SQL Query: SELECT
ROLE_GUID AS "id"
, EXTERNAL_ID AS "externalId"
, ROLE_NAME AS "displayName"
, DESCRIPTION AS "description"
, 'Group' AS "metaResourceType"
FROM
T_AUTH_ROLE
WHERE
DELETED = 'N'
AND
EXTERNAL_ID IS NOT NULL
AND
APP_NAME = :app_name
AND
(ROLE_GUID = :group_guid OR ROLE_NAME = UPPER(:displayName))
2026-08-13T15:55:29,194 [grizzly-http-server-0] INFO [ScimEngine] - Named Parameters: {app_name=MYAPP, group_guid=ad86835a4c084bd4b959e3d3ed4afc11, displayName=null}
... (further SELECT statements resolve the group's members and extension properties) ...
2026-08-13T15:55:29,235 [grizzly-http-server-0] INFO [ScimEngine] - SQL Query: UPDATE T_AUTH_ROLE
SET
EXTERNAL_ID = :externalId
WHERE
DELETED = 'N'
AND
EXTERNAL_ID IS NOT NULL
AND
:externalId IS NOT NULL
AND
APP_NAME = :app_name
AND
ROLE_GUID = :id
2026-08-13T15:55:29,235 [grizzly-http-server-0] INFO [ScimEngine] - Named Parameters: {app_name=MYAPP, externalId=0, id=ad86835a4c084bd4b959e3d3ed4afc11}
2026-08-13T15:55:29,244 [grizzly-http-server-0] INFO [ScimEngine] - SQL Query: INSERT INTO T_AUTH_ROLE_USER (
APP_NAME
, ROLE_NAME
, USERNAME
, DEFAULT_ROLE
)
SELECT
r.APP_NAME
, r.ROLE_NAME
, u.USERNAME
, :default_role
FROM
T_AUTH_ROLE r
, T_AUTH_USER u
WHERE
r.DELETED = 'N'
AND
r.EXTERNAL_ID IS NOT NULL
AND
r.APP_NAME = :app_name
AND
(r.ROLE_GUID = :role_guid OR r.ROLE_NAME = :role_name)
AND
u.USER_GUID = :user_guid
AND
u.EXTERNAL_ID IS NOT NULL
2026-08-13T15:55:29,244 [grizzly-http-server-0] INFO [ScimEngine] - Named Parameters: {role_name=null, app_name=MYAPP, role_guid=ad86835a4c084bd4b959e3d3ed4afc11, default_role=N, user_guid=3836971057594f369d03ec34151a5552}
2026-08-13T15:55:29,351 [grizzly-http-server-0] INFO [ScimResource] - Group with id 'ad86835a4c084bd4b959e3d3ed4afc11' has been updated
2026-08-13T15:55:29,352 [grizzly-http-server-0] INFO [ScimResource] - Group details: {"id":"ad86835a4c084bd4b959e3d3ed4afc11","externalId":"0","displayName":"ROLE2","members":[{"value":"3836971057594f369d03ec34151a5552"}],"schemas":["urn:ietf:params:scim:schemas:core:2.0:Group"],"meta":{"resourceType":"Group","location":"https://localhost:40506/scim/v2/Groups/ad86835a4c084bd4b959e3d3ed4afc11"}}
2026-08-13T15:55:29,369 [grizzly-http-server-0] INFO [SessionManager] - Session identified: session-id=7466b5a0-c9d7-4d05-a45b-80d061abc47d session-name=auth session-protocol=USOFT authenticated=yes user-name=MYAPP
2026-08-13T15:55:29,371 [grizzly-http-server-0] INFO [ResponseInfoFilter] - status-code:200 client-ip:10.0.0.5 method:PATCH uri:/scim/v2/Groups/ad86835a4c084bd4b959e3d3ed4afc11 content-media-type:application/scim+json time-taken:227
The block records the full change: who authenticated (user-name=MYAPP), what was requested (add member 3836971057594f369d03ec34151a5552 to group ad86835a4c084bd4b959e3d3ed4afc11), the two statements that actually changed data (UPDATE T_AUTH_ROLE, INSERT INTO T_AUTH_ROLE_USER), the resulting group resource, and the outcome (status-code:200 in 227 ms).
A failed request
A SCIM client requests a user that does not exist, or is not linked to SCIM, with GET /Users/{id}:
2026-08-13T15:57:04,533 [grizzly-http-server-8] INFO [RequestInfoFilter] - server-ip:10.0.0.5 method:GET uri:/scim/v2/Users/bf27a5cec9a544b3aa82bce14c9b4aaf query:- server-port:40506 client-ip:10.0.0.5 client-user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 client-referer:-
2026-08-13T15:57:04,535 [grizzly-http-server-8] INFO [SessionManager] - Session identified: session-id=95fb5605-c0b8-4550-918a-6264b1fc609a session-name=auth session-protocol=USOFT authenticated=yes user-name=MYAPP
2026-08-13T15:57:04,562 [grizzly-http-server-8] INFO [ScimResource] - GET https://localhost:40506/scim/v2/Users/bf27a5cec9a544b3aa82bce14c9b4aaf
2026-08-13T15:57:04,564 [grizzly-http-server-8] INFO [ScimEngine] - SQL Query: SELECT
u.USER_GUID AS "id"
, u.EXTERNAL_ID AS "externalId"
, u.USERNAME AS "userName"
, u.DISPLAY_NAME AS "displayName"
, u.ACTIVE AS "active"
FROM
T_AUTH_USER u
WHERE
( u.USER_GUID = :user_guid OR LOWER(u.USERNAME) = LOWER(NVL(:user_name, '')) )
AND
u.EXTERNAL_ID IS NOT NULL
2026-08-13T15:57:04,564 [grizzly-http-server-8] INFO [ScimEngine] - Named Parameters: {user_name=null, user_guid=bf27a5cec9a544b3aa82bce14c9b4aaf}
2026-08-13T15:57:04,570 [grizzly-http-server-8] ERROR [ScimException] - Error: [404] Not Found: User not found
2026-08-13T15:57:04,573 [grizzly-http-server-8] INFO [SessionManager] - Session identified: session-id=95fb5605-c0b8-4550-918a-6264b1fc609a session-name=auth session-protocol=USOFT authenticated=yes user-name=MYAPP
2026-08-13T15:57:04,575 [grizzly-http-server-8] WARN [ResponseInfoFilter] - status-code:404 status-string:Not Found client-ip:10.0.0.5 method:GET uri:/scim/v2/Users/bf27a5cec9a544b3aa82bce14c9b4aaf content-media-type:application/scim+json time-taken:40
The request authenticated successfully (SessionManager reports authenticated=yes), but the lookup SELECT returned no row, so ScimEngine never logs an INSERT, UPDATE or DELETE. The failure is recorded twice: as an ERROR from ScimException with the reason, and as a WARN from ResponseInfoFilter with the resulting status-code.
Using the log as an audit trail
Because every request is bounded by a matching RequestInfoFilter and ResponseInfoFilter pair, and every statement ScimEngine runs against the Authorizer tables is logged in between, SCIM-<portnr>.log is a complete, chronological record of every change a SCIM client made — and every attempt it made that failed.
The log is plain text, so it can be fed to a file scanner and processed by another tool for reporting, rather than read by hand. Two things a scanner needs to account for:
- An entry can span multiple lines (see Log format): treat any line that does not start with a timestamp as a continuation of the previous entry.
- Requests are handled concurrently, each on its own thread (
grizzly-http-server-<n>). If more than one request is in flight, their entries interleave in the file. A scanner reconstructing one request must match itsRequestInfoFilterandResponseInfoFilterby thread name, not simply by taking the nextResponseInfoFilterline that appears.
Some patterns this supports:
- List every failed or rejected request: search for
WARN [ResponseInfoFilter]orERRORlines. The matchingScimExceptionline gives the reason, and theRequestInfoFilterline on the same thread gives the client IP, method and URI that were rejected. - Find every change made to a specific user or group: search for its GUID (or, for a group, its role name) across the
ScimEngineSQL Query/Named Parameterspairs.INSERT,UPDATEandDELETEstatements mark the points where data actually changed; theSELECTstatements around them show what the request read to get there. - Reconstruct one request in full: take a
RequestInfoFilterline and read forward, on the same thread, to itsResponseInfoFilterline. Everything in between — the raw request body, the exact SQL run, and the resulting resource — is the complete record of that one request.
ScimResource logs the request body and, on success, the resulting resource, in full. For /Users, this can include personal data, such as a userName that is an email address. Handle SCIM-<portnr>.log with the same data-protection care you would apply to the Authorizer data it describes.
Related documentation
- Introduction to SCIM - what SCIM is and why USoft implements it as a SCIM server.
- How to set up USoft as a SCIM server - configuring the Rules Service that writes this log.
- How to connect an identity provider to a USoft SCIM server
- SCIM endpoints - the endpoints these requests are made against.
- SCIM users and groups - the
T_AUTH_USERandT_AUTH_ROLEcolumns the logged SQL statements act on. - Log files and temporary files - where USoft's central logging location is configured.