Webhooks
A DoorFlow OAuth application can define a webhook_url through the developer portal at
DoorFlow uses webhooks to notify your OAuth application when an event happens in your account. Webhooks are particularly useful for asynchronous events like when a persons credentials have been updated.
Supported webhook triggers
At present the following changes will trigger a webhook callback:
- PersonCredential changes
- Perimeter events (door forced, door extended open, door normal)
- Access events
Your OAuth application will need to have the appropriate scopes approved in order to receive these webhook callbacks. If you have any questions, please get in touch with us.
Steps to receive webhooks
- Create a webhook endpoint as an HTTP endpoint (URL) on your server.
- Handle requests from DoorFlow by parsing the payload and returning a 200 response status.
- Secure your webhook by validating the HMAC signature sent by DoorFlow to ensure authenticity.
- Use a service such as ngrok to make your
webhook_url
publicly accessible during development. - Add your temporary
webhook_url
through the developer portal at https://developer.doorflow.com. - Once a webhook request has been received from DoorFlow, use the
resource_url
provided to request the latest resource from our API. - Acknowledge the receipt of each webhook using the
ack_token
provided to maintain reliable delivery. - Test your webhook endpoint is working properly with DoorFlow.
- Deploy your webhook endpoint to your production servers.
- Replace your temporary
webhook_url
with your productionwebhook_url
through the developer portal.
Security Measures
HMAC Signature
The linchpin of our webhook security is the HMAC-SHA256 signature, included in every outgoing webhook within the Signature
header. This signature is a cryptographic hash generated from the webhook payload and the shared secret key, ensuring the authenticity and integrity of the request.
Timestamp
Each webhook payload is accompanied by a timestamp, within the Timestamp
header. This inclusion is a security measure against replay attacks, ensuring that intercepted webhook requests cannot be reused maliciously. The timestamp is integral to the signature generation process, providing a time-sensitive layer of security that enhances the trustworthiness of the webhook interaction.
Signature Generation Process
The signature is generated by concatenating the timestamp and the serialized JSON payload, forming a string with the structure timestamp.payload
. This concatenated string is then encrypted using the SHA-256 algorithm and the secret key to produce the HMAC signature. This method ensures that both the content and the timing of the message are verified, adding an extra layer of security.
Verifying Webhook Authenticity
To verify the authenticity of a received webhook:
- Extract the Signature: Retrieve the HMAC signature from the
Signature
header. - Recreate the Signature Data String: Concatenate the received timestamp with the received payload in the format
timestamp.payload
. - Generate Your Signature: Encrypt the combined string using the SHA-256 hashing algorithm and your secret key to produce a signature.
- Compare Signatures: Match your generated signature against the one in the header. If they match, the webhook is confirmed to be authentic, indicating it has been sent by DoorFlow and has not been altered.
This thorough validation process ensures that the webhooks you process are secure, verified, and authentic, maintaining the integrity of the information exchange.
Verifying Webhook Example
Example HTTP Request
RequestPOST /webhook-endpoint HTTP/1.1
Host: your-webhook-endpoint.com
Content-Type: application/json
Timestamp: 1712049196
Signature: 80be869dade5c74a15326aa6e1b7a41b33540cb0c7ca4018b3feef92a7a2e270
[
{
"action": "CREATE",
"resource": "https://api.doorflow.com/api/3/events/98321?ack_token=unique_acknowledgement_token",
"resource_type": "Event",
"resource_id": "98321",
"account_id": "nbYfy7",
"ack_token": "unique_acknowledgement_token"
}
]
Verification with Python
import hashlib
import hmac
# Example values from the webhook request
timestamp = "1712049196"
received_signature = "da6685646a982f973f26bdfd84762e3f02a9d6676dbde0692e91267a1ebd7f6d"
payload = '[{"action":"CREATE","resource":"https://api.doorflow.com/api/3/events/98321?ack_token=unique_acknowledgement_token","resource_type":"Event","resource_id":"98321","account_id": "nbYfy7","ack_token":"unique_acknowledgement_token"}]'
# Your secret key provided by DoorFlow
secret_key = "fGdEhjYl_cdFIcAhL3Cq0kr5osdnLnMQQJEef0yWxPX"
# Generate the HMAC-SHA256 signature
signature = hmac.new(secret_key.encode(), f"{timestamp}.{payload}".encode(), hashlib.sha256).hexdigest()
# Signature validation
print("Signature is valid." if hmac.compare_digest(received_signature, signature) else "Signature is invalid.")
Acknowledge Token
Each webhook may include an ack_token
when provided this must be used to acknowledge the receipt of the webhook. This acknowledgement should be sent back to DoorFlow as a param named ack_token
when accessing the associated resource. This process ensures reliable delivery of webhooks and accountability to our users that the Oauth Application is processing webhooks for their account.
Access Token Requirement
For a webhook to be sent, a valid access token with the appropriate scopes is required. This requirement ensures that only authorized applications can receive webhook data, protecting sensitive information from unauthorized access. The access token acts as a permission slip, indicating that the application has been granted explicit consent to receive information about specific events.
Handling Webhooks Across Multiple Accounts
In a multi-tenant system where your application receives webhooks from various accounts, it is essential to associate each operation with the correct account. This ensures that actions triggered by webhooks are accurately attributed and that your application interacts with the DoorFlow API using the correct access token for each account.
Establishing an Access Token Registry
Your application should maintain a registry of access tokens, associating each token with its corresponding account_id. This registry is critical for identifying which access token to use when interacting with the DoorFlow API in response to received webhooks.
Obtaining account_id Using the OAuth 2.0 /oauth/token/info Endpoint
To associate an access token with an account_id, use the DoorFlow OAuth 2.0 /oauth/token/info endpoint. This endpoint provides metadata about an access token, including the account_id it's associated with.
Making a Request
GET https://api.doorflow.com/oauth/token/info
Authorization: Bearer <ACCESS_TOKEN>
{
"resource_owner_id": 44,
"account_id": 884455,
"scope": [
"account.person.readonly",
"account.event.access.readonly"
],
"expires_in": 3086,
"application": {
"uid": "CN90U5jZxvnCaOUaNlGgMWjo5YMVo8aAg9P1mTKah-U"
},
"created_at": 1712498127
}
The account_id field is critical; it indicates the account the access token is associated with. This information allows your application to select the correct access token from your registry when processing webhooks.
Best Practices
- Secure Storage: Ensure the secure storage of access tokens and their associated account_ids to protect against unauthorized access.
- Token Lifecycle Management: Implement logic to handle token expiration and renewal, ensuring your application has continuous access.
- Minimal Scope Request: Limit the scopes requested for each token to minimize potential damage in the event of a token compromise.
Processing Webhooks from Multiple Accounts
When your application receives a webhook:
- Identify the account context of the webhook. If not directly provided in the webhook payload, use stored data that associates webhook types or identifiers with specific accounts.
- Retrieve the appropriate access token for the account from your registry.
- Use this access token for any API calls made to the DoorFlow API in response to the webhook.
Responding to a webhook
Please ensure your endpoint returns a status code within the 200-299 range. Any code outside this range is considered an error.
Example Request Body
The webhook request will be made by DoorFlow to your webhook_url you have defined for your application.
Example Payload
[
{
"action": "CREATE",
"resource": "https://api.doorflow.com/api/3/events/98321?ack_token=unique_acknowledgement_token",
"resource_type": "Event",
"resource_id": "98321",
"account_id": "nbYfy7",
"ack_token": "unique_acknowledgement_token"
}
]
Actions
The action
field in the webhook payload specifies the type of event that occurred. The possible values and their meanings are as follows:
Action | Meaning |
---|---|
CREATE | A new resource has been created |
UPDATE | An existing resource has been updated |
DESTROY | A resource has been destroyed |
Scopes for Webhooks
To ensure your application receives the appropriate webhook events, it must request the correct scopes. The updated scopes related to webhook events are:
-
account.event.perimeters.readonly
: This scope allows event webhooks and viewing events related to perimeter events, such as doors being forced open or left open. -
account.event.access.readonly
: This scope allows event webhooks and viewing events related to access information, including when access is admitted or rejected. -
account.person.readonly
: This scope allows person credential webhooks and viewing people related to this information, including the credential type and value.
It's important to configure your application with the necessary scopes to ensure it receives the relevant webhook events from DoorFlow.
Redemption of resources
Sometimes it's important that webhooks aren't sent into the wind without any confirmation that they've been consumed. This is particularly important when building security monitoring systems where you need to ensure that comms have been at least acknowledged.
To this end, we track when a webhook resource has been redeemed.
Webhook resources can be redeemed at any time. That said we assume that this will happen within 5 seconds of being issued.