Audit Logs
Overview
Glassix has many logs documenting both general changes and security events.
You might want to save these logs on your end or preform actions based on your needs.
Glassix provides two integration methods for receiving said logs:
- Sending logs via Webhooks.
- Using logs in Functions.
Log Types
Glassix has two main log types:
- Informative - logs of general operations and management e.g., chatbot mapping, department name change, business hours update, etc.
- Security - logs regarding sensitive information and operations e.g., security settings changes, user logins, password changes, etc.
Event Type Reference
Every audit log includes a type field identifying the event, and a logType field (Security or Informative). The tables below list all event types Glassix can emit, so you can map them in your monitoring or SIEM system.
Security events
These cover access, identity, permissions, and sensitive operations.
type | Description |
|---|---|
UserLogin | A user signed in |
UserLogout | A user signed out |
UserLoginFailed | A sign-in attempt failed |
UserFaildLoginAttempt | A failed login attempt was recorded |
LoginAttemptUnauthorizedIP | Login attempted from an IP outside the allowed list |
UserUnlocked | A locked user account was unlocked |
IncorrectPinCode | An incorrect PIN code was entered |
PinCodeGeneratedByAdmin | An admin generated a PIN code for a user |
TwoFactorAuthenticationEnabled | Two-factor authentication was enabled |
TwoFactorAuthenticationDisabled | Two-factor authentication was disabled |
NewUserCreated | A new user was created |
UserRemoved | A user was removed |
RoleAdded | A role was granted to a user |
RoleRemoved | A role was removed from a user |
TenantAddedToUser | A workspace/department was added to a user |
TenantRemovedFromUser | A workspace/department was removed from a user |
UserPasswordReset | A user password was reset |
UserPasswordChange | A user changed their password |
UserPasswordResetLinkSent | A password reset link was sent |
UserShortNameChange | A user's short name was changed |
UserFullNameChange | A user's full name was changed |
UserJobTitleChange | A user's job title was changed |
UserSetPhoneNumber | A user's phone number was set |
UserStatusChanged | A user's availability status changed |
TicketParticipantNameChange | A ticket participant's name was changed |
TicketOwnerChanged | A ticket's owner was changed |
GetUserAccessToken | A user access token was issued |
UserShowApiCredentials | A user viewed API credentials |
EnteredSettingsScreen | A user opened the settings screen |
AuthorizedIPAddressesChange | The list of authorized IP addresses was changed |
BlackListUpdated | The blacklist was updated |
PasswordStrengthSettingsChange | Password strength settings were changed |
AgentIdleSettingsChange | Agent idle settings were changed |
AlwaysAllowSupportTeamAccessToSettingsChanged | The "always allow support team access" setting was changed |
SupportDataAccessGranted | Access to data was granted to the support team |
SupportDataAccessRevoked | Access to data was revoked from the support team |
BillingChanged | Billing settings were changed |
UserGlobalDefinitionChange | A global user definition was changed |
TicketSearchQuery | A ticket search query was performed |
ApiListFirstTicketsQuery | An API query listed the first page of tickets |
ApiListNextTicketsQuery | An API query listed a subsequent page of tickets |
Query | A query was executed |
ReportsGeneration | A report was generated |
ReportsPushedToQueue | A report was queued for generation |
PdfTicketSummaryDownload | A PDF ticket summary was downloaded |
AvailableEmailAgent | An email agent became available |
AutoSetUserOfflineBrowserClosed | A user was set offline automatically after closing the browser |
FailedCreateDepartment | A department creation attempt failed |
Informative events
These cover channel/integration connections and general configuration changes.
type | Description |
|---|---|
CompanyNameChanged | The company name was changed |
DepartmentNameChanged | A department name was changed |
DepartmentLogoChanged | A department logo was changed |
DepartmentLocationChange | A department location was changed |
DepartmentSetDeleted | A department set was deleted |
BusinessHoursUpdate | Business hours were updated |
LicensingChanged | Licensing was changed |
SetTenantTags | Workspace tags were set |
SetTenantDefinition | A workspace definition was set |
LocalizationResourceChange | A localization resource was changed |
CopyTicketSummaryToClipboard | A ticket summary was copied to the clipboard |
AddCannedReplies | A canned reply was added |
UpdateCannedReplyCategory | A canned reply category was updated |
DeleteCannedReplyCategory | A canned reply category was deleted |
ChatbotMappingsChange | Chatbot mappings were changed |
SurveyMappingsChange | Survey mappings were changed |
SurveyUpdatedOrAdded | A survey was added or updated |
SurveyDeleted | A survey was deleted |
FlowPublished | A chatbot flow was published |
FlowDeleted | A chatbot flow was deleted |
FlowDuplicated | A chatbot flow was duplicated |
FlowConversationCardsChanged | A flow's conversation cards were changed |
FunctionEventAdded | A function event was added |
FunctionEventChanged | A function event was changed |
FunctionEventDeleted | A function event was deleted |
FunctionLog | A function emitted a log |
EnvironmentVariableLog | An environment variable change was logged |
WebhookItemAdded | A webhook was added |
WebhookItemChanged | A webhook was changed |
WebhookItemDeleted | A webhook was deleted |
ProtocolSettingChange | A channel protocol setting was changed |
ProtocolIdentifierDeleted | A channel protocol identifier was deleted |
InvalidThirdPartyAccessToken | A third-party access token was found invalid |
ApiGetAccessToken | An API access token was issued |
MetaPageConnected | A Meta (Facebook) page was connected |
FacebookTokenIsValidChange | A Facebook token validity status changed |
GoogleBusinessMessagesConnected | Google Business Messages was connected |
Outlook365Connected | An Outlook 365 mailbox was connected |
Outlook365SubscribeInboundMessages | Subscribed to Outlook 365 inbound messages |
Outlook365ResubscribeInboundMessages | Re-subscribed to Outlook 365 inbound messages |
GmailConnected | A Gmail mailbox was connected |
GmailResubscribeInboundMessages | Re-subscribed to Gmail inbound messages |
SendGridConnected | A SendGrid account was connected |
SendGridDomainAuthenticated | A SendGrid domain was authenticated |
SendGridDomainValidated | A SendGrid domain was validated |
WhatsAppTemplateSubmitted | A WhatsApp template was submitted for approval |
WhatsAppTemplateDeleted | A WhatsApp template was deleted |
Note:New event types are added over time. If you receive a
typenot listed here, treat itslogTypefield as the source of truth for categorization.
Logs Format
Informative
{
"key": "9200c94a-13d7-4397-a52c-1728fc6bb670",
"dateTime": "2024-01-07T12:23:16.9159993Z",
"changes": [
{
"_event": "AUDIT_LOGS",
"log": {
"id": "8e548273-0418-4e7b-acd6-c79f7d31e3ec",
"dateTime": "2024-01-07T12:23:16.7965229Z",
"departmentId": "9200c94a-13d7-4397-a52c-1728fc6bb670",
"initiatorUser": {
"id": "aca76a89-8950-4424-b727-2f277c24a891",
"gender": "Male",
"UserName": "[email protected]",
"culture": "en-US",
"isAnonymous": false,
"uniqueArgument": "",
"type": "AGENT"
},
"ipAddress": "212.199.97.210",
"message": "[email protected] changed chatbot mappings",
"type": "ChatbotMappingsChange",
"logType": "Informative"
}
}
]
}Security
{
"key": "9200c94a-13d7-4397-a52c-1728fc6bb670",
"dateTime": "2024-01-11T09:18:32.7608826Z",
"changes": [
{
"_event": "AUDIT_LOGS",
"log": {
"id": "cb20ff99-25bb-400c-a8cd-9052fc5f6d3f",
"dateTime": "2024-01-11T09:18:32.7452358Z",
"departmentId": "9200c94a-13d7-4397-a52c-1728fc6bb670",
"initiatorUser": {
"id": "aca76a89-8950-4424-b727-2f277c24a891",
"gender": "Male",
"UserName": "[email protected]",
"culture": "en-US",
"isAnonymous": false,
"uniqueArgument": "",
"type": "AGENT"
},
"targetUser": {
"id": "2bab1a91-b203-4127-a546-8636165e873a",
"gender": "Male",
"UserName": "[email protected]",
"culture": "en-US",
"isAnonymous": false,
"uniqueArgument": "",
"type": "AGENT"
},
"ipAddress": "212.199.97.210",
"message": "[email protected] removed by [email protected]",
"type": "UserRemoved",
"logType": "Security"
}
}
]
}Send Logs via Webhooks
You can connect logs to your webhooks endpoint to receive a copy of the event's message to your systems. You can perform various actions using these logs, including documenting them in your systems.
- Go to Settings.
Click on the symbol in the agent dashboard.
- In the Developers section, click on Events →Webhooks → Add +.
- Type a name for your webhook in the Name text box.
- In the Target text box, type <Your HTTPS Endpoint>.
- Use the checkbox to choose AUDIT_LOGS .
- Click Save.
Send logs to Syslog using Glassix functions
Syslog is a protocol that computer systems use to send event data logs to a central location for storage. Logs can then be accessed by analysis and reporting software to perform audits, monitoring, troubleshooting, and other essential IT operational tasks.
Syslog Format Example
<166>1 2024-01-15T11:19:07.00Z glassix.com glassix - ad681bbc-9608-4a2a-a283-717011f35c35 [data id="ad681bbc-9608-4a2a-a283-717011f35c35" dateTime="2024-01-15T11:19:07.7935597Z" departmentId="95b4ae47-a872-4dd5-920d-7b01d64288ad" initiatorUser_id="f4d56da7-f39f-4741-8c84-4b5b34e40ad3" initiatorUser_gender="Undefined" initiatorUser_UserName="[email protected]" initiatorUser_culture="en-US" initiatorUser_isAnonymous="false" initiatorUser_uniqueArgument="" initiatorUser_type="AGENT" targetUser_id="2563e94e-f68e-4cf8-b13b-17cfc95c437d" targetUser_gender="Undefined" targetUser_UserName="[email protected]" targetUser_culture="en-US" targetUser_isAnonymous="true" targetUser_uniqueArgument="" targetUser_type="AGENT" ipAddress="212.199.97.210" message="[email protected] removed role SystemUser from [email protected]" type="RoleRemoved" logType="Security"] RoleRemoved: [email protected] removed role SystemUser from [email protected]
Most Syslog servers support receiving messages using TCP or UDP protocols, and NOT HTTP.
As our webhooks events are sent using HTTP requests, you need to find a way to send these messages using TCP or UDP. One way of doing that is by utilizing our native functions integration.
Glassix functions can be triggered by events.
You can connect logs to trigger a function whenever an event occurs.
The log object passed to the function will contain information about the log message, such as message text, timestamp, and related users that were affected.
First, you will have to create a webhook function that can listen to events.
Function Examples
Sending audit logs to a Syslog server using TCP
Note:You must import the net and glossy NPM. For more info on NPMs and Glassix read here.
import * as net from "net";
import * as glossy from "glossy";
const handler = async (key, dateTime, changes) => {
let glassixLog = changes?.[0]?.log;
if (!glassixLog.id) {
console.error('Payload must contain a log "id"');
};
//Flatten the log object
const mapObjProprties = (obj, output = {}, prefix = '') => {
Object.entries(obj).forEach(([key, val]) => {
if (val && typeof val == 'object') mapObjProprties(val, output, prefix + key + '_');
else output[prefix + key] = val;
});
return output;
};
glassixLog = mapObjProprties(glassixLog);
try {
//Open TCP Connection
const Syslog = glossy.Produce;
const syslogServerHost = process.env.SYSLOG_SERVER_HOST; // Your server's hostname
const syslogServerPort = process.env.SYSLOG_SERVER_PORT; // Syslog listener port
const socket = new net.createConnection(syslogServerPort, syslogServerHost);
const connectToServer = () => new Promise((resolve, reject) => {
socket.on('connect', () => {
resolve(true)
});
socket.on('error', function(error) {
resolve(false)
});
socket.on('timeout', function(error) {
resolve(false)
})
});
const isConnected = await connectToServer();
if (isConnected) {
const producer = new Syslog({ type: 'RFC5424', app_id: 'glassix', host: 'glassix.com' });
const logData = {
facility: 'local4', // You can override the default facility here if needed
severity: 'info', // Log severity level
appName: 'glassix', // Log source application
date: glassixLog.dateTime, // Log timestamp
msgID: glassixLog.id,
message: `${glassixLog.type}: ${glassixLog.message}`,
structuredData: { data: glassixLog }
};
// Convert the log data to the syslog format
const syslogMessage = producer.produce(logData);
// Send the syslog message to the server
socket.write(syslogMessage);
// Close the socket connection after sending the message
socket.end();
}
socket.end();
} catch (e) {
console.log(e)
}
};Sending audit logs to a Syslog server using UDP
Note:You must import the dgram and glossy NPM. For more info on NPMs and Glassix read here.
import * as dgram from "dgram";
import * as glossy from "glossy";
const handler = async (key, dateTime, changes) => {
try {
// Define UDP
const Syslog = glossy.Produce;
const client = dgram.createSocket('udp4');
const syslogServerHost = process.env.SYSLOG_SERVER_HOST; // Your server's hostname
const syslogServerPort = process.env.SYSLOG_SERVER_PORT; // Syslog listener port
let glassixLog = changes?.[0]?.log;
if (!glassixLog.id) {
console.error('Payload must contain a "id" key');
};
const mapObjProprties = (obj, output = {}, prefix = '') => {
Object.entries(obj).forEach(([key, val]) => {
if (val && typeof val == 'object') mapObjProprties(val, output, prefix + key + '_');
else output[prefix + key] = val;
});
return output;
};
glassixLog = mapObjProprties(glassixLog);
// Create a glossy producer
const producer = new Syslog({type: 'RFC5424', app_id: 'glassix', host: 'glassix.com'});
// Log a message
const logData = {
facility: 'local4', // You can override the default facility here if needed
severity: 'info', // Log severity level
appName: 'glassix', // Log source application
date: glassixLog.dateTime, // Log timestamp
msgID: glassixLog.id,
message: `${glassixLog.type}: ${glassixLog.message}`,
structuredData: { data: glassixLog }
};
// Convert the log data to the syslog format
const syslogMessage = producer.produce(logData);
const packet = Buffer.from(syslogMessage)
client.send(packet, syslogServerPort, syslogServerHost, (err) => {
if (err) {
console.error('Failed to send syslog.')
} else {
console.log('Syslog sent successfully!')
}
client.close();
});
} catch (e) {
console.log(e)
}
};Next, we will have to connect our function to the audit logs event type.
- Go to Settings.
Click on the symbol in the agent dashboard.
- In the Developers section, click on Events →Functions → Add +.
- Fill Name.
- From the Events drop-down select AUDIT_LOGS .
- From the Functions drop-down select your desired function.
- Click Save.
Updated 18 days ago