Using Additional Context in Policies

Allow rules take in an actor (which comes from authorization logic) and a resource (which comes from mapping). Sometimes you need some additional context information about the environment to write rules over.

For example, let’s say you have a policy like this:

01-context.polar
allow(actor, _action, _resource) if actor = "admin@example.org";

Here we have a very simple allow rule that allows an actor to access any resource if they are an admin. Maybe we want to also let any actor access any resource when the app is in development mode. A typical way to flag that an app is running in development or production mode would be to set an environment variable, e.g. ENV=development or ENV=production.

How would we read that environment variable from our policy though?

We can use a application class that lets us directly access the environment variables:

02-context.rb
class Env
  def self.var(variable)
    ENV[variable]
  end
end

OSO.register_class(Env)

The above class exposes a var method that reads the application’s environment variables and returns the requested value. We register the class with Oso, allowing us to instantiate it in the policy.

We can add a new allow rule that permits an actor to access a resource if the application is in development mode:

01-context.polar
allow(_actor, _action, _resource) if Env.var("ENV") = "development";

Summary

Application classes make it easy to expose any sort of application data to your policy, including environment variables and request context. This simple pattern lets you expose any kind of data you want to use in your policy, not just Actor and Resource classes.

Connect with us on Slack

If you have any questions, or just want to talk something through, jump into Slack. An Oso engineer or one of the thousands of developers in the growing community will be happy to help.