Java Client API

💡

Before going through this guide, make sure you follow the Oso Cloud Quickstart to get your Oso Cloud API Key properly set in your environment.

See the Oso Cloud Java client's Maven Central page (opens in a new tab) for instructions on how to add it to your project.

Instantiating an Oso Cloud client

The Oso Cloud client provides an Oso class that takes your API key:


import com.osohq.oso_cloud.Oso;
...
Oso oso = new Oso(YOUR_API_KEY);
// Later:
oso.tell("has_role", user, role, resource);
// Wherever authorization needs to be performed:
boolean allowed := oso.authorize(user, action, resource);
if (allowed) {
// Action is allowed.
}

ℹ️

You should instantiate one client and share it across your application. Under the hood, it reuses connections to avoid paying the cost of negotiating a new connection on every request.

Specifying an Oso Fallback host

If you have deployed Oso Fallback nodes to your infrastructure, you may specify the host when instantiating the Oso Cloud client.


// Assumes Oso Fallback is hosted at http://localhost:8080
Oso oso = new Oso(YOUR_API_KEY, null, URI.create("http://localhost:8080"));

Passing application entities into the client

Under the hood, Oso Cloud represents an entity in your application as a combination of a type and an ID, which together uniquely identify the entity. The Java client represents these entities as Value objects with both type and id fields. For example:


import com.osohq.oso_cloud.api.Value;
...
Value alice = new Value("User", "alice");
Value anvilsRepository = new Value("Repository", "anvils");

You will pass objects like these into nearly every method call you make to the Java client.

Management API

Add fact: oso.tell(name, ...args)

Adds a fact named name with the provided arguments. Example:


oso.tell(
"has_role",
new Value("User", "bob"),
new Value("owner"),
new Value("Organization", "acme")
);

Add many facts: oso.bulkTell(facts)

ℹ️

For Oso Cloud developer accounts, bulkTell, bulkDelete, and bulk calls are limited to 20 facts. If you attempt to send more than 20 facts, the API will return an error.

Adds many facts at once. Example:


oso.bulkTell(Arrays.asList(
new Fact(
"has_role",
new Value("User", "bob"),
new Value("owner"),
new Value("Organization", "acme")
),
new Fact(
"has_role",
new Value("User", "bob"),
new Value("maintainer"),
new Value("Repository", "anvil")
)
));

Delete fact: oso.delete(name, ...args)

Deletes a fact. Does not throw an error if the fact is not found. Example:


oso.delete(
"has_role",
new Value("User", "bob"),
new Value("maintainer"),
new Value("Repository", "anvil")
);

Delete many facts: oso.bulkDelete(facts)

Deletes many facts at once. Does not throw an error when some of the facts are not found. Example:


oso.bulkDelete(Arrays.asList(
new Fact(
"has_role",
new Value("User", "bob"),
new Value("owner"),
new Value("Organization", "acme")
),
new Fact(
"has_role",
new Value("User", "bob"),
new Value("maintainer"),
new Value("Repository", "anvil")
)
));

Transactionally delete and add facts: oso.bulk(delete, tell)

Deletes and adds many facts in one atomic transaction. The deletions are performed before the adds. Does not throw an error when the facts to delete are not found. Example:


oso.Bulk(
Arrays.asList(
new Fact(
"has_role",
new Value("User", "bob"),
new Value("viewer"),
new Value("Repository", "anvil")
)
),
Arrays.asList(
new Fact(
"has_role",
new Value("User", "bob"),
new Value("maintainer"),
new Value("Repository", "anvil")
)
)
)

List facts: oso.get(name, ...args)

ℹ️

For Oso Cloud developer accounts, Get calls are limited to 1000 results. If you have more than 1000 facts, the function will return an error.

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",
new Value("User", "bob"),
new Value("admin"),
new Value("Repository", "anvils")
);
// List all roles on the `anvils` repo
oso.get(
"has_role",
new Value("User", null),
null,
new Value("Repository", "anvils")
);

Note that null fields for type or id behave like a wildcard: the above means "find all has_role facts where the first argument is a User and the Repository{"anvils"} is the third argument.".

Check API

ℹ️

For Oso Cloud developer accounts, the number of context facts per request is limited to 20; and the number of records returned is limited to 1000.

Context facts

Each Check API method has a variant to which you may provide a list of context facts. 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. Learn more about context facts.

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:


boolean allowed = oso.authorize(user, "read", anvilsRepository);
if (allowed) {
// Action is allowed.
}

You may provide a list of context facts as a fourth argument to this method. Example:


boolean allowed = oso.authorize(user, "read", issueOnAnvilsRepository, Arrays.asList(
// a context fact
new Fact("has_relation", issueOnAnvilsRepository, new Value("parent"), anvilsRepository)
));

