Use the Oso Dev Server

Whether iterating on your policy locally or running integration tests in CI, hitting a remote service is not always the ideal developer experience. To bridge that gap, we offer a stripped-down Oso Dev Server (formerly Oso Local Development Binary) that you can run offline.

Installation

The Oso Dev Server is available for download from the Install page (opens in a new tab) in the Oso Cloud UI. We don't yet provide a hosted Docker image for the Oso Dev Server, but we do provide a Dockerfile that can be used to build an image.

Versioning

The install links for the Oso Dev Server contain a semver version number, e.g. {root-url}/{version}/{tarball}.

When using the Oso Dev Server in a CI/CD pipeline, we recommend pinning to a specific version.

You can check the version of the Oso Dev Server by running standalone --version.

Note: we consider the on-disk file format to be part of the API for semver versioning. When upgrading between major versions, you will need to delete and recreate any files stored in the OSO_DIRECTORY.

Setup

Once the Oso Dev Server is installed, you run it the same way you would run a dependency like Postgres or Redis locally. You need to make sure that the Oso Cloud CLI and the Oso Cloud client library integrated into your application are both configured to point at the Oso Dev Server using the local development test credential.

For the CLI, set the OSO_URL environment variable to http://localhost:8080 and the OSO_AUTH environment variable to e_0123456789_12345_osotesttoken01xiIn for the default test environment. If you use that API key against the Oso Cloud production service or use one of your real API keys against the local service, you will encounter authentication failures.

For the various language integrations, consult the API documentation for how to pass the local URL and API token to the constructor. E.g., for the Node.js library, you would instantiate it like so:


const { Oso } = require("oso-cloud");
const oso = new Oso(
"http://localhost:8080",
"e_0123456789_12345_osotesttoken01xiIn"
);

By default, the Oso Dev Server will run on port 8080 and store local data in a .oso/ directory. You can override either by setting the OSO_PORT and OSO_DIRECTORY environment variables, respectively.

We recommend creating a script that starts up the Oso Dev Server, loads your policy and a set of seed facts via either the oso-cloud CLI or one of the language clients, and then gracefully resets the data in the Oso Dev Server on exit via the CLI's clear command.

Initializing the policy

The Oso Dev Server supports passing in a list of policy files to initialize the environment.

e.g. run ./standalone main.polar tests.polar to start the Oso Dev Server and load the two policy files.

The Oso Dev Server also supports a --watch-for-changes flag, which will reload the policy files whenever any file changes. This can be useful for local development.

Creating test environments

The Oso Dev Server supports creating a new test environment with the POST /test_environment?copy=true endpoint. This will return a new environment id and token which can be used to make requests to the Oso Dev Server. When copy=true is set, the new environment will copy any existing policy data from the default test environment (e_0123456789).

When copy=false is set, the new environment will start with an empty policy.

Because the Oso Dev Server is a stateful service, these new environments will persist on disk after the Oso Dev Server is stopped. If you run many tests that create new environments, you may need to delete the .oso directory to reset the state of the Oso Dev Server and cleanup resources.

Create a new test environment with curl:


curl -X POST http://localhost:8080/test_environment\?copy\=true
> { "pub_id": "...", "token": "..." }

Using Node.js and Jest, you might create a new test environment :


const { Oso } = require("oso-cloud");
const OSO_SERVER_URL = "http://localhost:8080";
async function initializeOsoClient(devServerURL, opts) {
const response = await fetch(devServerURL + "/test_environment", {
method: "POST",
});
const data = await response.json();
return new Oso(devServerURL, data.token, opts);
}
describe("oso tests", () => {
let oso;
beforeEach(async () => {
oso = await initializeOsoClient(OSO_SERVER_URL);
});
test("denied", async () => {
const authorize = await oso.authorize(...);
expect(authorize).toEqual(false);
});
test("policy 1", async () => {
const authorize = await oso.authorize(...);
expect(authorize).toEqual(true);
});
});

Caveats

  • The Oso Dev Server is not for production use. It does, however, support all APIs, and there is no hard limit on the number of facts it supports.
  • The Oso Dev Server is a stateful service that supports default test environment with an active policy and set of facts. Integration tests that need to run in parallel should create separate test environments per unit test using the create test environment endpoint.
  • While we try to release new versions of the Oso Dev Server as we update the running Oso Cloud service, there may be a lag. Additionally, the Oso Dev Server does not currently have a 'check for updates' mechanism built-in, so updating to the latest version will fall on users. For both of these reasons, you should not rely on the validation and evaluation semantics of the Oso Dev Server exactly matching the Oso Cloud service, and, critically, you should do all final, pre-production validation of policy, data (facts), and enforcement changes against the live Oso Cloud service.

Feedback

We are actively iterating on developer experience and would appreciate all feedback on the Oso Dev Server and the broader development experience with Oso Cloud. Please do not hesitate to reach out on Slack (opens in a new tab) and/or submit ideas via the feature request portal (opens in a new tab) in the Oso Cloud UI.