> ## 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.

# Implement in Oso Cloud

# Implement the Logic in Oso Cloud

In this guide, you will implement the authorization logic in Oso Cloud. You will run the Oso Cloud logic alongside your existing logic to confirm that the Oso Cloud implementation is correct. After, you will replace the authorization logic with Oso Cloud.

## Convert the logic to Polar

In Oso Cloud, you express your authorization logic in
[Polar](/develop/policies/overview). Polar is a concise and flexible language that provides powerful abstractions for both authorization models and application entities. For now, you will implement the logic with simple permission checks in order to mirror the existing application logic. Once that works, you can improve the logic further with more abstractions available in Polar.

Recall the authorization logic from the previous step:

```typescript src/authz.ts theme={null}
// A user can read a repo if they have any role on the repo or its parent organization.
function canReadRepo(user: UserWithRoles, repo: Repository): boolean {
  const orgRole = user.orgRoles.some((orgRole) => orgRole.orgId == repo.orgId);
  const repoRole = user.repoRoles.some(
    (repoRole) => repoRole.repoId == repo.id,
  );

  return orgRole || repoRole;
}
```

This says that **a user has the read permission on a repository** if:

* they have a role on the repository *or*
* they have a role on the repository's parent organization

Write this logic in Polar:

```polar policy.polar theme={null}
actor User {}

resource Organization {}

resource Repository {}

# A user has the read permission on a repository if ...
has_permission(user: User, "read", repository: Repository) if
  # ... they have a role on the repository
  has_role(user, _, repository);

# A user has the read permission on a repository if ...
has_permission(user: User, "read", repository: Repository) if
  # ... they have a role on the repository's parent organization
  organization matches Organization and
  has_relation(repository, "parent", organization) and
  has_role(user, _, organization);
```

This Polar code does the following:

* Entities in authorization logic are *actors* or *resources*.
  * An *actor* is the entity that is requesting a permission (e.g. `User`)
  * A *resource* is the entity upon which the actor is requesting permission (e.g. `Organization`, `Repository`)
* Two `has_permission` statements that mirror the logic from our application.

Copy the Polar code and save it to your [Oso Cloud
Workspace](https://ui.osohq.com/rules-editor/).

For a more basic introduction, you can review our [quickstart guide](/get-started/quickstart).

## Use the Oso Cloud SDK alongside existing authorization code

Next, you will use the Oso Cloud SDK to evaluate authorization requests in your application.
Do not replace your existing logic immediately. Instead, add the check API call for your
language alongside your existing logic.

In TypeScript, this is `authorize()`

Import and instantiate the Oso Cloud client.

```typescript src/authz.ts focus=1-11 theme={null}
import { Oso } from "oso-cloud";

// Make sure the API key is defined and instantiate the client
if (!process.env.OSO_API_KEY) {
  throw "Missing OSO API key from environment";
}

const osoUrl = process.env.OSO_URL
  ? process.env.OSO_URL
  : "https://cloud.osohq.com";
const osoClient = new Oso(osoUrl, process.env.OSO_API_KEY);
```

Then, add the `authorize()` call to the `canReadRepo()` function, alongside the existing logic.

<Info>
  The call to `osoClient.authorize()` in the following sample will not return the
  correct results until you send data to Oso Cloud in the next step.Do not use in
  production without providing [data as facts](/develop/facts/overview).
</Info>

```typescript src/auth.tz focus=13-20 theme={null}
// A user can read a repo if they have any role on the repo or its parent organization.
export async function canReadRepo(
  user: UserWithRoles,
  repo: Repository,
): Promise<boolean> {
  const orgRole = user.orgRoles.some((orgRole) => orgRole.orgId == repo.orgId);
  const repoRole = user.repoRoles.some(
    (repoRole) => repoRole.repoId == repo.id,
  );

  const authorizedInline = orgRole || repoRole;

  // entities for Oso
  const osoUser = { type: "User", id: user.id.toString() };
  const osoRepo = { type: "Repository", id: repo.id.toString() };

  const authorizedOso = await osoClient.authorize(osoUser, "read", osoRepo);
  console.log(
    `User:${user.id} read Repository:${repo.id}: inline: ${authorizedInline}; Oso: ${authorizedOso}`,
  );

  throw new Error(
    "This is sample code that fails without sending the necessary data to Oso Cloud.",
  );
  return authorizedInline;
}
```

The `authorize()` function accepts three arguments: an **actor**, an **action**, and a **resource**. It returns `true` if the actor has permission to perform the action on the resource. If the actor does not have permission, `authorize()` returns `false`.

* The `actor` and `resource` arguments are represented by a `type` and an `id`.
  * This is how Oso represents entities in your application.
* In the Node SDK, these entities are expressed as an object with `type` and `id` properties.
  * `User` object: ` {type: "User", id: user.id.toString() }`
  * `Repository` object: ` {type: "Repository", id: repo.id.toString() }`
* The `permission` argument is a string that is the name of the permission.
  * `"read"`

In the sample above, the `User` and `Repository` objects are assigned to the `osoUser` and `osoRepository` variables. This simplifies the resulting `osoClient.authorize()` call.

<Callout>
  If you're using a different client library, the form of the `Actor` and
  `Resource` arguments will be different. Check the documentation for [your
  language's client](/reference/sdks/overview) for details.
</Callout>

## Compare the results from Oso Cloud to the original code

By logging the authorization results of the original code and the Oso Cloud SDK, you can compare them ensure the results are identicial. After that, you can switch to using Oso for live authorization with confidence.

If you compare those results now, you'll see something like this:

```console focus=2,6 theme={null}
backend  | User:1 read Repository:1: inline: false; Oso: false
backend  | User:1 read Repository:2: inline: true; Oso: false
backend  | User:1 read Repository:3: inline: false; Oso: false
backend  | User:1 read Repository:4: inline: false; Oso: false
backend  | User:1 read Repository:5: inline: false; Oso: false
backend  | User:1 read Repository:6: inline: true; Oso: false
backend  | User:1 read Repository:7: inline: false; Oso: false
```

The calls to Oso always return `false`, even when the original code returns `true`. This results because we have not provided Oso the authorization data to determine what permissions the `User` possesses for the `Repository`.

We will provide these data initially as [context facts](/learn/guides/adopt-local-authorization/data-as-context-facts).
