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

# Resource Hierarchies

> Model parent-child relationships between resources

## What are Resource Hierarchies?

**Resource hierarchies** allow you to model parent-child relationships between resources. A folder contains documents, a project contains tasks, an order contains line items. These relationships enable hierarchical permission propagation and structured queries.

## Hierarchy Edge Properties

| Property           | Type              | Description                                           |
| ------------------ | ----------------- | ----------------------------------------------------- |
| `parentResourceId` | `string`          | The parent resource                                   |
| `childResourceId`  | `string`          | The child resource                                    |
| `relationshipType` | `string?`         | Type of relationship (e.g., "contains", "references") |
| `cascade`          | `CascadeModeEnum` | Permission inheritance: `inherit` or `none`           |
| `createdAt`        | `string`          | When the relationship was created                     |

## Cascade Modes

The `cascade` property controls how permissions propagate through the hierarchy:

### Inherit

A permission **patterned to a parent resource** can grant access to that resource's descendants:

```bash theme={null}
curl -X POST 'https://api.example.com/resource-hierarchy' \
  -d '{
    "parentResourceId": "resource_folder_123",
    "childResourceId": "resource_doc_456",
    "relationshipType": "contains",
    "cascade": "inherit"
  }'
```

With `cascade: "inherit"`, when a **child** resource is evaluated and direct RBAC denies, the engine walks up the `inherit` edges to the child's ancestors. Access is granted if the subject holds a permission whose `resourceType` matches the **child's** type (or `*`) **and** whose `resourcePattern` is an **ancestor's resource id**.

<Warning>
  This is **not** "folder-read permission implies document-read". The granting permission must be
  typed to the child (or `*`) and **patterned to the ancestor's id**—e.g. a `document`-typed
  (or `*`) read permission with `resourcePattern: "resource_folder_123"` grants `read` on
  documents beneath that folder. A permission typed `folder` does **not** satisfy a `document`
  evaluation.
</Warning>

### None

No permission inheritance—child resources require explicit access:

```bash theme={null}
curl -X POST 'https://api.example.com/resource-hierarchy' \
  -d '{
    "parentResourceId": "resource_issue_1",
    "childResourceId": "resource_issue_2",
    "relationshipType": "references",
    "cascade": "none"
  }'
```

With `cascade: "none"`:

* Parent access does not grant child access
* Each resource requires its own permissions
* Ideal for references, links, dependencies

## Creating Resource Hierarchies

```bash theme={null}
# Create a folder
curl -X POST 'https://api.example.com/resources' \
  -d '{
    "resourceTypeId": "rtype_folder",
    "ownerScopeId": "scope_engineering",
    "externalResourceId": "folder-123",
    "displayName": "Engineering Docs"
  }'

# Create a document
curl -X POST 'https://api.example.com/resources' \
  -d '{
    "resourceTypeId": "rtype_document",
    "ownerScopeId": "scope_engineering",
    "externalResourceId": "doc-456",
    "displayName": "API Design Doc"
  }'

# Link document to folder
curl -X POST 'https://api.example.com/resource-hierarchy' \
  -d '{
    "parentResourceId": "resource_folder_123",
    "childResourceId": "resource_doc_456",
    "relationshipType": "contains"
  }'
```

## Resource Type Hierarchies

Before creating resource hierarchies, define which resource types can contain which:

```bash theme={null}
# Folders can contain Documents
curl -X POST 'https://api.example.com/resource-type-hierarchy' \
  -d '{
    "parentTypeId": "rtype_folder",
    "childTypeId": "rtype_document"
  }'

# Folders can contain Folders (nested)
curl -X POST 'https://api.example.com/resource-type-hierarchy' \
  -d '{
    "parentTypeId": "rtype_folder",
    "childTypeId": "rtype_folder"
  }'

# Projects can contain Tasks
curl -X POST 'https://api.example.com/resource-type-hierarchy' \
  -d '{
    "parentTypeId": "rtype_project",
    "childTypeId": "rtype_task"
  }'
```

## Hierarchical Permission Patterns

### Pattern 1: Grant Access to a Folder's Contents

Grant `read` on everything beneath a folder by patterning a permission to the folder's id (typed to the child, or `*`). The engine applies it automatically when a document inside is evaluated:

```bash theme={null}
curl -X POST 'https://api.example.com/permissions' \
  -d '{
    "scopeId": "scope_org",
    "action": "read",
    "resourceType": "document",
    "resourcePattern": "resource_folder_123",
    "key": "document:read:resource_folder_123"
  }'
```

```typescript theme={null}
// Evaluate the DOCUMENT directly — the engine walks the inherit edge up to the folder
const decision = await bedrock.evaluate({
  actor: { subjectId: "subject_jane", subjectType: "user" },
  scopeId: "scope_engineering",
  action: "read",
  resource: { resourceId: "resource_doc_456" }  // inside folder_123
});
// allowed via the folder-patterned permission
```

