> ## Documentation Index
> Fetch the complete documentation index at: https://www.osohq.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Facts as Data

Polar, via Oso Cloud, can evaluate data that are stored outside your policy. These are referred to as "facts" in Oso documentation.

Whether a fact is written directly in the policy or stored externally, Polar applies the same logic during authorization. The difference affects environment mutability, query performance, and where evaluation occurs.

For related documentation:

* [Rules + Facts](/reference/polar/rules-and-facts): Writing facts inside policy files

## Fact Construction

Facts stored as data follow these rules:

* They must be unconditionally true, no `if` clauses.
* Arguments must be either [primitives](/reference/polar/types#primitive-types) (e.g. `3`, `"two"`) or [object literals](/reference/polar/types#object-literal-representation) (e.g. `User{"alice"}`).

Example:

```polar theme={null}
integer_string_eq(2, "two");
```

## Type Inference

Oso infers the expected types of facts based on their usage in policy rules. For example:

```polar theme={null}
has_permission(user: User, "pet", dog: Dog) if are_friends(user, dog);
```

From this rule, Oso infers that valid `are_friends` facts must take two arguments: a `User` and a `Dog`.

Based on inferred types, Oso will:

* Reject facts with mismatched types (e.g.,`are_friends(User:alice, Rabbit:peter)`)
* Reject facts with missing arguments (e.g., `are_friends(User:alice)`)
* Reject facts with unrecognized predicates (e.g., `ar_frens(User:alice, Dog:fido)`)

### Declaring Unused Fact Types

If you want to store facts that aren't currently used in your policy—e.g., tagging users or resources—you must declare the allowed type signature using `declare`:

```polar theme={null}
declare has_tag(User, Tag);
```

This allows facts like `has_tag(User:alice, Tag:is-cool)`, even if the policy does not use this fact type.

You can declare the same fact with different argument types using multiple `declare` statements:

```polar theme={null}
declare has_tag(User, Tag);
declare has_tag(Dog, Tag);
declare has_tag(Tag, Tag, Tag);
```

These `declare` statements form a union type. Oso will accept any fact that matches *one* of the declared or inferred types.

You do not need to use `declare` for fact types already referenced in your policy, its only required for types your policy does not use. Most policies do not require any declarations.
