Quickstart
Schedule a 1x1 to go through this guide with an Oso engineer.
This guide will walk you through deploying your first policy and making your first authorization checks with Oso Cloud. You’ll use the Oso Cloud CLI, which is a thin wrapper around the HTTP API.
Get Your Oso API Key
Login to the Oso Cloud Sandbox at
https://cloud.osohq.com/
. This will generate an
API Key that you can use to experiment with Oso Cloud. Set the OSO_AUTH
environment variable to your API key:
$ export OSO_AUTH=<your_oso_api_key>
Setup the Oso CLI
Install the Oso Cloud CLI (and make sure that oso-cloud
is in your system PATH
):
$ curl https://cloud.osohq.com/install.sh | bash
Verify the Oso Cloud CLI is installed and that your Oso API Key is properly set:
$ oso-cloud inspect Actor:hello
(no results)
Write your first policy
Create a new file named quickstart.polar
and add the following code:
actor User {}
resource Organization {
permissions = ["read"];
roles = ["owner"];
"read" if "owner";
}
The logic here is pretty straightforward. We declare types User
and Organization
,
and we declare that actors possessing the owner
role on organizations are allowed to
perform the read
action on those organizations.
The "read" if "owner";
line is a shorthand syntax that declares the following rule:
has_permission(actor: Actor, "read", resource: Organization) if
has_role(actor, "owner", resource);
You can read more about shorthand rules.
Load your policy file to your Oso Cloud server with the oso-cloud policy
command:
$ oso-cloud policy quickstart.polar
Policy successfully loaded.
The server is now ready to authorize requests. Try to authorize an action: User bob
is trying to read
Organization acme
.
$ oso-cloud authorize User:bob read Organization:acme
Denied.
No dice. There’s no data that indicates that bob
can read Organization acme
. Oso Cloud is deny-by-default, meaning that you must explicitly allow an action using your policy logic and the right authorization data.
You have the policy logic in place (in quickstart.polar
) — now you just need data.
Grant Bob an owner
role:
$ oso-cloud tell has_role User:bob owner Organization:acme
Writing has_role(User:bob, String:owner, Organization:acme) to Oso at https://cloud.osohq.com/
Success.
Now, run the same check again:
$ oso-cloud authorize User:bob read Organization:acme
Allowed.
Cool. Bob is an owner
of the Acme organization, so he is allowed to read the organization. This is the basic idea behind Oso Cloud: you define implications in your policy (”read” if “owner”
, etc), and then you insert your roles and relations data. The combination of those things determine which actions are allowed.
Relations: a more complex policy
It’s time to add some complexity to your policy and introduce the concept of relations. Edit quickstart.polar
to contain the following:
actor User {}
resource Organization {
permissions = ["read"];
roles = ["owner"];
"read" if "owner";
}
resource Repository {
permissions = ["push"];
roles = ["maintainer"];
relations = { parent: Organization };
"maintainer" if "owner" on "parent";
"push" if "maintainer";
}
This added a Repository
type which belongs to the Organization
type (through a relation called parent
). The rule "maintainer" if "owner" on "parent";
means that an owner
role on an organization implicitly grants the maintainer
role on any repository related to that organization.
Now, update our policy in Oso Cloud:
$ oso-cloud policy quickstart.polar
Policy successfully loaded.
While Bob is still an owner of the Acme organization, he cannot push to any repositories yet:
$ oso-cloud authorize User:bob push Repository:anvils
Denied.
There is not yet any repository-related data in Oso Cloud that would grant any repository permissions. Now, create a parent
relation between Organization:acme
with Repository:anvils
using oso-cloud add relation
:
$ oso-cloud tell has_relation Repository:anvils parent Organization:acme
Writing has_relation(Repository:anvils, String:parent, Organization:acme) to Oso at https://cloud.osohq.com/
Success.
Now, the same authorization check (can User:bob
perform the push
action on Repository:anvils
?) should succeed:
$ oso-cloud authorize User:bob push Repository:anvils
Allowed.
The action was allowed because of two “edges” in the graph:
- An edge connecting
User:bob
toOrganization:acme
with theowner
role. - An edge connecting
Repository:anvils
toOrganization:acme
with theparent
relation.
Together with the policy in quickstart.polar
, Oso is able to determine that User:bob
has an implicit maintainer
role on Repository:anvils
and therefore is granted push
permission.
Repository-specific roles
You can also give a user a role directly on a repository! Imagine that Bob has been made a maintainer of Repository:oso
, which belongs to a different organization:
$ oso-cloud tell has_role User:bob "maintainer" Repository:oso
Writing has_role(User:bob, String:maintainer, Repository:oso) to Oso at https://cloud.osohq.com/
Success.
Now, list all of the repositories that Bob can perform the push
action on:
$ oso-cloud list User:bob push Repository
[anvils, oso]
Two results! Bob can push to Repository:anvils
because of his role on Organization:acme
, and also to Repository:oso
because of a direct role on the oso
repository.
Try adding more edges and see how they affect results! You can also change around the policy in quickstart.polar
to add additional roles, relationships, and resource types.
What's next?
Take a look at the API docs to learn more about how to integrate Oso with your app.
If you have any questions, or would like to talk through any details of your implementation, schedule a 1x1 with an Oso Engineer.