Ruby Client API
Before going through this guide, make sure you follow the Oso Cloud Quickstart to get your Oso API Key properly set in your environment.
First, install the oso-cloud
gem from RubyGems:
gem install oso-cloud
Instantiating an Oso Cloud Client
The Oso Cloud library works by providing an Oso::Client
class which you configure with your Oso Cloud URL:
require 'oso/client'
oso = Oso::Client.new(url: "https://cloud.osohq.com", api_key: YOUR_API_KEY)
# Later:
oso.tell("has_role", user, role, resource)
# Wherever authorization needs to be performed:
if oso.authorize(user, action, resource)
# Action is allowed
Write API
Under the hood, Oso represents your objects as a TYPE and an ID. Right now,
the Ruby API assumes that each object passed to these methods is either a string or
an instance of a class (with a name) and with an id
property, which together form a unique
type/ID combination.
Add fact: oso.tell(predicate, *args)
Adds a fact named predicate
with the provided arguments. Example:
oso.tell("has_role", User.new("bob"), "owner", Organization.new("acme"))
Add many facts: oso.bulk_tell([*[predicate, *args]])
Adds many facts at once. Example:
oso.bulk_tell([
["has_role", User.new("bob"), "owner", Organization.new("acme")],
["has_role", User.new("bob"), "maintainer", Repository.new("anvil")],
])
Delete fact: oso.delete(predicate, *args)
Deletes a fact. Does not throw an error if the fact is not found. Example:
oso.delete("has_role", User.new("bob"), "maintainer", Repository.new("anvil"))
Delete many facts: oso.bulk_delete([*[predicate, *args]])
Deletes many facts at once. Does not throw an error when some of the facts are not found. Example:
oso.bulk_delete([
["has_role", User.new("bob"), "owner", Organization.new("acme")],
["has_role", User.new("bob"), "maintainer", Repository.new("anvil")],
])
Check API
Under the hood, Oso represents your objects as a TYPE and an ID. Right now,
the Ruby API assumes that objects passed to these methods are instances of a
class (with a name) and have an id
property, which together form a unique
type/ID combination.
Context facts
You may provide an array of context facts as an optional argument to any of the Check API methods. When Oso Cloud performs a check, it will consider these context facts in addition to any other facts you've previously added. Context facts are only used in the API call in which they're provided-- they do not persist across requests.
Context facts can be used to pass context from your application that you don't want to store in Oso Cloud:
- Deep resource hierarchies: by passing
has_relation(issue.repository, "parent", issue)
as a context fact, you can check permissions on an issue without storing everyissue -> repository
relationship in Oso Cloud. - Claims from a user token: if users get certain roles or permissions based on their authentication token (such as a JWT), you can pass that extra information using context facts like
is_admin(user)
. - Request-specific context: if you want to protect resources based on IP addresses, or time of day, or other ephemeral request properties, you can pass them as context facts with no arguments:
is_weekend()
orrequest_came_from_eu()
.
Check a permission: oso.authorize(actor, action, resource)
Determines whether or not an action is allowed, based on a combination of authorization data and policy logic. Example:
raise "Action is not allowed" unless oso.authorize(user, "read", anvils_repository)
You may provide an array of context facts as an optional fourth argument to this method. Example:
oso.authorize(user, "read", anvils_repository, [
["has_relation", issue_on_anvils_repository, "parent", anvils_repository] # a context fact
])
Check authorized resources: oso.authorize_resources(actor, action, resources)
Returns a subset of resources
on which an actor can perform a particular action.
Ordering and duplicates, if any exist, are preserved. Example:
resources = oso.authorize_resources(user, "read", [anvils_repository, acme_repository])
You may provide an array of context facts as an optional fourth argument to this method. Example:
resources = oso.authorize_resources(
user, "read", [anvils_repository, acme_repository],
[ # context facts
["has_relation", issue_on_anvils_repository, "parent", anvils_repository],
["has_relation", issue_on_acme_repository, "parent", acme_repository]
]
)
List authorized resources: oso.list(actor, action, resource_type)
Fetches a list of resources on which an actor can perform a particular action. Example:
repository_ids = oso.list(user, "read", Repository)
You may provide an array of context facts as an optional fourth argument to this method. Example:
repository_ids = oso.list(
user, "read", Issue,
[ # context facts
["has_relation", issue_on_anvils_repository, "parent", anvils_repository],
["has_relation", issue_on_acme_repository, "parent", acme_repository]
]
)
List authorized actions: oso.actions(actor, resource)
Fetches a list of actions which an actor can perform on a particular resource. Example:
actions = oso.actions(user, anvils_repository)
You may provide an array of context facts as an optional third argument to this method. Example:
actions = oso.actions(
user, issue_on_anvils_repository,
[
["has_relation", issue_on_anvils_repository, "parent", anvils_repository] # a context fact
]
)
List facts: oso.get(predicate, *args)
Lists facts that are stored in Oso Cloud. Can be used to check the existence of a particular fact, or used to fetch all facts that have a particular argument:
# Get one fact:
oso.get("has_role", bob, "admin", anvils)
# => [{
# "predicate": "has_role",
# "args": [
# { "type": "User", "id": "bob" },
# { "type": "String", "id": "admin" },
# { "type": "Repository", "id": "anvils" }
# ]
# }]
# List all roles on the `anvils` repo
oso.get("has_role", nil, nil, anvils)
# => [
# {
# "predicate": "has_role",
# "args": [
# { "type": "User", "id": "bob" },
# { "type": "String", "id": "admin" },
# { "type": "Repository", "id": "anvils" }
# ]
# },
# ... other has_role facts
# ]
Note that nil
behaves like a wildcard: passing nil, nil, anvils
means "find all facts where anvils
is the third argument, regardless of other
arguments".
Policy API
Update the active policy: oso.policy(policy)
Updates the policy in Oso Cloud. The string passed into this method should be written in Polar. Example:
oso.policy("actor User {}")
Talk to an Oso Engineer
Our team is happy to help you get started with Oso. If you'd like to learn more about using Oso in your app or have any questions about this guide, schedule a 1x1 with an Oso engineer.