Authentication

The RxInferServer uses token-based authentication to secure access to its endpoints. This guide explains how to obtain and use authentication tokens, understand token roles, and manage model access.

Overview

Most endpoints in RxInferServer require authentication, with a few exceptions. The authentication system is based on tokens and follows the Bearer token scheme. All authentication-related endpoints are grouped under the Authentication tag in the OpenAPI specification.

Getting Started with Authentication

Obtaining a Token

To authenticate with the server, you first need to obtain a token using the token_generate operation. This endpoint supports both user authentication and API key authentication.

import RxInferClientOpenAPI
import RxInferClientOpenAPI.OpenAPI.Clients: Client
import RxInferClientOpenAPI: AuthenticationApi, token_generate, basepath

url          = basepath(AuthenticationApi)
client       = Client(url)
api          = AuthenticationApi(client)
response, _  = token_generate(api)

response.token
"d55edce9-c63a-400d-899e-a75a7679b6cc"
Development Mode

During development, you can enable the development mode by setting the RXINFER_SERVER_ENABLE_DEV_TOKEN environment variable to true.

Using the Token

Once you have obtained a token, you need to include it in the Authorization header of your requests. The token should be prefixed with Bearer as shown below:

import RxInferClientOpenAPI.OpenAPI.Clients: set_header

set_header(client, "Authorization", "Bearer $(response.token)")
"Bearer d55edce9-c63a-400d-899e-a75a7679b6cc"
Token Security
  • Keep your tokens secure and private
  • Store tokens in a secure location
  • Never expose tokens in client-side code or version control
  • Implement proper token rotation and management in production
  • Remember that models are associated with the token used to create them

Understanding Token Roles

Viewing Token Roles

Each token comes with a set of assigned roles that determine its access permissions. You can retrieve the roles associated with your token using the token_roles operation:

import RxInferClientOpenAPI: token_roles

response, _ = token_roles(api)

response.roles
1-element Vector{String}:
 "user"

Model Access and Roles

Roles control which models a token can access. Here's how to list accessible models:

import RxInferClientOpenAPI: ModelsApi, get_available_models

models_api = ModelsApi(client)
available_models, _ = get_available_models(models_api)

available_models
3-element Vector{RxInferClientOpenAPI.AvailableModel}:
 {
  "details": {
    "name": "BetaBernoulli-v1",
    "description": "A simple Beta-Bernoulli model",
    "author": "Lazy Dynamics",
    "roles": [
      "user"
    ]
  },
  "config": {
    "name": "BetaBernoulli-v1",
    "author": "Lazy Dynamics",
    "arguments": [
      {
        "name": "prior_a",
        "default": 1,
        "required": true,
        "description": "The initial alpha parameter of the prior Beta distribution `p`",
        "type": "int"
      },
      {
        "name": "prior_b",
        "default": 1,
        "required": true,
        "description": "The initial beta parameter of the prior Beta distribution `p`",
        "type": "int"
      }
    ],
    "parameters": [
      {
        "name": "posterior_a",
        "description": "The posterior parameter `a` of the Beta distribution"
      },
      {
        "name": "posterior_b",
        "description": "The posterior parameter `b` of the Beta distribution"
      }
    ],
    "data": [
      {
        "name": "observation",
        "required": true,
        "description": "A single `1` or `0` value indicating the outcome of a Bernoulli trial",
        "type": "int"
      }
    ],
    "roles": [
      "user"
    ],
    "description": "A simple Beta-Bernoulli model"
  }
}

 {
  "details": {
    "name": "Drone3D-v1",
    "description": "A 3D drone model",
    "author": "Lazy Dynamics",
    "roles": [
      "user"
    ]
  },
  "config": {
    "name": "Drone3D-v1",
    "author": "Lazy Dynamics",
    "arguments": [
      {
        "name": "dt",
        "default": 0.05,
        "required": true,
        "description": "The time step of the drone",
        "type": "float"
      },
      {
        "name": "horizon",
        "default": 40,
        "required": true,
        "description": "The horizon of the drone",
        "type": "int"
      },
      {
        "name": "gravity",
        "default": 9.81,
        "required": true,
        "description": "The gravity of the environment",
        "type": "float"
      },
      {
        "name": "mass",
        "default": 1.0,
        "required": true,
        "description": "The mass of the drone",
        "type": "float"
      },
      {
        "name": "inertia",
        "default": 1.0,
        "required": true,
        "description": "The inertia of the drone",
        "type": "float"
      },
      {
        "name": "radius",
        "default": 0.2,
        "required": true,
        "description": "The radius of the drone",
        "type": "float"
      },
      {
        "name": "force_limit",
        "default": 15.0,
        "required": true,
        "description": "The maximum force that can be applied to the drone",
        "type": "float"
      }
    ],
    "parameters": null,
    "roles": [
      "user"
    ],
    "description": "A 3D drone model"
  }
}

 {
  "details": {
    "name": "LinearStateSpaceModel-v1",
    "description": "This model represents a linear Guassian dynamical system with unknown dynamics.\nThe state transition is modeled as a matrix with Gaussian prior on the elements.\nThe observational model is assumed to be the diagonal matrix with `1` on the diagonal.\n",
    "author": "Lazy Dynamics",
    "roles": [
      "user"
    ]
  },
  "config": {
    "name": "LinearStateSpaceModel-v1",
    "author": "Lazy Dynamics",
    "arguments": [
      {
        "name": "state_dimension",
        "required": true,
        "description": "The dimension of the state space",
        "type": "int"
      },
      {
        "name": "horizon",
        "default": 10,
        "description": "The horizon of the model for prediction",
        "type": "int"
      }
    ],
    "parameters": [
      {
        "name": "A",
        "description": "The state transition matrix"
      }
    ],
    "roles": [
      "user"
    ],
    "description": "This model represents a linear Guassian dynamical system with unknown dynamics.\nThe state transition is modeled as a matrix with Gaussian prior on the elements.\nThe observational model is assumed to be the diagonal matrix with `1` on the diagonal.\n"
  }
}

To inspect the roles required for a specific model, you can simply access the roles field of the model details:

available_models[1].details
{
  "name": "BetaBernoulli-v1",
  "description": "A simple Beta-Bernoulli model",
  "author": "Lazy Dynamics",
  "roles": [
    "user"
  ]
}

or alternatively use the get_available_model operation:

import RxInferClientOpenAPI: ModelsApi, get_available_model

models_api = ModelsApi(client)
response, _ = get_available_model(models_api, available_models[1].details.name)

response.details
{
  "name": "BetaBernoulli-v1",
  "description": "A simple Beta-Bernoulli model",
  "author": "Lazy Dynamics",
  "roles": [
    "user"
  ]
}

Read more about how to create and manage models in the Models management section.