Events representing employee activity.
Push Security Webhooks (v1)
Configure webhooks for the Push Security platform and receive real-time updates when events occur.
Each webhook event has the following:
- Versioning
- Idempotency key
- Metadata
- New and old objects to show exactly what has changed
- A signature for verifying sender authenticity
To create or manage your webhooks, go to the Settings page in the Push admin console.
Your endpoint has 5 seconds to respond with a 200 OK (or any other 2xx response). Otherwise, retry behavior will be triggered.
Each event will be sent a maximum of 4 times at the following time intervals:
- Immediately
- After 1 minute
- After 5 minutes
- After 15 minutes
If the event is acknowledged within a 5-second window, no more retries will be attempted.
Each retry of the event will have a newly generated X-Signature, but the event id will be the same for all retries.
The payload body is JSON-encoded and contains an idempotency key named id. If you want to ensure that you handle an event exactly once, please store this value and compare it against incoming events. This can be used to discard duplicate events that have been delivered more than once.
Each event has a header X-Signature which contains 2 parts:
- A UNIX timestamp value
t(in seconds) - An HMAC-SHA-256 value
v1which contains the payload signature to check using your webhook secret obtained at the time you created it
Here is an example of how it is formatted:
X-Signature: t=1698349494,v1=0E01666E58BC2E6C64E9A5DA66C28CF9D88C3E342CCFC029D56B749A4B4282CETo calculate and verify the signature, perform the following steps:
- Parse the
X-Signatureheader by splitting it first by,and then by=to obtain key-value pairs. - Store the
t(timestamp) andv1(signature) values in variables. - Concatenate the value of
t(as a string) with a.and the JSON request body (in its raw format). - Use the HMAC-SHA256 algorithm to compute the hash of the concatenated string.
- Compare the computed HMAC with the
v1value from the header to verify the signature. - Additionally, check the timestamp (
t) and compare it to the current time. If the difference is bigger than 35 mins (or your preferable threshold) you should discard the event to avoid replay attacks.
Example in Python:
import json
import hmac
import hashlib
import time
# Your secret key for the webhook
SECRET_KEY = b'psws_ad9d0bba8260baf774c3821acaff1b7d'
# Example header and request body (you would normally get these from the incoming HTTP request)
example_header = 't=1698349494,v1=0E01666E58BC2E6C64E9A5DA66C28CF9D88C3E342CCFC029D56B749A4B4282CE'
example_request_body = json.dumps({"key": "value"})
# Step 1: Parse the header
elements = example_header.split(',')
parsed_header = {}
for element in elements:
key, value = element.split('=')
parsed_header[key] = value
# Step 2: Store 't' and 'v1' values in variables
received_t = parsed_header.get('t')
received_v1 = parsed_header.get('v1')
# Step 3: Concatenate 't' value with '.' and the JSON request body
payload = f"{received_t}.{example_request_body}"
# Step 4: Compute the HMAC using SHA256
computed_hmac = hmac.new(SECRET_KEY, payload.encode(), hashlib.sha256).hexdigest().upper()
# Step 5: Compare the signature
is_valid = hmac.compare_digest(received_v1, computed_hmac)
# Step 6: Check the timestamp
current_time = int(time.time())
time_difference = current_time - int(received_t)
if time_difference > 2100: # 35 minutes
is_valid = False
message = "Timestamp is too old."
else:
message = "Signature verified" if is_valid else "Signature mismatch"
print(f"Is the signature valid? {is_valid}. Message: {message}")Example in Node.js:
const crypto = require('crypto');
// Your secret key for the webhook
const SECRET_KEY = 'psws_ad9d0bba8260baf774c3821acaff1b7d';
// Example header and request body (you'd normally get these from the incoming HTTP request)
const exampleHeader = 't=1698349494,v1=0E01666E58BC2E6C64E9A5DA66C28CF9D88C3E342CCFC029D56B749A4B4282CE';
const exampleRequestBody = JSON.stringify({ key: 'value' });
// Step 1: Parse the header
const elements = exampleHeader.split(',');
const parsedHeader = {};
elements.forEach((element) => {
const [key, value] = element.split('=');
parsedHeader[key] = value;
});
// Step 2: Store 't' and 'v1' values in variables
const receivedT = parsedHeader['t'];
const receivedV1 = parsedHeader['v1'];
// Step 3: Concatenate 't' value with '.' and the JSON request body
const payload = `${receivedT}.${exampleRequestBody}`;
// Step 4: Compute the HMAC using SHA256
const computedHmac = crypto.createHmac('sha256', SECRET_KEY).update(payload).digest('hex');
// Step 5: Compare the signature
const isValid = crypto.timingSafeEqual(Buffer.from(receivedV1, 'hex'), Buffer.from(computedHmac, 'hex'));
// Step 6: Check the timestamp
const currentTime = Math.floor(Date.now() / 1000);
const timeDifference = currentTime - parseInt(receivedT, 10);
let message;
if (timeDifference > 2100) { // 35 minutes
isValid = false;
message = 'Timestamp is too old.';
} else {
message = isValid ? 'Signature verified' : 'Signature mismatch';
}
console.log(`Is the signature valid? ${isValid}. Message: ${message}`);
The payload body is JSON-encoded and contains a value named version. You're currently working with version 1 of the Push Security webhooks. Should there be any breaking changes in the future, we'll bump up this version number. If you have any webhooks configured, we'll send you notifications over email about the deprecation date for the older version.
Some SIEMs or other external systems where you may wish to send Push webhook events require a custom HTTP header for authorization. You can configure a custom header for webhooks in the Push admin console.
Go to Settings > Webhooks and add a new webhook. You will see a dropdown option for Custom headers.
Then enter a header key and value. Note that once your header key and value are entered, you will not be able to view them again, as they may contain secrets.
You may wish to send only specific types (or categories) of Push webhook events to your receiver. You can configure this when creating a new webhook in the Push admin console.
Go to Settings > Webhooks and add a new webhook. You will see a dropdown option for Select events.
Then you can select the specific events, or categories of events, to enable. If you select a category, any new events that are added to that category later (as part of new features released) will also be sent.
An account was created, updated or deleted.
The unique identifier for the event. This can be used as an idempotency key.
When the event occurred, formatted as a UNIX timestamp (in seconds).
The description of the event. Note: this is subject to change and should not be used to match on this object.
The friendly name of this object. Note: this is subject to change and should not be used to match on this object.
This object represents an account in your organization.
Identifier of primary employee that this account belongs to
The ID of the app associated with this account
The email address used to log into the account
Whether MFA is registered or not. If unknown, null is provided.
The MFA methods registered for this account
| Enum Value | Description |
|---|---|
| APP_TOTP | Time-based one-time password via app |
| PUSH_NOTIFICATION | Authentication prompt on device |
| EMAIL_OTP | One-time password sent to email |
| U2F | Physical security key |
| HARDWARE_TOTP | Time-based password via hardware token |
| PHONE_CALL | Voice verification |
| SMS_OTP | One-time password sent via SMS |
| APP_PASSWORD | Specialized password for app access |
| GRID_CARD | Reference card with codes |
| EXTERNAL_PROVIDER | Third-party authentication service |
Identifier of the password used on this account. The actual password is not sent up by the browser extension and so this is an identifier for it instead. This value is null if password authentication is not used.
Whether or not this account has been logged into with a password
The identity provider that was used to do an OIDC login on this account. This is null if no OIDC login has been performed.
The identity provider that was used to do a SAML login on this account. This is null if no SAML login has been performed.
Whether or not this account has been logged into with Okta SWA
Whether or not this account has an associated vendor SSO provider.
When this account was created, formatted as a UNIX timestamp (in seconds)
This object represents an account in your organization.
Identifier of primary employee that this account belongs to
The ID of the app associated with this account
The email address used to log into the account
Whether MFA is registered or not. If unknown, null is provided.
The MFA methods registered for this account
| Enum Value | Description |
|---|---|
| APP_TOTP | Time-based one-time password via app |
| PUSH_NOTIFICATION | Authentication prompt on device |
| EMAIL_OTP | One-time password sent to email |
| U2F | Physical security key |
| HARDWARE_TOTP | Time-based password via hardware token |
| PHONE_CALL | Voice verification |
| SMS_OTP | One-time password sent via SMS |
| APP_PASSWORD | Specialized password for app access |
| GRID_CARD | Reference card with codes |
| EXTERNAL_PROVIDER | Third-party authentication service |
Identifier of the password used on this account. The actual password is not sent up by the browser extension and so this is an identifier for it instead. This value is null if password authentication is not used.
Whether or not this account has been logged into with a password
The identity provider that was used to do an OIDC login on this account. This is null if no OIDC login has been performed.
The identity provider that was used to do a SAML login on this account. This is null if no SAML login has been performed.
Whether or not this account has been logged into with Okta SWA
Whether or not this account has an associated vendor SSO provider.
When this account was created, formatted as a UNIX timestamp (in seconds)
- https://api.pushsecurity.com/account
An account (Other) was created, updated or deleted.
The unique identifier for the event. This can be used as an idempotency key.
When the event occurred, formatted as a UNIX timestamp (in seconds).
The description of the event. Note: this is subject to change and should not be used to match on this object.
The friendly name of this object. Note: this is subject to change and should not be used to match on this object.
This object represents an account (other) in your organization.
Identifier of primary employee that this account belongs to
The ID of the app associated with this account
The email address used to log into the account
Whether or not this account has been logged into with a password
The identity provider that was used to do an OIDC login on this account. This is null if no OIDC login has been performed.
The identity provider that was used to do a SAML login on this account. This is null if no SAML login has been performed.
When the account was first observed, formatted as a UNIX timestamp (in seconds)
This object represents an account (other) in your organization.
Identifier of primary employee that this account belongs to
The ID of the app associated with this account
The email address used to log into the account
Whether or not this account has been logged into with a password
The identity provider that was used to do an OIDC login on this account. This is null if no OIDC login has been performed.
The identity provider that was used to do a SAML login on this account. This is null if no SAML login has been performed.
When the account was first observed, formatted as a UNIX timestamp (in seconds)
- https://api.pushsecurity.com/accounts_other
An app was created, updated or deleted.
The unique identifier for the event. This can be used as an idempotency key.
When the event occurred, formatted as a UNIX timestamp (in seconds).
The description of the event. Note: this is subject to change and should not be used to match on this object.
The friendly name of this object. Note: this is subject to change and should not be used to match on this object.
This object represents an app in your organization.
Approval status of the app, null if not set
| Enum Value | Description |
|---|---|
| UNDER_REVIEW | The app is under review |
| APPROVED | The app has been approved |
| NOT_APPROVED | The app has not been approved |
The sensitivity level of the app, null if not set
| Enum Value | Description |
|---|---|
| HIGH | The sensitivity of the app is high |
| MEDIUM | The sensitivity of the app is medium |
| LOW | The sensitivity of the app is low |
Identifier of the employee who is the owner of this platform
Notes recorded on this app (Note - changes to this field do not trigger an UPDATE event)
This object represents an app in your organization.
Approval status of the app, null if not set
| Enum Value | Description |
|---|---|
| UNDER_REVIEW | The app is under review |
| APPROVED | The app has been approved |
| NOT_APPROVED | The app has not been approved |
The sensitivity level of the app, null if not set
| Enum Value | Description |
|---|---|
| HIGH | The sensitivity of the app is high |
| MEDIUM | The sensitivity of the app is medium |
| LOW | The sensitivity of the app is low |
Identifier of the employee who is the owner of this platform
Notes recorded on this app (Note - changes to this field do not trigger an UPDATE event)
- https://api.pushsecurity.com/app