Working with Ruby Types
Oso’s Ruby authorization library allows you to write policy rules over Ruby objects directly. This document explains how different types of Ruby objects can be used in Oso policies.
More detailed examples of working with application objects can be found in our Guides.
Class Instances
You can pass any Ruby instance into Oso and access its methods and fields from your policy (see Application Types).
Ruby instances can be constructed from inside an Oso policy using the
new
operator if the Ruby class has been registered using the
Oso#register_class
method. An example of this can be found
here.
Numbers and Booleans
Polar supports integer and floating point real numbers, as well as booleans
(see
Primitive Types). These map to the Ruby
Integer
, Float
, and TrueClass
/FalseClass
types.
Strings
Ruby strings are mapped to Polar strings. Ruby’s string methods may be called in policies:
allow(actor, _action, _resource) if actor.username.end_with?("example.com");
class User
attr_reader :username
def initialize(username)
@username = username
end
end
user = User.new("alice@example.com")
oso.authorize(user, "foo", "bar")
Polar does not support methods that mutate strings in place.
Lists
Ruby Arrays are mapped to Polar lists. Ruby’s Array methods may be called in policies:
allow(actor, _action, _resource) if actor.groups.include?("HR");
class User
attr_reader :groups
def initialize(groups)
@groups = groups
end
end
user = User.new(["HR", "payroll"])
oso.authorize(user, "foo", "bar")
Polar does not support methods that mutate lists in place unless the list is also returned from the method.
Likewise, lists constructed in Polar may be passed into Ruby methods:
allow(actor, _action, _resource) if actor.has_groups?(["HR", "payroll"]);
class User
attr_reader :groups
def initialize(groups)
@groups = groups
end
def has_groups(other)
@groups & other == other
end
end
user = User.new(["HR", "payroll"])
oso.authorize(user, "foo", "bar")
Ruby methods like
Array#at
may be used for random access to
list elements, but there is currently no Polar syntax that is equivalent to the
Ruby expression user.groups[1]
. To access the elements of a list without
using a method, you may iterate over it with
the in
operator or destructure it with
pattern
matching.
Hashes
Ruby hashes are mapped to Polar dictionaries:
allow(actor, _action, _resource) if actor.roles.project1 = "admin";
class User
attr_reader :roles
def initialize(roles)
@roles = roles
end
end
user = User.new({"project1" => "admin"})
oso.authorize(user, "foo", "bar")
Likewise, dictionaries constructed in Polar may be passed into Ruby methods.
Enumerables
You may iterate over any Ruby
enumerable using Polar’s
in
operator:
allow(actor, _action, _resource) if "payroll" in actor.get_groups();
class User
def get_groups(self)
["HR", "payroll"]
end
end
oso.authorize(User.new, "foo", "bar")
nil
The Ruby value nil
is registered as the Polar constant
nil
. If a Ruby method can return
nil
, you may want to compare the result to Polar’s nil
in your policy:
allow(actor, _action, _resource) if actor.get_optional != nil;
class User
def get_optional
some_condition? ? some_thing : nil
end
end
oso.authorize(User.new, "foo", "bar")
Ruby → Polar Types Summary
Ruby type | Polar type |
---|---|
Integer |
Integer |
Float |
Float |
TrueClass |
Boolean |
FalseClass |
Boolean |
Array |
List |
Hash |
Dictionary |
String |
String |
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.