### Pattern 2: Nested Inheritance

Inheritance walks the full ancestor chain, so a permission patterned to a top-level container reaches everything beneath it (as long as the edges are `cascade: "inherit"`):

```bash theme={null}
# Read anything under the workspace root
curl -X POST 'https://api.example.com/permissions' \
  -d '{
    "scopeId": "scope_org",
    "action": "read",
    "resourceType": "*",
    "resourcePattern": "resource_workspace_root",
    "key": "*:read:resource_workspace_root"
  }'
```

<Note>
  Inheritance is driven by the ancestor **resourcePattern**, not a condition. There is no
  `resource.parentId` or `subject.accessibleFolders` in the condition context—don't model
  hierarchy access with a `logic` condition.
</Note>

## Common Hierarchy Patterns

### Document Management

```
Workspace
└── Folder
    ├── Document
    │   └── Comment
    └── Folder (nested)
        └── Document
```

```bash theme={null}
# Define type hierarchy
curl -X POST 'https://api.example.com/resource-type-hierarchy/batch' \
  -d '[
    {"parentTypeId": "rtype_workspace", "childTypeId": "rtype_folder"},
    {"parentTypeId": "rtype_folder", "childTypeId": "rtype_folder"},
    {"parentTypeId": "rtype_folder", "childTypeId": "rtype_document"},
    {"parentTypeId": "rtype_document", "childTypeId": "rtype_comment"}
  ]'
```

### Project Management

```
Project
├── Epic
│   └── Issue
│       └── Subtask
└── Sprint
    └── Issue (linked)
```

### E-Commerce

```
Store
└── Category
    └── Product
        ├── Variant
        └── Review
```

### Construction

```
Job Site
├── Work Order
│   └── Task
└── Daily Log
    └── Entry
```

## Querying Hierarchies

```bash theme={null}
# Get children of a resource
curl -X GET 'https://api.example.com/resources/resource_folder_123/children'

# Get parent of a resource
curl -X GET 'https://api.example.com/resources/resource_doc_456/parent'

# Get all descendants (recursive)
curl -X GET 'https://api.example.com/resources/resource_folder_123/descendants'
```

## Relationship Types

Use `relationshipType` to distinguish different kinds of relationships:

| Type         | Use Case                                             |
| ------------ | ---------------------------------------------------- |
| `contains`   | Parent physically contains child (folder → document) |
| `references` | Parent references child (issue → linked issue)       |
| `owns`       | Parent owns child (user → created documents)         |
| `depends-on` | Parent depends on child (task → blocking task)       |

```bash theme={null}
# Different relationship types
curl -X POST 'https://api.example.com/resource-hierarchy/batch' \
  -d '[
    {"parentResourceId": "folder_1", "childResourceId": "doc_1", "relationshipType": "contains"},
    {"parentResourceId": "issue_1", "childResourceId": "issue_2", "relationshipType": "references"},
    {"parentResourceId": "task_1", "childResourceId": "task_2", "relationshipType": "depends-on"}
  ]'
```

## Best Practices

<AccordionGroup>
  <Accordion title="Define type hierarchies first">
    Always define resource type hierarchies before creating resource instance hierarchies.
  </Accordion>

  <Accordion title="Use meaningful relationship types">
    Choose relationship types that reflect your domain model.
  </Accordion>

  <Accordion title="Avoid deep nesting">
    Very deep hierarchies can impact query performance. Consider flattening when possible.
  </Accordion>

  <Accordion title="Consider permission implications">
    Plan how permissions will propagate through your hierarchy before building it.
  </Accordion>
</AccordionGroup>

## Ancestor Traversal

When evaluating permissions with `cascade: "inherit"`, the engine traverses ancestors:

```bash theme={null}
# Get all ancestors of a resource
curl -X GET 'https://api.example.com/resource-hierarchy/ancestors/resource_doc_456'
```

Response:

```json theme={null}
[
  {
    "id": "resource_folder_123",
    "displayName": "Engineering Docs",
    "cascade": "inherit"
  },
  {
    "id": "resource_workspace_root",
    "displayName": "Workspace",
    "cascade": "inherit"
  }
]
```

The evaluation engine checks permissions on each ancestor until access is granted or all ancestors are exhausted.

## Next Steps

<CardGroup cols={2}>
  <Card title="Resource Scope Links" icon="link" href="/resources/resource-scope-links">
    Associate resources with multiple scopes
  </Card>

  <Card title="Resource Policies" icon="shield-check" href="/resources/resource-policies">
    Fine-grained access control on resources
  </Card>
</CardGroup>
