Why?
ActionHook
is a drop-in ruby gem for sending webhooks. You specify the content and destination, ActionHook
takes care of securely delivering it.
Build Status
Features:
- [x] Core Send webhooks
- [x] Configuration Timeout, IP blocking, etc.
- [x] Security Supports HTTP Basic, Token, and Bearer Token auth
- [x] Security Blocks private IPs and allows custom IP blocking
- [x] Security 2-factor authentication using a secret for each receiver
- [x] Usability Works seamlessly on Ruby on Rails. Example
- [x] Scale Works seamlessly on AWS Lambda. Example
- [x] More Logging
Send Webhooks
request = ActionHook::Core::JSONRequest.new(url: 'https://example.com',
method: :post, body: { hello: "world" }, headers: {})
ActionHook::Core::NetHTTPSender.send(request)
Configuration
All configs are optional, only use these if you want to override the defaults.
You can set the following configs in ActionHook.configuration
object.
Name | Description | Default Value |
---|---|---|
open_timeout |
Net::HTTP open timeout in seconds |
5 |
read_timeout |
Net::HTTP read timeout in seconds |
15 |
hash_header_name |
A HTTP Request header that contains the SHA256 fingerprint of the request body | SHA256-FINGERPRINT |
allow_private_ips |
If loopback or private IPs should be allowed as receiver | false |
blocked_ip_ranges |
Custom IP ranges to block, e.g. %w{172.8.9.8/24} |
[] |
Instead of ActionHook.configuration
, you can provide an instance of ActionHook::Core::Configuration
to the send
method as follows:
ActionHook::Core::NetHTTPSender.send(request, ActionHook::Core::Configuration.new)
Security: Authentication
ActionHook supports Basic
, Token
, and BearerToken
authentication out of the box. You can assign one of these authentication methods to the request object as follows:
basic = ActionHook::Security::Authentication::Basic.new(username: 'a_user', password: 'a_pass')
token = ActionHook::Security::Authentication::Token.new('a_token')
bearer_token = ActionHook::Security::Authentication::BearerToken.new('a_bearer_token')
request = ActionHook::Core::JSONRequest.new(url: 'https://example.com',
authentication: basic, # or token, bearer_token
)
Security: 2-Factor Authentication: Hashing With a Secure Key
You can generate a secure key for each receiving endpoint and pass it to ActionHook
for adding a 2nd factor authentication. Using this key, ActionHook
will automatically add the SHA256-FINGERPRINT
header to the webhook. The receiver can compute the SHA256 digest of the request body using the same secret to verify you as the sender and message integrity.
request = ActionHook::Core::JSONRequest.new(url: 'https://example.com',
secret: '<Your Secret For This Hook>', # Remember to provide your secret
method: :post, body: { hello: "world" }, headers: {})
ActionHook::Core::NetHTTPSender.send(request)
Security: IP Blocking
When a request is blocked due to private IP receiver, send
raises ActionHook::Security::IPBlocking::PrivateIPError
.
When a request is blocked due to the blocked_ip_ranges
, send
raises ActionHook::Security::IPBlocking::BlockedRequestError
.
In both cases, the error message includes necessary context for debugging / logging.
Logging
You should pass an instance of Logger
to put all ActionHook
logs into where your application log is. Otherwise, logs are written into STDOUT
by default.
# For example, in Rails, you can pass the Rails logger in an initializer
# config/initializers/actionhook_initializer.rb
ActionHook.logger = Rails.logger
Set the log level to debug
for detailed information. Even in debug, the secure header values aren't logged for accidental credential leakage, only the header names are mentioned.