Writing Facts

Facts only apply to rules that exist in your policy. Oso Cloud prevents you from uploading facts that are not supported by your policy. Therefore, when you begin writing facts you should have in mind the rule that you are writing facts for. The rule itself provides much of the structure and information you’ll need to write your facts.

From Rules to Facts

In this section we'll cover some common variations of rule and their corresponding facts. The process for creating facts from rules is the same regardless of the rule. With one exception: short-form rules.

With shorthand rules there is a trade-off between the simplicity of writing the rule and the information that gets thrown under the hood. When working with shorthand rules, use the equivalent expanded rule to guide you in writing your facts.

How Facts and Rules are Related

Rule Statements

Here is a simple rule statement with three arguments.


<RULE_NAME> ( var1: $Type1, var2: $Type2, var3: $Type3);

A fact related to this rule must have the same name as the rule. Also, the arguments must have the same order and type as the rule.

Example Fact

oso-cloud tell <RULE_NAME> $Type1:ID-1 $Type2:ID-2 $Type3:ID-3

Conditional Rules

In this example we've added a condition to the rule.


<RULE_NAME> ( var1: $Type1, var2: $Type2, var3: $Type3) if
<CONDITIONAL_RULE_1> (var1: $Type1, var4: $Type4, var3: $Type3);

When you write facts for conditional rules you have two options:

  1. Write a fact that is explicit to the rule itself (<RULE_NAME>).

    Example Fact

    oso-cloud tell <RULE_NAME> $Type1:ID-1 $Type2:ID-2 $Type3:ID-3
  2. Write a fact, or set of facts, that satisfy all the conditions for the rule (the rules that come after if).

    Example Fact

    oso-cloud tell <CONDITIONAL_RULE_1> $Type1:ID-1 $Type4:ID-2 $Type3:ID-3

You have the flexibility to use whatever facts you want to achieve your authorization needs. However, the authorization patterns you chose will guide you to the best facts to add to Oso Cloud.

Facts that Grant Role Based Permissions


...
resource Organization {
...
"write" if "admin";
}

This is a shorthand roles based access pattern. The rule is contained within a resource block and it only applies to resources matching its type. In this example, the type is Organizations.

Equivalent Longhand Rule


has_permission(actor: Actor, "write", org: Organization) if
has_role(actor, "admin", org);

These rules only require the appropriate has_role fact to exist.

You'll write facts that:

  • Use any actor type defined in your policy
  • Use the role defined in the conditional rule (in this example: admin)
  • Use only the resource type defined in the rule (in this case Organization)

Example Fact

oso-cloud tell has_role User:bob admin Organization:resource_1

Facts that Grant Role Based Permissions with Relations


...
resource Organization {
...
}
resource Repository {
...
relations = {parent_org: Organization};
"write" if "admin" on "parent_org";
}

This is a shorthand roles based access pattern that grants permissions based on a resource-resource relationship.

Equivalent Longhand Rule


has_permission(actor: Actor, "write", repo: Repository) if
org matches Organization and
has_relation(repo, "parent_org", org) and
has_role(actor, "admin", org);

Unlike the previous example, this rule has two required conditional rule statements:

  • org matches Organization
  • has_role(actor, "admin", org)

As a result, two supporting facts are needed: the familiar has_role fact and has_relation fact.

You'll write facts that:

  • Use any actor type defined in your policy
  • Use the role defined in the rule conditions (in this example: admin)
  • Use the resource type defined in the rule conditions (in this case Organization)
  • Specifies the relationship between two resources (in this case the parent_org relationship between a Repository and an Organization)

Example Facts (both are required)

oso-cloud tell has_role User:bob admin Organization:org_1
oso-cloud tell has_relation Repository:my_repo parent_org Organization:org_1

Facts that Inherit Roles from Relationships


...
resource Organization {
...
}
resource Repository {
...
relations = {parent_org: Organization};
"admin" if "admin" on "parent_org";
}

This is a shorthand roles based access pattern that inherits roles based on a resource-resource relationship.

Equivalent Longhand Rule


has_role(actor: Actor, "admin", repo: Repository) if
org matches Organization and
has_relation(repo, "parent_org", org) and
has_role(actor, "admin", org);

The two required conditional rule statements are:

  • has_relation(repo, "parent_org", org)
  • has_role(actor, "admin", org)

You'll write facts that:

  • Use any actor type defined in your policy

  • Use the role defined in the rule conditions (in this example: admin)

  • Use the resource type defined in the rule conditions (in this case Organization)

  • Specifies the relationship between two resources (in this case the parent_org relationship between a Repository and an Organization)

    Example Facts (both are required)

    oso-cloud tell has_role User:bob admin Organization:org_1
    oso-cloud tell has_relation Repository:my_repo parent_org Organization:org_1

Facts that Inherit Roles from Groups


has_role(user: User, role: String, resource: Resource) if
group matches Group and
has_group(user, group) and
has_role(group, role, resource);

This is a custom roles pattern that inherits roles based on an actor-actor relationship. This rule has two required conditional rule statements:

  • has_group(user, group)
  • has_role(group, role, resource)

You'll write facts that:

  • Use only the actor type defined in the rule (in this case User)
  • Assign custom roles (any string is valid)
  • Use any resource type defined in your policy
  • Establishes membership of a User to a Group
  • Defines the role the group has on a particular resource

Example Facts (both are required)

oso-cloud tell has_role group:my_group admin Organization:org_1
oso-cloud tell has_group User:bob my_group

Additional Resources

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, connect with us on Slack. We're happy to help.

Get started with Oso Cloud →