Open Notificaties Documentation
Open Notificaties is a modern, open-source messaging service that implements the VNG API standard for the “Notificaties API” in line with the Common Ground model. Among others, it can be used in combination with Open Zaak which implements the VNG standards for “API’s voor Zaakgericht werken” that require a Notificaties API.
Getting Started
To get you started, you might find some of these links relevant:
New to Open Notificaties? Have a look at the Introduction
New to the VNG standards for “API’s voor Zaakgericht werken”? Read up on the API-specifications.
Want to get started with Open Notificaties yourself? See Installation.
Need help with Open Notificaties? Contact Support.
Are you a developer? Head over to Development (TODO)!
Open Notificaties is and only uses Open-source.
Introduction
Open Notificaties is a modern, open-source messaging service that implements the VNG API standard for the “Notificaties API” in line with the Common Ground model. Among others, it can be used in combination with Open Zaak which implements the VNG standards for “API’s voor Zaakgericht werken” that require a Notificaties API.
Open Notificaties exposes a Notificaties API (notifications) to route privacy-safe messages from publishers to subscribers.
Open Notificaties is based on the API reference implementations by VNG Realisatie to create a production-grade product that can be used by municipalities.
Architecture
Open Notificaties is based on the reference implementation of the “API’s voor Zaakgericht werken” made by VNG Realisatie. The overall architecture remains faithful to the Common Ground principles and all API specifications.
The architecture of Open Notificaties focusses on excellent performance, optimal stability and to guarantee data integrity. Under the hood, it uses RabbitMQ as message broker with just a light weight REST API on top of it.
It largely resembles the original reference implementation and remains its own component to scale separately from any other component.
Who’s behind Open Notificaties?
The Open Notificaties project was built for the Open Zaak project, initiated shortly before the 1.0 release of the VNG standards for “API’s voor Zaakgericht werken”, on August 1, 2019, by 9 municipalities:
Amsterdam
Rotterdam
Utrecht
Tilburg
Arnhem
Haarlem
‘s-Hertogenbosch
Delft
Hoorn, Medemblik, Stede Broec, Drechteland, Enkhuizen (SED)
Using Dimpact as a legal entity, they formed a project to develop a modern, open-source data- and services-layer to enable zaakgericht werken, in line with the Common Ground model.
Open-source
Open Notificaties is open-source and available under the EUPL license.
In addition, this project makes use of various open-source Python libraries and npm packages under the hood.
API-specifications
Open Notificaties adheres to the API-specifications as described by the VNG API standard for the “Notificaties API”.
Supported API versions
The following API’s are available in Open Notificaties:
API |
Specification version(s) |
---|---|
Installation
There are several ways to install Open Notificaties. A scalable solution is to use Kubernetes. You can also run the Docker containers on a single machine
Before you begin
Check the minimum system requirements for the target machine(s).
Make sure the target machine(s) have access to the Internet.
The target machine(s) should be reachable via at least a local DNS entry:
Open Zaak:
open-zaak.<organization.local>
Open Notificaties:
open-notificaties.<organization.local>
The machine(s) do not need to be publically accessible and do not need a public DNS entry. In some cases, you might want this but it’s not recommended. The same machine can be used for both Open Zaak and Open Notificaties.
If you want to use NLX, make sure you have a publicaly available domain name, for example
nlx.<organization.com>
, where your NLX-inway is accessible to the outside world.
Guides
Hardware
Based on our initial performance tests in both a Kubernetes environment and single machine setups, we can indicate some minimum system requirements to reach a certain performance.
Notifications are likely to increase over time, due to more external components makes use of it, or more subscribers want to receive notifications. Hence, we recommend a Kubernetes setup since it will scale more easy.
Determine what you need
Since notifications are typically only sent for update and create actions, the number of notifications will most likely not be that high. Some functional views might cause a series of create and/or update actions, so there is a short burst of notifications which you will need to handle.
It really depends on how many consumers and other components will make use of Open Notificaties but assuming 50 requests per second will probably be a good start for any environment.
Minimum system requirements
Platform: 64-bit
Processor(s): 4 - 12 CPUs (see below) at 2.0 GHz
RAM: 4 - 12 GB (see below)
Hard disk space: 20 GB
Based on the number of requests per second you need, you can see what kind of hardware you need to achieve this.
Requests per second |
CPUs |
Memory (GB) |
50 |
4 |
4 |
100 |
6 |
6 |
200 |
12 |
12 |
With these specifications you can run everything on a single machine or divided over several instances.
Use a seperate database server with roughly a third of the CPUs and memory as the main server. The database is usually the limiting factor.
Preferably use 2 load balancer (like Traefik) replica’s.
Use as many replica’s as available CPU’s taking into account you need to have a few replica’s for your load balancer, and possibly other services.
RabbitMQ needs at least 256MB of memory - don’t configure your resource limits lower than that amount.
Deploying on Kubernetes (TODO)
Deploying on a single server
Open Notificaties can be deployed on a single machine - either a dedicated server (DDS) or virtual private server (VPS). The required hardware can be rented from a hosting provider or be provided in your environment. Please see Hardware to determine the hardware requirements.
This documentation describes the architecture, prerequisites and how to deploy Open Notificaties on a server. Additionally, it documents the possible configuration options.
Note
The default settings allow Open Notificaties to be deployed to the same machine as Open Zaak.
Architecture
The application is deployed as Docker containers, of which the images are available on docker hub. Traffic is routed to the server, where the web server (nginx) handles SSL termination and proxies the requests to the application containers.
Data is stored in a PostgreSQL database. By default, the database is installed on the same machine (running on the host), but you can make use of a hosted database (Google Cloud, AWS, Azure…). See the Configuration parameters for more information.
Prerequisites
Before you can deploy, you need:
Ensure you have a server with root
privileges. We assume you can directly
ssh to the machine as root
user. If that’s not the case, a user with
sudo
will also work. Python 3 must be available on the server.
Note
Make sure there is enough space in /var/lib/docker
. You need at
least 8 GB to download all Docker container images.
Supported operating systems
Support for different Linux flavours is maintained in the Ansible collection used for deployment.
Currently the following OS flavours are supported:
Debian: buster (10, actively supported), stretch (9, actively supported), jessie (8)
Ubuntu: eoan (EOL), disco (EOL), cosmic (EOL), bionic (18.04 LTS). focal (20.04 LTS) is not tested yet
SUSE Enterprise Linux: 15 (actively supported)
OpenSUSE: 15.1
Red Hat: 7, 8
CentOS: 7, 8 (actively supported)
You can either clone the https://github.com/open-zaak/open-notificaties repository, or download and extract the latest ZIP: https://github.com/open-zaak/open-notificaties/archive/main.zip
You will need to have at least Python 3.5 installed on your system. In the examples, we assume you have Python 3.6.
Create a virtualenv with:
[user@laptop]$ python3.6 -m venv env/
[user@laptop]$ source env/bin/activate
Make sure to install the deployment tooling. In your virtualenv, install the dependencies:
(env) [user@laptop]$ pip install -r deployment/requirements.txt
(env) [user@laptop]$ ansible-galaxy collection install -r requirements.yml
(env) [user@laptop]$ ansible-galaxy role install -r requirements.yml
Deployment
Deployment is done with an Ansible playbook, performing the following steps:
Install and configure PostgreSQL database server
Install the Docker runtime
Install the SSL certificate with Let’s Encrypt
Setup Open Notificaties with Docker
Install and configure nginx as reverse proxy
Make sure the virtualenv is activated:
[user@laptop]$ source env/bin/activate
Navigate to the correct deployment directory:
(env) [user@laptop]$ cd deployment/single-server
Create the vars/open-notificaties.yml
file - you can find an example in
vars/open-notificaties.yml.example
. Generate a secret key using the
django secret key generator and put the value between single
quotes.
Configure the host by creating the hosts
file from the example:
(env) [user@laptop]$ cp hosts.example hosts
Edit the open-notificaties.gemeente.nl
to point to your actual domain name. You must
make sure that the DNS entry for this domain points to the IP address of your
server.
Warning
It’s important to use the correct domain name, as the SSL certificate
will be generated for this domain and only this domain will be whitelisted
by Open Notificaties! If you are using a private DNS name, then no SSL certificate
can be created via Letsencrypt - make sure to disable it by setting
certbot_create_if_missing=false
.
Execute the playbook by running:
(env) [user@laptop]$ ansible-playbook open-notificaties.yml
Hint
If you have your secrets Ansible vault encrypted, make sure you have either:
set the
ANSIBLE_VAULT_PASSWORD_FILE
environment variable, orpass
--ask-vault-pass
flag toansible-playbook
.
If you need to override any deployment variables (see Configuration parameters), you can pass variables to
ansible-playbook
using the syntax:--extra-vars "some_var=some_value other_var=other_value"
.If you want to run the deployment from the same machine as where it will run (ie. install to itself), you can pass
--connection local
toansible-playbook
.If you cannot connect as
root
to the target machine, you can pass--user <user> --become --become-method=sudo --ask-become-pass
which will connect as user<user>
that needssudo
-rights on the target machine to install the requirements.
A full example might look like this:
(env) [user@laptop]$ ansible-playbook open-notificaties.yml \
--user admin
--inventory my-hosts \ # Use inventory file ``my-hosts`` instead of ``hosts``.
--limit open-notificaties.gemeente.nl \ # Only pick open-notificaties.gemeente.nl from the inventory file.
--extra-vars "certbot_create_if_missing=false app_db_name=opennotificaties-test app_db_user=opennotificaties-test" \
--connection local \
--become \
--become-method=sudo \
--ask-become-pass
Note
You can run the deployment multiple times, it will not affect the final outcome. If you decide to change configuration parameters, you do not have to start from scratch.
After the initial deployment, some initial configuration is required. This configuration is stored in the database and is only needed once.
Create a superuser
A superuser allows you to perform all administrative tasks.
Log in to the server:
[user@laptop]$ ssh root@open-notificaties.gemeente.nl
Create the superuser (interactive on the shell). Note that the password you type in will not be visible - not even with asterisks. This is normal.
[root@open-notificaties.gemeente.nl]# docker exec -it opennotificaties-0 src/manage.py createsuperuser Gebruikersnaam: demo E-mailadres: admin@open-notificaties.gemeente.nl Password: Password (again): Superuser created successfully.
Configure Open Notificaties Admin
See the Open Notificaties configuration on how to configure Open Notificaties post-installation.
Configuration parameters
At deployment time, you can configure a number of parts of the deployment by
overriding variables. You can override variables on the command line (using the
-e "..."
syntax) or by overriding them in vars/secrets.yml
.
Note
Tweaking configuration parameters is considered advanced usage.
certbot_admin_email
: e-mail address to use to accept the Let’s Encrypt terms and conditions.certbot_create_if_missing
: whether to use Let’s Encrypt to create an SSL certificate for your domain. Set tofalse
if you want to use an existing certificate.
The default values can be found in roles/opennotificaties/defaults/main.yml
.
opennotificaties_db_port
: database port. If you are running multiple PostgreSQL versions on the same machine, you’ll have to point to the correct port.opennotificaties_db_host
: specify the hostname if you’re using a cloud database or a database on a different server.opennotificaties_db_name
: specify a different database name.opennotificaties_secret_key
: A Django secret key. Used for cryptographic operations - this may NOT leak, ever. If it does leak, change it.
Scaling
The opennotificaties_replicas
variable controls scaling on backend services. If
your hardware allows it, you can create more replicas. By default, 3 replicas
are running.
The format of each replica is:
name: opennotificaties-i
port: 900i
The port number must be available on the host - i.e. you may not have other services already listening on that port.
The opennotificaties_worker_replicas
variable controls the scaling of the queue
workers - these are responsible for actually distributing the notifications. By default,
3 replicas spin up.
The format of each replica is:
name: opennotificaties-worker-i
Updating an Open Notificaties installation
Make sure you have the deployment tooling installed - see the installation steps for more details.
If you have an existing environment (from the installation), make sure to update it:
# fetch the updates from Github
[user@host]$ git fetch origin
# checkout the tag of the version you wish to update to, e.g. 1.0.0
[user@host]$ git checkout X.Y.z
# activate the virtualenv
[user@host]$ source env/bin/activate
# ensure all (correct versions of the) dependencies are installed
(env) [user@host]$ pip install -r requirements.txt
(env) [user@host]$ ansible-galaxy install -r requirements.yml
Open Notificaties deployment code defines variables to specify the Docker image tag to use. This is synchronized with the git tag you’re checking out.
Next, to perform the upgrade, you run the open-notificaties.yml
playbook just like
with the installation in Running the deployment:
(env) [user@laptop]$ ansible-playbook open-notificaties.yml
Note
This will instruct the docker containers to restart using a new image. You may notice some brief downtime (order of seconds to minutes) while the new image is being downloaded and containers are being restarted.
Configuration
Environment configuration reference
Open Notificaties can be ran both as a Docker container or directly on a VPS or dedicated server. It relies on other services, such as database and cache backends, which can be configured through environment variables.
DJANGO_SETTINGS_MODULE
: which environment settings to use. Available options:nrc.conf.production
nrc.conf.staging
nrc.conf.docker
nrc.conf.dev
nrc.conf.ci
SECRET_KEY
: secret key that’s used for certain cryptographic utilities. You should generate one via miniwebtoolALLOWED_HOSTS
: a comma separated (without spaces!) list of domains that serve the installation. Used to protect againstHost
header attacks.
Docker
Additionally, the following optional envvars MUST be set/changed when running
on Docker, since localhost
is contained within the container:
CACHE_DEFAULT
CACHE_AXES
EMAIL_HOST
SITE_ID
: defaults to1
. The database ID of the site object. You usually won’t have to touch this.DEBUG
: defaults toFalse
. Only set this toTrue
on a local development environment. Various other security settings are derived from this setting!IS_HTTPS
: defaults to the inverse ofDEBUG
. Used to construct absolute URLs and controls a variety of security settings.DB_HOST
: hostname of the PostgreSQL database. Defaults tolocalhost
, unless you’re using thedocker
environment, then it defaults todb
.DB_USER
: username of the database user. Defaults toopennotificaties
, unless you’re using thedocker
environment, then it defaults topostgres
.DB_PASSWORD
: password of the database user. Defaults toopennotificaties
, unless you’re using thedocker
environment, then it defaults to no password.DB_NAME
: name of the PostgreSQL database. Defaults toopennotificaties
, unless you’re using thedocker
environment, then it defaults topostgres
.DB_PORT
: port number of the database, defaults to5432
.NUM_PROXIES
: the number of reverse proxies in front of Open Notificaties, as an integer. This is used to determine the actual client IP adres. Defaults to 1, which should be okay on Kubernetes when using an Ingress.CACHE_DEFAULT
: redis cache address for the default cache. Defaults tolocalhost:6379/0
.CACHE_AXES
: redis cache address for the brute force login protection cache. Defaults tolocalhost:6379/0
.EMAIL_HOST
: hostname for the outgoing e-mail server. Defaults tolocalhost
.EMAIL_PORT
: port number of the outgoing e-mail server. Defaults to25
. Note that if you’re on Google Cloud, sending e-mail via port 25 is completely blocked and you should use 487 for TLS.EMAIL_HOST_USER
: username to connect to the mail server. Default empty.EMAIL_HOST_PASSWORD
: password to connect to the mail server. Default empty.EMAIL_USE_TLS
: whether to use TLS or not to connect to the mail server. Defaults toFalse
. Should beTrue
if you’re changing theEMAIL_PORT
to487
.SENTRY_DSN
: URL of the sentry project to send error reports to. Default empty, i.e. -> no monitoring set up. Highly recommended to configure this.EXTRA_VERIFY_CERTS
: a comma-separated list of paths to certificates to trust, empty by default. If you’re using self-signed certificates for the services that Open Notificaties communicates with, specify the path to those (root) certificates here, rather than disabling SSL certificate verification. Example:EXTRA_VERIFY_CERTS=/etc/ssl/root1.crt,/etc/ssl/root2.crt
.LOG_NOTIFICATIONS_IN_DB
: indicates whether or not sent notifications should be saved to the database (default:False
).
CELERY_BROKER_URL
: the URL of the broker that will be used to actually send the notifications (default:amqp://127.0.0.1:5672//
).CELERY_RESULT_BACKEND
: the backend where the results of tasks will be stored (default:redis://localhost:6379/1
)NOTIFICATION_DELIVERY_MAX_RETRIES
: the maximum number of retries Celery will do if sending a notification failed.NOTIFICATION_DELIVERY_RETRY_BACKOFF
: a boolean or a number. If this option is set toTrue
, autoretries will be delayed following the rules of exponential backoff. If this option is set to a number, it is used as a delay factor.NOTIFICATION_DELIVERY_RETRY_BACKOFF_MAX
: an integer, specifying number of seconds. Ifretry_backoff
is enabled, this option will set a maximum delay in seconds between task autoretries. By default, this option is set to 48 seconds.
The following parameters control the CORS policy.
CORS_ALLOW_ALL_ORIGINS
: allow cross-domain access from any client. Defaults toFalse
.CORS_ALLOWED_ORIGINS
: explicitly list the allowed origins for cross-domain requests. Defaults to an empty list. Example:http://localhost:3000,https://some-app.gemeente.nl
.CORS_ALLOWED_ORIGIN_REGEXES
: same asCORS_ALLOWED_ORIGINS
, but supports regular expressions.CORS_EXTRA_ALLOW_HEADERS
: headers that are allowed to be sent as part of the cross-domain request. By default,Authorization
,Accept-Crs
andContent-Crs
are already included. The value of this variable is added to these already included headers. Defaults to an empty list.
There are two strategies to specify the environment variables:
provide them in a
.env
filestart the Open Notificaties processes (with uwsgi/gunicorn/celery) in a process manager that defines the environment variables
This is the most simple setup and easiest to debug. The .env
file must be
at the root of the project - i.e. on the same level as the src
directory (
NOT in the src
directory).
The syntax is key-value:
SOME_VAR=some_value
OTHER_VAR="quoted_value"
If you use a process manager (such as supervisor/systemd), use their techniques to define the envvars. The Open Notificaties implementation will pick them up out of the box.
Open Notificaties configuration
Before you can work with Open Notificaties after installation, a few settings need to be configured first.
Open Notificaties uses the Autorisaties API to check if the sender is authorized to send notifications. Open Zaak offers an Autorisaties API and below we assume you use this one.
Configure the Open Zaak Autorisaties API endpoint (so Open Notificaties knows where to check for the proper autorisations):
Navigate to Configuratie > Autorisatiecomponentconfiguratie
Fill out the form:
API root: The URL to the Notificaties API. For example:
https://open-zaak.gemeente.local/autorisaties/api/v1/
.Component:
Notificatierouteringcomponent
Click Opslaan.
For a complete example of setting up Open Zaak to send notifications to Open Notificaties, see the documentation of Open Zaak.
Below are the general steps to allow an application to send notifications and using Open Zaak as the example.
Configure the credentials for the Open Zaak Autorisaties API (so Open Notificaties can access the Autorisaties API):
Navigate to API Autorisaties > Externe API credentials
Click Externe API credential toevoegen.
Fill out the form:
API root: The URL of the Open Zaak Autorisaties API endpoint
Label: For example:
Open Zaak Autorisaties
Client ID: For example:
open-notificaties
Secret: Some random string
User ID: Same as the Client ID
User representation: For example:
Open Notificaties
Make sure Open Notificaties is authorized in Open Zaak to access the Autorisaties API by using the same Client ID and Secret as given here.
Click Opslaan.
Finally, we need to allow Open Zaak to access Open Notificaties (for authentication purposes, so we can then check its authorizations):
Navigate to API Autorisaties > Client credentials
Click Client credential toevoegen.
Fill out the form:
Client ID: The same Client ID as given in Open Zaak step 2c
Secret: The same Secret as given in Open Zaak step 2c
Make sure Open Zaak is configured to use this Client ID and secret to access Open Notificaties.
Click Opslaan.
All done!
Using self-signed certificates
Open Notificaties supports self-signed certificates in two ways:
Hosting Open Notificaties using self-signed certificates - this is the classic route where your web server/ingress is configured appropriately
Consuming services hosted with self-signed certificates - this is what this guide is about.
Note
Some background!
Open Notificaties communicates with external services such as Open Zaak, Github and
of course any notification subscribers. It does this using https
- using http is
insecure.
When Open Notificaties makes these requests, the SSL certificates are verified for their validity - e.g. expired certificates or certificates signed by an unkonwn Certificate Authority (CA) will throw errors (as they should!).
When you’re using self-signed certificates, you are essentially using an unkonwn CA, and this breaks the functionality of Open Notificaties.
Adding your own certificates or CA (root) certificate
Open Notificaties supports adding extra, custom certificates to the provided CA bundle. You do
this by setting an environment variable EXTRA_VERIFY_CERTS
, which must be a
comma-separated list of paths to certificate files in PEM format.
An example of such a certificate is:
-----BEGIN CERTIFICATE-----
MIIByDCCAW8CFBRCXMlcdJAPb8XkG4cYMNL+Ku17MAoGCCqGSM49BAMCMGcxCzAJ
BgNVBAYTAk5MMRYwFAYDVQQIDA1Ob29yZC1Ib2xsYW5kMRIwEAYDVQQHDAlBbXN0
ZXJkYW0xEjAQBgNVBAoMCU9wZW4gWmFhazEYMBYGA1UEAwwPT3BlbiBaYWFrIFRl
c3RzMB4XDTIxMDMxOTExMDYyM1oXDTI0MDMxODExMDYyM1owZzELMAkGA1UEBhMC
TkwxFjAUBgNVBAgMDU5vb3JkLUhvbGxhbmQxEjAQBgNVBAcMCUFtc3RlcmRhbTES
MBAGA1UECgwJT3BlbiBaYWFrMRgwFgYDVQQDDA9PcGVuIFphYWsgVGVzdHMwWTAT
BgcqhkjOPQIBBggqhkjOPQMBBwNCAASzDq7C9atfN3uxoAGOCro8RfzWloVusDeO
bwXztxUC/wBu4WgfRsYjg65eVzaJWQKvIKn5W9rGyuIAYbJZJtMZMAoGCCqGSM49
BAMCA0cAMEQCIHKCp4qVEzF3WgaL6jY4tf60HBThnQTaXC99P7TaIFhxAiASMBVV
tmukm/NP8zSMrNpEGLnGIFa8uU/d8VwNNPFhtA==
-----END CERTIFICATE-----
Typically you would do this by (bind) mounting a volume in the Open Notificaties container containing these certificates, and then specify their paths in the container, for example:
docker run \
-it \
-v /etc/ssl/certs:/certs:ro \
-e EXTRA_VERIFY_CERTS=/certs/root1.crt,/certs/root2.crt
openzaak/open-notificaties:latest
Of course, you will need to adapt this solution to your deployment method (Helm, Kubernetes, single-server…).
Post-install checklist
After Open Notificaties has been installed successfully, go through the following checklist to see if the software works as expected:
Check configuration
Check the configuration page for Open Notificaties, accessible at the url
https://open-notificaties.gemeente.nl/view-config/
.
This page will indicate whether certain settings are properly configured.
Manual
Note
The manual is currently only available in the Dutch language!
Once Open Notificaties is installed, it can be further configured via the management interface.
Abonnementen toevoegen
Om te kunnen beginnen met het definiëren van Abonnementen in Open Notificaties, zijn de volgende zaken nodig (naast Open Notificaties zelf):
Een Autorisaties API
Een component dat notificaties kan versturen naar Open Notificaties (in deze handleiding is dit de Autorisaties API)
Een component dat notificaties kan ontvangen via een webhook callback (beveiligd met JWT authenticatie)
Vastleggen credentials
Allereerst moeten de credentials van alle componenten vastgelegd zijn in de Autorisaties API. Het gaat om de volgende credentials:
Er moet een
Applicatie
zijn die Open Notificaties de scopes autorisaties.lezen, notificaties.consumeren en notificaties.publiceren geeft.Er moet een
Applicatie
zijn die de API die notificaties gaat versturen (in dit geval Autorisaties API) de scope notificaties.publiceren geeft.
In het geval dat de Autorisaties API van Open Zaak gebruikt wordt, moeten er ook
Services
aangemaakt worden die gebruik maken van de aangemaakte Applicaties
,
zie Open Zaak documentatie.
Aanmaken kanaal
Vervolgens moet het Kanaal
, waarvoor de notificaties verstuurd gaan worden, aangemaakt worden
in de API van Open Notificaties. In het geval van Autorisaties API heet dit kanaal autorisaties.
In Open Zaak is er een makkelijke manier om kanalen te registreren, zie Open Zaak documentatie over kanalen
Aanmaken abonnement
Warning
Het aanmaken van abonnementen via de admininterface is bedoeld voor debug-doeleinden, idealiter worden abonnementen aangemaakt via de API.
Het abonnement kan aangemaakt worden door in de admininterface van Open Notificaties te navigeren naar Configuratie > Webhook subscriptions > Toevoegen.
Vul vervolgens het formulier in:
Kies bij Config de enige optie, namelijk het endpoint van de Open Notificaties API zelf
Vul bij Callback url de callback URL in van het component dat notificaties moet gaan ontvangen (de abonnee)
Vul bij Client ID het client ID in waarmee het JWT gemaakt wordt dat gebruikt wordt om de callback URL aan te spreken
Vul bij Client secret het client secret in waarmee het JWT gemaakt wordt dat gebruikt wordt om de callback URL aan te spreken
Vul bij Channels de kanalen in waarop geabonneerd moet worden (bijv.
autorisaties
)
Klik vervolgens op de Opslaan knop. Tot slot moet de webhook geregistreerd worden, dit gaat als volgt:
Vink de aangemaakte Webhook subscription aan in de lijst,
Klik op het dropdown menu Acties en selecteer
Register the webhooks
Klik op Uitvoeren
Vanaf nu zullen alle notificaties voor het gekozen Kanaal
doorgestuurd worden naar de geconfigureerde webhook.
Filters instellen
Per abonnement kunnen filteropties ingesteld worden, waarmee gefilterd kan worden op waardes van kenmerken
die meegegeven worden met de notificaties. De kenmerken waarop gefilterd kan worden zijn gedefinieerd per
kanaal, bijvoorbeeld: kenmerken voor het kanaal zaken
.
Filters kunnen toegevoegd worden aan abonnementen door in de admininterface van Open Notificaties te navigeren naar Notificaties > Abonnementen.
Klik op de UUID van het abonnement waarvoor filters toegevoegd moeten worden
Klik onder het kopje Filters op Nog een Filter toevoegen
Selecteer het kanaal waarvoor dit filter geldt (bijv.
zaken
) en klik op Opslaan en opnieuw bewerkenKlik vervolgens voor het aangemaakte filter onder Acties op Filters instellen
Klik onder het kopje Filter-onderdelen op Nog een filter-onderdeel toevoegen en vul in:
Sleutel: de naam van het kenmerk (bijv.
bronorganisatie
)Waarde: de waarde waarop gefilterd moet worden (bijv.
123456789
)
Klik op Opslaan
Vanaf nu worden notificaties voor het gekozen kanaal alleen verstuurd naar de geabonneerde callback als de waarde van het gekozen kenmerk van deze notificaties gelijk is aan de instelde waarde.
Note
Om voor hetzelfde kenmerk te filteren op meerdere waardes, moeten er een nieuw Filter toegevoegd worden per waarde (volgens de bovenstaande stappen)
Handmatig notificaties versturen
Via de admininterface van Open Notificaties kunnen ook handmatig notificaties aangemaakt en verstuurd worden. Dit kan handig zijn om notificaties en abonnementen te testen.
Notificaties versturen
Een nieuw notificatie aanmaken in de admininterface van Open Notificaties gaat als volgt:
Navigeer naar Notificaties > Notificaties > Toevoegen
Vul bij Forwarded msg het te versturen bericht in JSON formaat in, dit kan er als volgt uitzien:
{ "actie": "create", "kanaal": "objecten", "resource": "object", "kenmerken": {"objectType": "https://example.com"}, "hoofdObject": "https://example.com", "resourceUrl": "https://example.com", "aanmaakdatum": "2022-04-02T09:00:00Z" }
Selecteer bij Kanaal het kanaal waarvoor de notificatie gestuurd moet worden
Klik vervolgens op Opslaan, de nieuwe notificatie zal verschijnen bovenin de lijst
Klik op de notificatie, en zie de responses van de geabonneerde callbacks onder het kopje Notificatie responses
Bestaande notificaties opnieuw versturen
Het is ook mogelijk om bestaande notificaties opnieuw te versturen, dit kan handig zijn als het sturen van een notificatie eerder gefaald is bijvoorbeeld. Een bestaande notificatie opnieuw versturen in de admininterface van Open Notificaties gaat als volgt:
Navigeer in de admininterface naar Notificaties > Notificatie
Vink de notificatie of notificaties aan die verstuurd moeten worden
Selecteer vervolgens bij Actie Re-send the selected notifications en klik op Uitvoeren
Kijk per verzonden notificatie of deze nu wel goed zijn aangekomen bij de geabonneerde callbacks
ADFS (On premise) being removed
Warning
The ADFS integration is being removed. Instead you can use the generic OpenID Connect integration. Open Notificaties automatically migrates your ADFS/AAD configuration to the generic OIDC configuration.
Note that you should update your application Redirect URI in ADFS/AAD - the path
/adfs/callback
should be changed into /oidc/callback
.
Open Notificaties 1.4.0 provides a redirect from the old to the new URL, which will be removed in Open Notificaties 1.5.0.
Uninstalling
The uninstaller can be run from Open Notificaties 1.5.0 onwards, after we have removed the external dependencies.
$ docker exec opennotificaties-0 /app/bin/uninstall_adfs.sh
BEGIN
DROP TABLE
DELETE 3
COMMIT
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
cache-79455b996-jxk9r 1/1 Running 0 2d9h
opennotificaties-7b696c8fd5-hchbq 1/1 Running 0 2d9h
opennotificaties-7b696c8fd5-kz2pb 1/1 Running 0 2d9h
$ kubectl exec opennotificaties-7b696c8fd5-hchbq -- /app/bin/uninstall_adfs.sh
BEGIN
DROP TABLE
DELETE 3
COMMIT
OpenID Connect configureren
Open Notificaties ondersteunt Single Sign On (SSO) via het OpenID Connect protocol (OIDC) voor de beheerinterface.
Gebruikers kunnen op die manier inloggen op Open Notificaties met hun account bij de OpenID Connect provider. In deze flow:
Klikt een gebruiker op het inlogscherm op Inloggen met organisatieaccount
De gebruiker wordt naar de omgeving van de OpenID Connect provider geleid (bijv. Keycloak) waar ze inloggen met gebruikersnaam en wachtwoord (en eventuele Multi Factor Authentication)
De OIDC omgeving stuurt de gebruiker terug naar Open Notificaties (waar de account aangemaakt wordt indien die nog niet bestaat)
Een beheerder in Open Notificaties kent de juiste groepen toe aan deze gebruiker als deze voor het eerst inlogt.
Note
Standaard krijgen deze gebruikers geen toegang tot de beheerinterface. Deze rechten moeten door een (andere) beheerder ingesteld worden. De account is wel aangemaakt.
Configureren van OIDC zelf
Contacteer de IAM beheerders in je organisatie om een Client aan te maken in de omgeving van de OpenID Connect provider.
Voor de Redirect URI vul je https://open-notificaties.gemeente.nl/oidc/callback
in,
waarbij je open-notificaties.gemeente.nl
vervangt door het relevante domein.
Aan het eind van dit proces moet je de volgende gegevens hebben (on premise):
Server adres, bijvoorbeeld
login.gemeente.nl
Client ID, bijvoorbeeld
a7d14516-8b20-418f-b34e-25f53c930948
Client secret, bijvoorbeeld
97d663a9-3624-4930-90c7-2b90635bd990
Configureren van OIDC in Open Notificaties
Zorg dat je de volgende gegevens hebt:
Server adres
Client ID
Client secret
Navigeer vervolgens in de admin naar Configuratie > OpenID Connect configuration.
Vink Enable aan om OIDC in te schakelen.
Vul bij OpenID Connect client ID het Client ID in, bijvoorbeeld
a7d14516-8b20-418f-b34e-25f53c930948
.Vul bij OpenID Connect secret het Client secret in, bijvoobeeld
97d663a9-3624-4930-90c7-2b90635bd990
.Laat bij OpenID Connect scopes de standaardwaarden staan.
Vul bij OpenID sign algorithm
RS256
in.Laat Sign key leeg.
Vervolgens moeten er een aantal endpoints van de OIDC provider ingesteld worden,
deze kunnen automatisch bepaald worden aan de hand van het discovery endpoint
(https://login.gemeente.nl/auth/realms/{realm}/.well-known/openid-configuration
).
Vul bij Discovery endpoint het pad naar het juiste authenticatie realm endpoint van de OpenID Connect provider in (met een
/
op het einde). Voor provider-specifieke hints, zie Providersreferentie.Laat de overige endpoints leeg.
Klik tot slot rechtsonder op Opslaan.
Je kan vervolgens het makkelijkst testen of alles werkt door in een incognitoscherm naar https://open-notificaties.gemeente.nl/admin/ te navigeren en op Inloggen met OIDC te klikken.
Providersreferentie
ADFS (on premise)
For on premise ADFS, the discovery URL usually has the form
https://login.gemeente.nl/adfs/.well-known/openid-configuration
.
Azure AD
Azure Active Directory is a cloud-hosted identity provider from Microsoft, part of Azure webservices.
To use AAD as OIDC provider, you require a Tenant ID, usually in the same of a UUID v4.
This tenant ID is used in the discovery URL, having the form
https://login.microsoftonline.com/${tenantId}/v2.0
.
Keycloak
Keycloak is a multi-tenant IDP which itself can configure other IDPs.
To use Keycloak, you need to know your relevant realm
. The discovery URL has the form
https://keycloak.gemeente.nl/auth/realms/${realm}/.well-known/openid-configuration
.
Other
You may also find some configuration hints for other Identity Providers using OIDC in the NLX Reference documentation: https://docs.nlx.io/reference-information/oidc
Support
Development is done separately from any support or service that you might need to install, use, implement or integrate Open Notificaties.
What kind of support do you need?
Need help with the installation? Contact a service provider!
Found a bug? Please create an issue on Github!
Want to contribute? See Development (TODO)!
Service providers
Below is a list of service providers.
Want to be mentioned here? Please create a Pull Request on Github to add your company.
Delivery guarantees
Mechanism
The Notificaties API standard (and by extension Open Notificaties) operates on a simple yet powerful message delivery mechanism: webhooks.
A webhook, in essence, is nothing more than and HTTP endpoint exposed by a server where HTTP requests/messages can be sent to. Upon receiving such a request, the webhook receiver is responsible for processing the content of this request appropriately.
Webhooks are registered by parties interested in receiving notifications. The webhook
registration is recorded and saved in Open Notificaties. Whenever (another) party
publishes a notification, it does so by making a HTTP POST
call to the Open
Notificaties API. Open Notificaties, in turn, checks which parties should receive this
notification and forwards the message to the registered webhook.
Failure modes
Even though the mechanism is simple, the underlying infrastructure is not. There is always a chance that a message does not get properly delivered - a problem that all message broker systems have.
The Notificaties API standard defines that recipients of a message/notification have to reply with a HTTP 204 status code to confirm that the message was received. However, to complicate things further, this confirmation response may also be lost. To summarize, the following scenarios are possible:
Open Notificaties delivers message and receives confirmation (happy flow)
Open Notificaties delivers message but does not receive a confirmation (failure mode)
Open Notificaties fails to deliver the message successfully (failure mode)
Now there are essentially two mitigation modes available:
at-most-once delivery
at-least-once delivery
Delivering a message exactly once is not possible since the underlying infrastructure (“the internet”) may fail for whatever reason.
Mitigations
Open Notificaties operates in “at-least-once” delivery mode. This means that whenever a delivery attempt succeeds, no more delivery attempts are made and whenever no confirmation is received, another delivery attempt will be made.
A failure can be in the form of an HTTP status code that does not indicate
success
(so anything other than HTTP 200
, HTTP 201
, HTTP 202
, HTTP 204
) or
network errors such as connection or timeout errors (or anything else going wrong). In
practice, Open Notificaties will consider any 2xx
response status code as
“message is delivered, no further attempts must be made”.
Note
Webhook subscribers must be able to handle multiple deliveries of the same message! If they received a message correctly but failed to reply with a success response, Open Notificaties will deliver the same message again.
Retry mechanism
On delivery failure, Open Notificaties will automatically retry delivery, with exponential backoff. E.g. the first retry will be done after one second, the next after two seconds and the third after 4 seconds.
The parameters for this can be configured:
NOTIFICATION_DELIVERY_MAX_RETRIES
: the maximum number of automatic retries. After this amount of retries, Open Notificaties stops trying to deliver the message.NOTIFICATION_DELIVERY_RETRY_BACKOFF
: if specified, a factor applied to the exponential backoff. This allows you to tune how quickly automatic retries are performed.NOTIFICATION_DELIVERY_RETRY_BACKOFF_MAX
: an upper limit to the exponential backoff time.
On top of that, via the admin interface you can manually select notifications to retry delivery for.
Open Notificaties message broker
Under the hood, notifications are distributed by background workers to ensure API endpoint availability. For this we rely on RabbitMQ as internal message broker between the API and background workers.
RabbitMQ is excellent in terms of message guarantees and can survive restarts. However, configuring RabbitMQ for these kind of operation modes is in the scope of the infrastructure you are running Open Notificaties on. We advise you to configure the persistent storage appropriately for maximum robustness.
The results and metadata of the background tasks are stored in Redis, which is an in-memory key-value store. Redis can be used as a message broker too, but Open Notificaties only uses it as a cache and result store - RabbitMQ is the message broker. However, you can also configure Redis appropriately so that it saves snapshots to disk according to your reliability requirements. This also requires you to provide Redis with a suitable persistent storage.
Task metadata is important for keeping track of automatic delivery retries, so it is recommended to set up Redis as a highly-available and/or persistent storage.
Development (TODO)
Open Notificaties is open-source software. We’d love to have you contribute!
Contributing
Development environment
Performance
Performance is measured using different types of scenarios.
Measuring performance
Goal
The purpose of performance measurements is to gain insight into the relationships between system requirements, number of users and response times of the API’s. From these relationships we can draw up the minimum system requirements, depending on the number of users, on which the API’s still perform acceptable.
A standardized performance measurement also provides insight into which effect various optimizations have.
Technical test scenarios
There’s basically just one API-call that will be called often and that’s to send a notification. The other API-calls are neglible. The API-call (request) is measured to gain insights in the technical performance.
Notificaties API
Create NOTIFICATIE (
POST /api/v1/notificaties
)
A scenario in this test specification is equal to an API-call (request). Each API resource is continuously without any delay, or waiting time, between each request. This way, we can determine the maximum number of requests per second and average response times.
We test with an increasing number of virtual users, from 1 to 100, that concurrently execute the test scenarios. A virtual user is technically a script that executes the different scenarios one after another. This way, we see the number of virtual users that concurrently access the API’s and its impact on performance.
There’s not test data involved.
Changes
1.4.3 (2022-07-15)
Fixed a number of bugs introduced in the 1.4.x series
Accept 20x status codes from subscriber callbacks instead of only HTTP 204
Bumped to vng-api-common 1.7.8 for future feature development
[open-zaak/open-zaak#1207] Bumped to Django security release
[#78] Added missing bleach dependency
1.4.2 (2022-07-01)
Fixed a crash when using the OIDC integration.
Thanks @damm89 for reporting this and figuring out the cause!
1.4.1 (2022-06-24)
Bugfix release following 1.4.0
Fixed missing migration file for conversion from ADFS library to OpenID Connect library
Fixed the CI build not producing
latest
image tags correctly
1.4.0 (2022-05-03)
New features
Implemented automatic delivery retry mechanism on failure (#1132)
You can now manually (re)-send notifications from the admin interface (#1135)
Improved admin interface for notifications (#1133)
Documentation
document Open Notificaties message delivery guarantees (#1151)
described subscription filters in docs (#1134)
Project maintenance
Replace ADFS library with generic OpenID Connect library - please see the notes below! (#1139)
Upgraded Python version from 3.7 to 3.9
Upgraded to Django 3.2.13 (#1136)
Warning
Manual intervention required for ADFS/AAD users.
Open Notificaties replaces the ADFS/Azure AD integration with the generic OIDC integration. On update, Open Notificaties will attempt to automatically migrate your ADFS configuration, but this may fail for a number of reasons.
We advise you to:
back up/write down the ADFS configuration BEFORE updating
verify the OIDC configuration after updating and correct if needed
Additionally, on the ADFS/Azure AD side of things, you must update the Redirect URIs:
https://open-notificaties.gemeente.nl/adfs/callback
becomes
https://open-notificaties.gemeente.nl/oidc/callback
.
In release 1.5.0 you will be able to finalize the removal by dropping the relevant tables.
1.3.0 (2022-03-28)
New features
Upgraded to Django 3.2 LTS version (#1124)
Confirmed support for PostgreSQL 13 and 14
Project maintenance
Upgraded a number of dependencies to be compatible with Django 3.2 (#1124)
Warning
Manual intervention required!
Admin panel brute-force protection
Due to the ugprade of a number of dependencies, there is a new environment variable
NUM_PROXIES
which defaults to 1
which covers a typical scenario of deploying
Open Notificaties behind a single (nginx) reverse proxy. On Kubernetes this is
typically the case when using an ingress. Other deployment layouts/network topologies
may require tweaks if there are additional load balancers/reverse proxies in play.
Failing to specify the correct number may result in:
login failures/brute-force attempts locking out your entire organization because one of the reverse proxies is now IP-banned - this happens if the number is too low.
brute-force protection may not be operational because the brute-forcer can spoof their IP address, this happens if the number is too high.
1.2.3 (2021-12-17)
Fixed a container image bug
MIME-types of static assets (CSS, JS, SVG…) were not properly returned because of
the container base image not having the /etc/mime.types
file.
1.2.2 (2021-12-07)
Fixed a bug allowing for empty kenmerk values in notifications.
1.2.1 (2021-09-20)
Open Notificaties 1.2.1 fixes a resource leak. See the below info box for more details.
Note
Notifications are delivered to subscriptions via asynchronous background workers. These background tasks were incorrectly storing the execution metadata and result in the backend without consuming/ pruning them from the result store. The symptoms should have been fixed with the 1.2.0 release where the default backend is switched to Redis instead of RabbitMQ (which normally does evict keys after a certain timeout) - but this release fixes the root cause. Result and metadata are now no longer stored.
1.2.0 (2021-09-15)
Fixes
Fixed the webserver and background worker processes not having PID 1
Containers now run as un-privileged user rather than the root user (open-zaak/open-zaak#869)
Added Celery Flower to the container images for background worker task monitoring
New features
Added support for generic OpenID Connect admin authentication (open-zaak/open-zaak#1034)
1.1.5 (2021-04-15)
Bugfix release
Bumped ADFS libraries to support current state of Azure AD
Fixed issue with self-signed certificates loading
1.1.4 (2021-03-25)
Quality of life release
Updated to pip-tools 6 internally for dependency management
Bumped Django and Jinja2 dependencies to get their respective bug- and security fixes
Added support for self-signed (root) certificates, see the documentation on readthedocs for more information.
Clarified version numbers display in footer
1.1.3 (2021-03-17)
Bugfix release fixing some deployment issues
Fixed broken
STATIC_URL
andMEDIA_URL
settings derived fromSUBPATH
. This should fix CSS/Javascript assets not loading inRemoved single-server documentation duplication (which was outdated too)
Removed
raven test
command from documentation, it was removed.Made CORS set-up opt-in
1.1.2 (2020-12-17)
Quality of life release, no functional changes.
Updated deployment tooling to version 0.10.0. This adds support for CentOS/RHEL 7 and 8.
Migrated CI from Travis CI to Github Actions
Made PostgreSQL 10, 11 and 12 support explicit through build matrix
1.1.1 (2020-11-09)
Small quality of life release.
Updated documentation links in API Schema documentation
Added missing Redis service to
docker-compose.yml
Fixed
docker-compose.yml
(Postgres config, session cache…)Fixed version var in deploy config
Fixed settings/config for hosting on a subpath
Added management command for initial Open Notificaties setup (
setup_configuration
)Fixed broken links in docs
Bumped dev-tools isort, black and pip-tools to latest versions
Fixed tests by mocking HTTP calls that weren’t mocked yet
Fixed handling HTTP 401 responses on callback auth validation. Now both 403 and 401 are valid responses.
1.1.0 (2020-03-16)
Feature and small improvements release.
Note
The API remains unchanged.
Removed unnecessary sections in documentation
Updated deployment examples
Tweak deployment to not conflict (or at least less likely :-) ) with Open Zaak install Open Zaak and Open Notificaties on the same machine are definitely supported
Added support for ADFS Single Sign On (disabled by default)
Added documentation build to CI
1.0.0 final (2020-02-07)
🎉 First stable release of Open Notificaties.
Features:
Notificaties API implementation
Tested with Open Zaak integration
Admin interface to view data created via the APIs
Scalable notification delivery workers
NLX ready (can be used with NLX)
Documentation on https://open-notificaties.readthedocs.io/
Deployable on Kubernetes, single server and as VMware appliance
Automated test suite
Automated deployment