Webhook Post-Auth - Extensions - Idura Verify Documentation
  1. Verify
  2. Extensions
  3. Webhook Post-Auth

Webhooks allow you to hook into the Idura Verify login lifecycle directly to implement custom authentication logic and integrate with other systems. Webhooks can be implemented in any programming language of your choice.

Example use cases include:

  • Fetching additional claims from a CX or CIAM system and adding them to the Idura Verify token
  • Redirecting users to accept terms on your website before continuing the login flow

Configuration

  • url: URL where your Webhook is hosted. Must be HTTPS. Subpaths are supported.
    ex. https://your.domain/webhook/invoke
  • claim_whitelist: List of OpenID Connect Standard claims your webhook can set. By default, webhooks are disallowed from setting non-namespaced claims for security reasons.
    ex. ['address', 'email', 'phone_number']

Requests

Your webhook will be invoked with an application/json body and an Authorization: Bearer <token> header (see Security).

There is two types of events your webhook will receive:

  • post-auth: A post-auth event is sent when a user has successfully completed a login with a eID provider. In response to a post-auth event you can add or remove claims, abort the login process or redirect the user to another webpage.
  • post-auth-resume: A post-auth-resume event is sent when a user was redirected in response to a 'post-auth' event and has been redirected back to Idura Verify. In response to a post-auth event you can add or remove claims or abort the login process.

Common Properties

  • event: Identifying the type of event (post-auth-event-1.0 or post-auth-resume-event-1.0)
  • conversationId: Unique ID per-login. Can be used as a key to store session state between post-auth and post-auth-resume.
  • environment: Either test or production.

Post-Auth Example

{
  "event": "post-auth-event-1.0",
  "conversationId": "e926e5da4c8d428e8c4f36d88060459e",
  "environment": "test",
  "user": {
    "identityscheme": "sebankid",
    "sub": "{ba8568cb-e9f4-4d1c-a9a5-814462641bdc}",
    "...": "eID specific"
  },
  "resumeUrl": "https://extensions.criipto.com/extension/resumePostAuth?..."
}

The user field will always contain a sub entry uniquely identifying a user. Additional properties are eID-specific. You can find examples of the JWT token formats on the eID provider pages.

The resumeUrl field is used when redirecting the user to another webpage or service. Once the user is done interacting with that page, they should be redirected to this url to trigger the post-auth-resume event and continue the login flow.

Post-Auth-Resume Example

Your webhook will be invoked with a post-auth-resume event once the user has been redirected to the resumeUrl of the initial post-auth request.

{
  "event": "post-auth-resume-event-1.0",
  "conversationId": "e926e5da4c8d428e8c4f36d88060459e",
  "environment": "test",
  "resumeRequest": {
    "url": "..."
  }
}

To persist state between the post-auth and post-auth-resume events, conversationId should be used as a session identifier.

Responses

No-op response

The webhook should respond with HTTP status code 204 if it wishes to make no modifications to the login flow.

Adding/Removing Claims

The webhook should respond with HTTP status code 200 if it wishes to add or remove claims to the issued login token. The response body should be application/json encoded and contain a claimsOperations key containg a key-value map.

Below is a non-normative example response:

{
  "claimsOperations": {
    "$set": {
      "https://customer.com/namespace/key": "value",
      "https://customer.com/namespace/complex": {
        "key": "value"
      }
    },
    "$remove": {
      "key": "value"
    }
  }
}

Redirect response

The webhook should respond with HTTP status code 303 and a Location header indicating where the user should be redirected to. After the redirect, the login process is effectively paused. To resume the process the user must be redirected back to resumeUrl, at which point your webhook will be invoked again with a post-auth-resume event.

Security

All webhook invocations by Criipto will include an Authorization: Bearer <token> header. The token must be validated on all requests to ensure the authenticity of the HTTP request.

Example token format

{
  "jti": "90fb519d-6d64-4646-a02c-39b4833d61b2",
  "iss": "https://extensions.criipto.com/service",
  "sub": "e1369c3702d344e38e2cbc3fcb947e01",
  "aud": "ext_test_webhook_postauth_03028258"
}

Token validation

  • Perform standard token validation against JWKS from https://extensions.criipto.com/service/.well-known/jwks
  • Validate nbf and exp as usual
  • Validate that iss is https://extensions.criipto.com/service
  • Validate that sub matches your tenant id
  • Validate that aud matches your extension id

Replay attacks

The bearer token contains a jti that must be checked against a store to guard against replay attacks. If jti reuse is detected the webhook request MUST be rejected.

Shared responsibility model

Responsibilities of Criipto

  • Criipto secures the boundary between Criipto Verify, the extension executor service and the webhook executor service
  • Criipto ensures that webhook response bodies are never logged
  • Criipto ensures that webhooks are always invoked with a fresh bearer token

Responsibilities of customer

  • Customer must perform token validation on each request
  • Customer must perform replay attack detection on each request
  • Customer must ensure that no request payloads are logged

Schemas

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://criipto.com/extensions/webhook/post-auth-request.1.0.schema.json",
  "title": "PostAuthWebhookExtension10Request",
  "type": "object",
  "required": [
    "method",
    "headers",
    "body"
  ],
  "additionalProperties": false,
  "properties": {
    "method": {
      "type": "string",
      "enum": [
        "POST"
      ]
    },
    "headers": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "Authorization",
        "Content-Type"
      ],
      "properties": {
        "Authorization": {
          "type": "string"
        },
        "Content-Type": {
          "type": "string",
          "enum": [
            "application/json"
          ]
        }
      }
    },
    "body": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "event",
        "conversationId",
        "environment",
        "user",
        "resumeUrl"
      ],
      "properties": {
        "event": {
          "type": "string",
          "enum": [
            "post-auth-event-1.0"
          ]
        },
        "conversationId": {
          "type": "string",
          "description": "Random ID identifying this particular login session. Should be used as a session key to persist state between post-auth and post-auth-resume."
        },
        "environment": {
          "type": "string",
          "enum": [
            "test",
            "production"
          ]
        },
        "user": {
          "type": "object",
          "additionalProperties": true,
          "required": [
            "sub"
          ],
          "properties": {
            "sub": {
              "type": "string"
            }
          }
        },
        "resumeUrl": {
          "type": "string",
          "description": "If the webhook responds with a redirect, the login process is effectively paused until the user is directed back to this URL, at which point the webhook will receive a post-auth-resume event."
        }
      }
    }
  }
}