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
"73a76e63-4cda-4080-b091-f4a7daa7cb5d"
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 73a76e63-4cda-4080-b091-f4a7daa7cb5d"
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
7-element Vector{RxInferClientOpenAPI.AvailableModel}:
 {
  "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": "arm_length",
        "default": 0.5,
        "required": true,
        "description": "The length of the arm",
        "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": "ContextualBandits-v1",
    "description": "A Contextual Bandits model using Thompson Sampling with multivariate normal priors",
    "author": "Lazy Dynamics",
    "roles": [
      "user"
    ]
  },
  "config": {
    "name": "ContextualBandits-v1",
    "author": "Lazy Dynamics",
    "arguments": [
      {
        "name": "context_dim",
        "required": true,
        "description": "The dimensionality of the context vectors",
        "type": "int"
      },
      {
        "name": "n_arms",
        "required": true,
        "description": "The number of arms/actions available for selection",
        "type": "int"
      },
      {
        "name": "iterations",
        "required": true,
        "description": "The number of inference iterations for learning",
        "type": "int"
      }
    ],
    "parameters": [
      {
        "name": "θ",
        "description": "The posterior parameters for each arm's mean vector (multivariate normal)"
      },
      {
        "name": "γ",
        "description": "The posterior parameters for each arm's precision matrix (Wishart)"
      },
      {
        "name": "τ",
        "description": "The posterior parameter for noise precision (Gamma)"
      }
    ],
    "data": [
      {
        "name": "context",
        "required": true,
        "description": "The current context vector for arm selection",
        "type": "array"
      },
      {
        "name": "reward",
        "required": false,
        "description": "Historical rewards from previous arm selections",
        "type": "array"
      },
      {
        "name": "choice",
        "required": false,
        "description": "Historical arm choices from previous selections",
        "type": "array"
      },
      {
        "name": "context",
        "required": false,
        "description": "Historical context vectors from previous selections",
        "type": "array"
      }
    ],
    "roles": [
      "user"
    ],
    "description": "A Contextual Bandits model using Thompson Sampling with multivariate normal priors"
  }
}

 {
  "details": {
    "name": "FeatureDiscovery-v1",
    "description": "A Bayesian feature regression model with unknown noise precision",
    "author": "Lazy Dynamics",
    "roles": [
      "user"
    ]
  },
  "config": {
    "name": "FeatureDiscovery-v1",
    "author": "Lazy Dynamics",
    "arguments": [
      {
        "name": "number_of_iterations",
        "default": 25,
        "required": false,
        "description": "The number of variational inference iterations",
        "type": "int"
      }
    ],
    "parameters": [
      {
        "name": "omega_mean",
        "description": "The posterior mean of the coefficients parameter `omega`"
      },
      {
        "name": "omega_covariance",
        "description": "The posterior covariance of the coefficients parameter `omega`"
      },
      {
        "name": "s_shape",
        "description": "The posterior shape parameter of the noise precision `s` for the likelihood"
      },
      {
        "name": "s_rate",
        "description": "The posterior rate parameter of the noise precision `s` for the likelihood"
      }
    ],
    "data": [
      {
        "name": "x",
        "required": true,
        "description": "Input features for feature discovery.\nThis should be an array of numbers. \nFor example, if you have D features, `x` should be an array of D numbers.\n",
        "type": "array"
      },
      {
        "name": "y",
        "required": false,
        "description": "Target values (dependent variables) for the feature discovery regression.\nThis is the output variable that the model will attempt to predict\nbased on the input features `x` using Bayesian regression. Can be omitted\nif the model is used for inference only.\n",
        "type": "number"
      }
    ],
    "roles": [
      "user"
    ],
    "description": "A Bayesian feature regression model with unknown noise precision"
  }
}

 {
  "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": false,
        "description": "The initial alpha parameter of the prior Beta distribution `p`",
        "type": "int"
      },
      {
        "name": "prior_b",
        "default": 1,
        "required": false,
        "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": "Autoregressive-v1",
    "description": "An autoregressive model",
    "author": "Lazy Dynamics",
    "roles": [
      "user"
    ]
  },
  "config": {
    "name": "Autoregressive-v1",
    "author": "Lazy Dynamics",
    "arguments": [
      {
        "name": "order",
        "required": true,
        "description": "The order of the autoregressive model",
        "type": "int"
      },
      {
        "name": "horizon",
        "default": 0,
        "description": "The horizon of the model for prediction",
        "type": "int"
      },
      {
        "name": "x_μ",
        "required": false,
        "description": "The mean of the initial state",
        "type": "vector"
      },
      {
        "name": "x_Λ",
        "required": false,
        "description": "The precision of the initial state",
        "type": "matrix"
      }
    ],
    "parameters": [
      {
        "name": "τ_α",
        "description": "The shape parameter of the precision of the coefficients"
      },
      {
        "name": "τ_β",
        "description": "The rate parameter of the precision of the coefficients"
      },
      {
        "name": "θ_μ",
        "description": "The mean of the coefficients"
      },
      {
        "name": "θ_Λ",
        "description": "The precision of the coefficients"
      }
    ],
    "roles": [
      "user"
    ],
    "description": "An autoregressive 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"
  }
}

 {
  "details": {
    "name": "LinearRegression-v1",
    "description": "A Bayesian linear regression model with unknown noise variance",
    "author": "Lazy Dynamics",
    "roles": [
      "user"
    ]
  },
  "config": {
    "name": "LinearRegression-v1",
    "author": "Lazy Dynamics",
    "arguments": [
      {
        "name": "number_of_iterations",
        "default": 25,
        "required": false,
        "description": "The number of variational inference iterations",
        "type": "int"
      }
    ],
    "parameters": [
      {
        "name": "a_mean",
        "description": "The posterior mean of the slope parameter `a`"
      },
      {
        "name": "a_variance",
        "description": "The posterior variance of the slope parameter `a`"
      },
      {
        "name": "b_mean",
        "description": "The posterior mean of the intercept parameter `b`"
      },
      {
        "name": "b_variance",
        "description": "The posterior variance of the intercept parameter `b`"
      },
      {
        "name": "s_shape",
        "description": "The posterior shape parameter of the noise variance `s`"
      },
      {
        "name": "s_rate",
        "description": "The posterior rate parameter of the noise variance `s`"
      }
    ],
    "data": [
      {
        "name": "x",
        "required": true,
        "description": "Input features (independent variables) for linear regression",
        "type": "array"
      },
      {
        "name": "y",
        "required": true,
        "description": "Target values (dependent variables) for linear regression",
        "type": "array"
      }
    ],
    "roles": [
      "user"
    ],
    "description": "A Bayesian linear regression model with unknown noise variance"
  }
}

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": "Drone3D-v1",
  "description": "A 3D drone 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": "Drone3D-v1",
  "description": "A 3D drone model",
  "author": "Lazy Dynamics",
  "roles": [
    "user"
  ]
}

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