# Access Policies

## Overview

When creating an [API Key](/environments/api-keys.md) for using Neurelo APIs in the Environment for your Project, by default you can allow Read-Only or Read/Write permissions for the entire Environment. Access Policies allow more fine-grained control, where you can configure permissions at an object and property level for the schema being used in the environment.

## Using Access Policies

### **Define your schema**

Before you start with access policies, you should have your schema already in place (see <https://docs.neurelo.com/definitions>). This is because you will reference objects and their properties when defining access policies.&#x20;

### **Define Access Policies**

* Navigate to the “Access Policies” tab under the Definitions for your Project
* Create one or more access policies. See [Access Policy definitions](#access-policy-definitions) for a description of the supported policy definitions and their format.

<figure><img src="/files/aRaRyyZychLDrPwfjRsq" alt="" width="563"><figcaption></figcaption></figure>

* Once you have defined your access polices, create a new **commit** for your definitions.

<figure><img src="/files/vFlkRWqhQseOPaWGBeI3" alt="" width="563"><figcaption></figcaption></figure>

### **Create an API Key**

* First, if you don’t already have one, you will now have to create an environment (see <https://docs.neurelo.com/environments/creating-a-new-environment>) and use the Commit of the definitions which include the Access Policy definitions.
* If you already have an environment, navigate to the Environment for your project from the left side navigation bar or from the dashboard for your project and update the Environment to use the **Commit** of the definitions which include the Access Policy definitions.&#x20;
* Create the API Key as described in <https://docs.neurelo.com/environments/api-keys>. Now you will find there an option to choose your access policy to be attached to this key

<figure><img src="/files/fJwvbxOBW9ZgrZK2U5LK" alt="" width="375"><figcaption></figcaption></figure>

### **Use the API Key**

* You can use your access policies enabled API key anywhere you would use a regular key.&#x20;
* The operations that can be performed using the key will follow the policies you have defined and attached to that key.&#x20;

## Access policy definitions

Each Access Policy is defined as a list of CRUD (<mark style="color:red;">`create`</mark>/ <mark style="color:red;">`read`</mark> / <mark style="color:red;">`update`</mark> /<mark style="color:red;">`delete`</mark>) permissions on an object or inner object.

### <mark style="color:red;">**`create`**</mark>

Create an object. This also allows creation of contained inner objects (for MongoDB projects).

Example:&#x20;

```json
[
   {
      "create":"Book"
   }
]
```

### <mark style="color:red;">**`createAnyObject`**</mark>

Create any object (regardless of the object name). This also allows creation of contained inner objects (for MongoDB projects).

Example:

```
[
    "createAnyObject"
]
```

### <mark style="color:red;">**`read`**</mark>

Read fields in an object or inner object (for MongoDB projects). This includes checks in a `where`.

Checks must have these keys

* `objectName`/`innerObjectName`: Name of the object or inner object (for MongoDB)
* `properties`: The properties allowed to be inspected

Example:&#x20;

```json
[
   {
      "read":{
         "objectName":"Publisher",
         "properties":[
            "id",
            "location",
            "name"
         ]
      }
   },
   {
      "read":{
         "innerObjectName":"Location",
         "properties":[
            "city_name",
            "state_name",
            "zip_code"
         ]
      }
   }
]
```

### <mark style="color:red;">**`readAnyProperty`**</mark>

Read any field in an object or inner object (for MongoDB projects), regardless of the property name. This includes checks in a `where`.

Checks must have these keys

* `objectName`/`innerObjectName`: Name of the object or inner object (for MongoDB)

Example:&#x20;

```json
[
   {
      "readAnyProperty":{
         "objectName":"Publisher",
      }
   },
   {
      "readAnyProperty":{
         "innerObjectName":"Location",
      }
   }
]
```

### <mark style="color:red;">**`readAnyObject`**</mark>

Read fields in any object or inner object (for MongoDB projects), regardless of the object name. This includes checks in a `where`.

Example:&#x20;

```json
[
   "readyAnyObject"
]
```

### <mark style="color:red;">**`update`**</mark>

Alter the contents of an object or inner object (for MongoDB). This is parameterized by a list of properties, allowing only some fields to be modified.

Checks must have these keys

* `objectName`/`innerObjectName`: Name of the object or inner object (for MongoDB)
* `properties`: The properties allowed to be inspected

Example:

```json
[
   {
      "update":{
         "objectName":"Publisher",
         "properties":[
            "id",
            "location",
            "name"
         ]
      }
   },
   {
      "update":{
         "innerObjectName":"Location",
         "properties":[
            "city_name",
            "state_name",
            "zip_code"
         ]
      }
   }
]
```

### <mark style="color:red;">**`updateAnyProperty`**</mark>

Alter the contents of an object or inner object (for MongoDB), regardless of the property names.

Checks must have these keys

* `objectName`/`innerObjectName`: Name of the object or inner object (for MongoDB)

Example:

```json
[
   {
      "updateAnyProperty":{
         "objectName":"Publisher",
      }
   },
   {
      "updateAnyProperty":{
         "innerObjectName":"Location",
      }
   }
]
```

### <mark style="color:red;">**`updateAnyObject`**</mark>

Alter the contents of any object or inner object (for MongoDB), regardless of object name.&#x20;

Example:

```json
[
    "updateAnyObject"
]
```

### <mark style="color:red;">**`delete`**</mark>

Delete an object. This will also allow delete for any inner objects (for MongoDB projects).

Example:&#x20;

```json
[
   {
      "delete":"Book"
   }
]
```

### <mark style="color:red;">**`deleteAnyObject`**</mark>

Delete any object, regardless of object name. This will also allow delete for any inner objects (for MongoDB projects).

Example:&#x20;

```json
[
    "deleteAnyObject"
]
```

### <mark style="color:red;">**`customQuery`**</mark>

Allow a specifc custom query, specified by name.

Example:&#x20;

```json
[
   {
      "customQuery": "find_books_by_publishers_in_new_york"
   }
]
```

### <mark style="color:red;">**`customQueryAny`**</mark>

Allow any custom query, regardless of name.

Example:&#x20;

```json
[
    "customQueryAny"
]
```

## Usage Notes

### Response Code&#x20;

If the request attempts to perform an operation that isn’t allowed by the policies specified, the response will have the status code <mark style="color:red;">**`HTTP 403 - Forbidden`**</mark>

### Updating Policies

If you would like to update the existing attached policies for an api key,

* Edit the policies in the Access Policies tab under Definitions
* Create a new Commit
* Update the Environment to use this new Commit. This step will need Runners for the environment to be stopped and re-started.

Once the environment is updated, new incoming requests with that key will be evaluated against the updated policy definitions

### Multiple Policies

You can create and attach multiple policies to an API Key. When multiple policies are identified for an API operation, the operation will be allowed based on the cumulative set of permissions from all of the policies. For example, consider the following permissions:

```jsx
# `read_city_state` permissions:

[{
    "read": {
        "objectName": "Location",
        "properties": ["city_name", "state_name"]
    }
}]
```

```jsx
# `read_zip_code` permissions:

[{
    "read": {
        "objectName": "Location",
        "properties": ["zip_code"]
    }
}]
```

A `GET` request to the `/rest/Location` endpoint with&#x20;

* the select parameter `{"city_name":true,"state_name":true,"zip_code":true}`&#x20;
* specifying the roles `["read_city_state","read_zip_code"]`&#x20;

will be allowed because each selected field is permitted by a rule in one of the policies.&#x20;

However, the same operation only with the `"read_city_state"` role but not `"read_zip_code"` would receive an `HTTP 403` response due to no permissions allowing inspection of the `zip_code` field to be found.

### Relations

When performing an operation that accesses or modifies across a relation, permissions for the related object will be checked as needed.&#x20;

For example, if a schema contains an object called `User` with a field called `blog_post_ids` that relates to one or more `Post` objects,&#x20;

* querying the `blog_posts` field of the `Users` object will require read permissions for the relevant `id` field of `Post` that the `blog_post_ids` field of `User` references.&#x20;
* Similarly, an update to the `User` object that uses the `"create"` operator to add a reference to new existing `Post` would require permission to create that


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.neurelo.com/guides/access-policies.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
