Check pipelines

You can add check pipelines to request units to perform checks on incoming requests. check pipelines needs only to explicitly green-light the incoming request, otherwise an error is returned to the caller without executing the main pipeline.

check pipelines can also be used to contribute to the rate limiting and access control features of Xapix.

Check Pipeline Protocol

A check pipeline needs to adhere to the following data structure:

result.pass - Boolean, required
result.error.body - String, optional; error body
result.error.status - Integer, optional; http error status

In case result.pass is set to false (or undefined), an error is returned to the user. If result.error.body and/or result.error.status are set, those are used to create the error response. In case multiple check pipelines fail and provide an error body / status, one of them is picked. It's recommended to always define both, error body and status. If no error body or status is defined, a 401 with the body "Access denied." is returned.

In case result.pass is set to true for all check pipelines, the request is allowed to proceed.

Custom Authentication Pipeline

The check pipeline can also be used to authenticate users, and pass details about the user back to the main pipeline. The result can also be used with the rate limiting and access control features of Xapix.

To use the rate limiting and access control features with check pipelines, you first need to set the user management to custom (see examples section below).

And one of the check pipeline needs to return the following data structure, with result.pass set to true in case the authorization passed:

result.pass - Boolean, required
result.user.id - String; user id to be used for rate limiting
result.user.roles - Array of Strings; roles to be used for access control and rate limiting

The result.user.id needs to be unique per user, and will be used to rate limit access as defined in the users' roles.

The result.user.roles needs to list the user's roles, which are used to control access and enforce rate limits as defined by those roles. The roles are looked up by their id. If the user has no roles or no matching roles, access will be denied.

Examples

Smallest Check Pipeline

For an easy example, let's assume you want to require basic authentication to be present, and otherwise deny access. In that case you could use the following check pipeline:

---
version: v1
kind: Pipeline
metadata:
id: simple-check
project: simple-check
definition:
units:
- version: v1
kind: Unit/Entry
metadata:
id: entry
definition:
name: Entry
parameters:
- name: header
type: object
properties:
- name: Authorization
type: string
sample: Basic dGVzdDp0ZXN0
- version: v1
kind: Unit/Result
metadata:
id: result
definition:
name: Result
inputs:
- entry
parameters:
- name: result
type: object
properties:
- name: pass
type: boolean
formula: "entry.header.Authorization = 'Basic dGVzdDp0ZXN0'"

The request pipeline would then look like this:

---
version: v1
kind: Endpoint/REST
metadata:
id: test
project: simple-check
definition:
name: test
path: test
httpMethod: get
pipeline:
units:
- version: v1
kind: Unit/Request
metadata:
id: request
definition:
name: Request
parameters:
- name: header
type: object
properties:
- name: Authorization
type: string
checkPipelines:
- simple-check
- version: v1
kind: Unit/Endpoint
metadata:
id: endpoint
definition:
name: Endpoint
inputs:
- request
parameters:
- name: body
type: object
properties:
- name: status
formula: '"ok"'

Note the checkPipelines in the Unit/Request resource which references the simple-check pipeline defined above.

Check Pipeline for Authentication, Rate Limiting and Access Controls

To switch a project to use a custom check pipeline for authentication, and to use rate limiting and access controls, apply the following ApiPublishing resource definition to switch user management to custom

---
version: v1
kind: ApiPublishing
metadata:
id: <project-id>
definition:
enabled: true
userManagement: custom

Then adjust the check-pipeline above to return result.user.id and result.user.roles.