# Receiving CloudEvents

This page will help you set up your system to receive events from BankID Antifraud.

## Integration steps

### 1. Provide the required information

Start by providing BankID with the full webhook URL where you want to receive the events.

> **Requirements for your webhook URL**
>
> - Must be publicly accessible from the internet via HTTPS
> - Must accept both `POST` and `OPTIONS` requests

### 2. Validate subscription

When we create the subscription, a validation request will be sent to your URL via an HTTP `OPTIONS` call.

The request will include the header `WebHook-Request-Origin` containing a DNS expression identifying the sending system. This will be set to `eventgrid.azure.net`.

To accept the subscription, respond with:

- **HTTP Status**: `200`
- **Headers**:

| Header                   | Value                                                           |
| ------------------------ | --------------------------------------------------------------- |
| `WebHook-Allowed-Origin` | Same value as `WebHook-Request-Origin` or `*`                   |
| `WebHook-Allowed-Rate`   | `*` (no rate limit) or a positive integer (requests per minute) |

> **Code example (Kotlin/Ktor)**
>
> ```kotlin
> route("/bankid-antifraud-event") {
>     options {
>         call.response.headers.apply {
>             append("WebHook-Allowed-Origin", "eventgrid.azure.net")
>             append("WebHook-Allowed-Rate", "100")
>             append(HttpHeaders.Allow, "POST")
>         }
>         call.respond(HttpStatusCode.OK)
>     }
>     authenticate("jwt") {
>         post { handleAntifraudEvent() }
>     }
> }
> ```

### 3. Receive events

Events are delivered as HTTP `POST` requests. For successful delivery, respond with one of the following status codes:

| Status Code                       | Result                                   |
| --------------------------------- | ---------------------------------------- |
| `200`, `201`, `202`, `203`, `204` | Success - event delivered                |
| `400`, `401`, `403`, `404`, `413` | Failure - no retry                       |
| Other codes                       | Failure - retry with exponential backoff |

### 4. Handle CloudEvents

Events are delivered in the [CloudEvents](https://cloudevents.io/) format. Here's an example request:

```http
POST /your-subscription HTTP/1.1
Host: webhook.example.com
Content-Type: application/cloudevents+json; charset=utf-8
Content-Length: nnnn
Authorization: Bearer <token>

{
  "specversion": "1.0",
  "type": "no.bankid.antifraud.alarm.dispatch.v2",
  "source": "...",
  "id": "...",
  "time": "...",
  "data": {
    ... alarm data ...
  }
}
```

> **Always check the event type**
>
> Always verify the `type` field before processing the event. This ensures your system can handle new event types gracefully when they are introduced.

The domain-specific data (the alarm) will be in the `data` field.

### 5. Authenticate requests

The service uses JSON Web Tokens (JWT) issued by Microsoft Entra ID to authorize requests. Each `POST` request includes a JWT in the `Authorization` header using the Bearer scheme.

Verify the token using:

| Parameter  | Value                                                                                        |
| ---------- | -------------------------------------------------------------------------------------------- |
| JWT Issuer | `https://login.microsoftonline.com/08a02467-3604-46e9-b818-6be676cf015b/v2.0`                |
| JWK URL    | `https://login.microsoftonline.com/08a02467-3604-46e9-b818-6be676cf015b/discovery/v2.0/keys` |

> **Audience claim**
>
> Make sure to also verify the `aud` (audience) claim in the JWT.

## Troubleshooting

### Subscription validation fails

If the subscription validation fails, check the following:

- [ ] Firewalls are open for incoming requests
- [ ] The `OPTIONS` handler does not check the `Authorization` header (it will not be set during validation)
- [ ] Your endpoint accepts the `Content-Type: application/cloudevents+json; charset=utf-8`

## Further documentation

For more information about the underlying technologies, refer to:

- [Azure Event Grid](https://learn.microsoft.com/en-us/azure/event-grid/)
- [Endpoint validation with Azure Event Grid](https://learn.microsoft.com/en-us/azure/event-grid/webhook-event-delivery)
- [Event Grid CloudEvents Schema](https://learn.microsoft.com/en-us/azure/event-grid/cloud-event-schema)
- [Webhook delivery with Azure AD](https://learn.microsoft.com/en-us/azure/event-grid/secure-webhook-delivery)