Check authorized resources: oso.authorizeResources(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.

ℹ️

For Oso Cloud developer accounts, the number of input resources is limited to 1000.

Example:


Value[] results = oso.authorizeResources(user, "read", Arrays.asList(anvilsRepository, acmeRepository));

You may provide a list of context facts as a fourth argument to this method. Example:


Value[] results = oso.authorizeResources(user, "read", Arrays.asList(issueOnAnvilsRepository, issueOnAcmeRepository),
// context facts
Arrays.asList(
new Fact("has_relation", issueOnAnvilsRepository, new Value("parent"), anvilsRepository),
new Fact("has_relation", issueOnAcmeRepository, new Value("parent"), acmeRepository)
)
);

List authorized resources: oso.list(actor, action, resourceType)

Fetches a list of resource IDs on which an actor can perform a particular action. Example:


String[] repositoryIds = oso.list(user, "read", "Repository");

You may provide a list of context facts as a fourth argument to this method. Example:


String[] repositoryIds = oso.list(user, "read", "Issue",
// context facts
Arrays.asList(
new Fact("has_relation", issueOnAnvilsRepository, new Value("parent"), anvilsRepository),
new Fact("has_relation", issueOnAcmeRepository, new Value("parent"), acmeRepository)
)
);

List authorized actions: oso.actions(actor, resource)

Fetches a list of actions which an actor can perform on a particular resource. Example:


String[] actions = oso.actions(user, anvilsRepository);

You may use provide a list of context facts as a third argument to this method. Example:


String[] actions = oso.actions(user, issueOnAnvilsRepository,
Arrays.asList(
// a context fact
new Fact("has_relation", issueOnAnvilsRepository, new Value("parent"), anvilsRepository)
)
);

Query for anything: oso.query(rule)

Query Oso Cloud for any predicate and any combination of concrete and wildcard arguments. Unlike oso.get, which only lists facts you've added, you can use oso.query to list derived information about any rule in your policy. Example:


// Query for all the repos `User:bob` can `read`
Fact[] results = oso.query(
new Fact(
"allow",
new Value("User", "bob"),
new Value("read"),
new Value("Repository", null)
)
);
// Query for all the resources `User:admin` can `read`
Fact[] results = oso.query(
new Fact(
"allow",
new Value("User", "admin"),
new Value("read"),
null
)
)

Note that null behaves like a wildcard. Passing "allow", null, null, anvils means "find anyone who can do anything to anvils". null also behaves like a wildcard in return values from oso.query. Additionally, if you want to query over all instances of a particular type, pass a Value with a type but null id. For example, "allow", bob, "read", new Value("Repository", null) will query for all the objects of type "Repository" that bob can read.

Learn more about how to query Oso Cloud.

Distributed Check API

The distributed check API allows you to perform authorization using data that's distributed across Oso Cloud and your own database. When you instantiate the Oso Cloud client, provide the path to the YAML file that specifies how to resolve facts in your database.


Oso oso = new Oso(..., ..., ..., "path/to/data_bindings.yaml");

For more information, see the guide on filtering lists with decentralized data.

List authorized resources with distributed data: oso.listLocal(actor, action, resourceType, column)

Fetches a filter that can be applied to a database query to return just the resources on which an actor can perform an action. Example with JPA:


List<Issue> authorizedIssues = entityManager.createNativeQuery(
"SELECT * FROM issues WHERE " + oso.listLocal(alice, "read", "Issue", "id"),
Issue.class
).getResultList();

Check a permission with distributed data: oso.authorizeLocal(actor, action, resource)

Fetches a query that can be run against your database to determine whether an actor can perform an action on a resource. Example with JPA:


boolean allowed = (Boolean) entityManager.createNativeQuery(
oso.authorizeLocal(alice, "read", swageIssue)
).getSingleResult();
if (allowed) {
// Action is allowed.
}

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 {}")

This command will run any tests defined in your policy. If one or more of these tests fail, an exception will be thrown and your policy will not be updated.

Get policy metadata: oso.policyMetadata()

Returns metadata about the currently active policy. Example:


PolicyMetadata metadata = oso.policyMetadata()
System.out.println(Arrays.toString(metadata.resources.keySet().toArray()));
// prints [Organization, Repository, User, global]
System.out.println(Arrays.toString(org.roles));
// returns [admin, member]

See the Policy Metadata guide for more information on use cases.

Talk to an Oso Engineer

If you'd like to learn more about using Oso Cloud in your app or have any questions about this guide, schedule a 1x1 with an Oso engineer. We're happy to help.

Get started with Oso Cloud →