Update metadata.yaml for Cloud Notifications (#15670)
* Update metadata.yaml for Cloud Notifications * Update metadata.yaml
Satyadeep Ashwathnarayana committed
Aug 1, 2023 at 18:08 UTC
995e3843226a5e1fbb667a9d5f6e469352f7bd85
1 file changed
+196
integrations/cloud-notifications/metadata.yaml
+196
@@ -475,6 +475,202 @@
475
* Basic - the client sends a request with an Authorization header that includes a base64-encoded string in the format **username:password**. These will settings will be required inputs.
476
* Bearer - the client sends a request with an Authorization header that includes a **bearer token**. This setting will be a required input.
477
478
+ ## Webhook service
479
+
480
+ A webhook integration allows your application to receive real-time alerts from Netdata by sending HTTP requests to a specified URL. In this document, we'll go over the steps to set up a generic webhook integration, including adding headers, and implementing different types of authorization mechanisms.
481
+
482
+ ### Netdata webhook integration
483
+
484
+ A webhook integration is a way for one service to notify another service about events that occur within it. This is done by sending an HTTP POST request to a specified URL (known as the "webhook URL") when an event occurs.
485
+
486
+ Netdata webhook integration service will send alert notifications to the destination service as soon as they are detected.
487
+
488
+ The notification content sent to the destination service will be a JSON object having these properties:
489
+
490
+ | field | type | description |
491
+ | :-- | :-- | :-- |
492
+ | message | string | A summary message of the alert. |
493
+ | alarm | string | The alarm the notification is about. |
494
+ | info | string | Additional info related with the alert. |
495
+ | chart | string | The chart associated with the alert. |
496
+ | context | string | The chart context. |
497
+ | space | string | The space where the node that raised the alert is assigned. |
498
+ | rooms | object[object(string,string)] | Object with list of rooms names and urls where the node belongs to. |
499
+ | family | string | Context family. |
500
+ | class | string | Classification of the alert, e.g. "Error". |
501
+ | severity | string | Alert severity, can be one of "warning", "critical" or "clear". |
502
+ | date | string | Date of the alert in ISO8601 format. |
503
+ | duration | string | Duration the alert has been raised. |
504
+ | additional_active_critical_alerts | integer | Number of additional critical alerts currently existing on the same node. |
505
+ | additional_active_warning_alerts | integer | Number of additional warning alerts currently existing on the same node. |
506
+ | alarm_url | string | Netdata Cloud URL for this alarm. |
507
+
508
+ ### Extra headers
509
+
510
+ When setting up a webhook integration, the user can specify a set of headers to be included in the HTTP requests sent to the webhook URL.
511
+
512
+ By default, the following headers will be sent in the HTTP request
513
+
514
+ | **Header** | **Value** |
515
+ |:-------------------------------:|-----------------------------|
516
+ | Content-Type | application/json |
517
+
518
+ ### Authentication mechanisms
519
+
520
+ Netdata webhook integration supports 3 different authentication mechanisms:
521
+
522
+ #### Mutual TLS authentication (recommended)
523
+
524
+ In mutual Transport Layer Security (mTLS) authentication, the client and the server authenticate each other using X.509 certificates. This ensures that the client is connecting to the intended server, and that the server is only accepting connections from authorized clients.
525
+
526
+ This is the default authentication mechanism used if no other method is selected.
527
+
528
+ To take advantage of mutual TLS, you can configure your server to verify Netdata's client certificate. In order to achieve this, the Netdata client sending the notification supports mutual TLS (mTLS) to identify itself with a client certificate that your server can validate.
529
+
530
+ The steps to perform this validation are as follows:
531
+
532
+ - Store Netdata CA certificate on a file in your disk. The content of this file should be:
533
+
534
+ <details>
535
+ <summary>Netdata CA certificate</summary>
536
+
537
+ ```
538
+ -----BEGIN CERTIFICATE-----
539
+ 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
570
+ 5zrbwvQf
571
+ -----END CERTIFICATE-----
572
+ ```
573
+ </details>
574
+
575
+ - Enable client certificate validation on the web server that is doing the TLS termination. Below we show you how to perform this configuration in `NGINX` and `Apache`
576
+
577
+ **NGINX**
578
+
579
+ ```bash
580
+ server {
581
+ listen 443 ssl default_server;
582
+
583
+ # ... existing SSL configuration for server authentication ...
584
+ ssl_verify_client on;
585
+ ssl_client_certificate /path/to/Netdata_CA.pem;
586
+
587
+ location / {
588
+ if ($ssl_client_s_dn !~ "CN=app.netdata.cloud") {
589
+ return 403;
590
+ }
591
+ # ... existing location configuration ...
592
+ }
593
+ }
594
+ ```
595
+
596
+ **Apache**
597
+
598
+ ```bash
599
+ Listen 443
600
+ <VirtualHost *:443>
601
+ # ... existing SSL configuration for server authentication ...
602
+ SSLVerifyClient require
603
+ SSLCACertificateFile "/path/to/Netdata_CA.pem"
604
+ </VirtualHost>
605
+ <Directory /var/www/>
606
+ Require expr "%{SSL_CLIENT_S_DN_CN} == 'app.netdata.cloud'"
607
+ # ... existing directory configuration ...
608
+ </Directory>
609
+ ```
610
+
611
+ #### Basic authentication
612
+
613
+ In basic authorization, the client sends a request with an Authorization header that includes a base64-encoded string in the format username:password. The server then uses this information to authenticate the client. If this authentication method is selected, the user can set the user and password that will be used when connecting to the destination service.
614
+
615
+ #### Bearer token authentication
616
+
617
+ In bearer token authentication, the client sends a request with an Authorization header that includes a bearer token. The server then uses this token to authenticate the client. Bearer tokens are typically generated by an authentication service, and are passed to the client after a successful authentication. If this method is selected, the user can set the token to be used for connecting to the destination service.
618
+
619
+ ##### Challenge secret
620
+
621
+ To validate that you has ownership of the web application that will receive the webhook events, we are using a challenge response check mechanism.
622
+
623
+ This mechanism works as follows:
624
+
625
+ - The challenge secret parameter that you provide is a shared secret between you and Netdata only.
626
+ - On your request for creating a new Webhook integration, we will make a GET request to the url of the webhook, adding a query parameter `crc_token`, consisting of a random string.
627
+ - You will receive this request on your application and it must construct an encrypted response, consisting of a base64-encoded HMAC SHA-256 hash created from the crc_token and the shared secret. The response will be in the format:
628
+
629
+ ```json
630
+ {
631
+ "response_token": "sha256=9GKoHJYmcHIkhD+C182QWN79YBd+D+Vkj4snmZrfNi4="
632
+ }
633
+ ```
634
+
635
+ - We will compare your application's response with the hash that we will generate using the challenge secret, and if they are the same, the integration creation will succeed.
636
+
637
+ We will do this validation everytime you update your integration configuration.
638
+
639
+ - Response requirements:
640
+ - A base64 encoded HMAC SHA-256 hash created from the crc_token and the shared secret.
641
+ - Valid response_token and JSON format.
642
+ - Latency less than 5 seconds.
643
+ - 200 HTTP response code.
644
+
645
+ **Example response token generation in Python:**
646
+
647
+ Here you can see how to define a handler for a Flask application in python 3:
648
+
649
+ ```python
650
+ import base64
651
+ import hashlib
652
+ import hmac
653
+ import json
654
+
655
+ key ='YOUR_CHALLENGE_SECRET'
656
+
657
+ @app.route('/webhooks/netdata')
658
+ def webhook_challenge():
659
+ token = request.args.get('crc_token').encode('ascii')
660
+
661
+ # creates HMAC SHA-256 hash from incomming token and your consumer secret
662
+ sha256_hash_digest = hmac.new(key.encode(),
663
+ msg=token,
664
+ digestmod=hashlib.sha256).digest()
665
+
666
+ # construct response data with base64 encoded hash
667
+ response = {
668
+ 'response_token': 'sha256=' + base64.b64encode(sha256_hash_digest).decode('ascii')
669
+ }
670
+
671
+ # returns properly formatted json response
672
+ return json.dumps(response)
673
+ ```
674
675
file:
676
name: ''