# How Entity Access Control and Share Permission Management Work in Macro

> Discover how Macro Inc handles entity access control and share permission management using the SharePermission model for secure authorization.

- Repository: [Macro/macro](https://github.com/macro-inc/macro)
- Tags: how-to-guide
- Published: 2026-08-17

---

**Entity access control and share permission management in Macro rely on the SharePermission model, which links every shareable entity to a specific access level and enforces authorization through compile-time checked database operations.**

The macro-inc/macro repository implements a type-safe permission system that governs access to documents, projects, chats, and calls. This system uses a centralized **SharePermission** architecture to ensure consistent enforcement of view, comment, edit, and owner privileges across all entity types.

## The SharePermission Model

At the core of Macro's access control system is the **SharePermission** (or **SharePermissionV2**) struct defined in [`models_permissions/src/share_permission/mod.rs`](https://github.com/macro-inc/macro/blob/main/models_permissions/src/share_permission/mod.rs). Every shareable entity—whether a document, project, thread, or call—maintains a relationship to a row in the `SharePermission` table. This row stores the permission ID and the specific **AccessLevel** granted to the user or channel.

When an entity is created, the system inserts a corresponding permission record. For example, a `DocumentPermission` row points to a `SharePermission` entry, establishing the ownership and access constraints for that specific document. Permission IDs propagate throughout the codebase to enforce access checks at every operation boundary.

## Access Level Hierarchy

The system defines a strict hierarchy of access levels in [`models_permissions/src/share_permission/access_level.rs`](https://github.com/macro-inc/macro/blob/main/models_permissions/src/share_permission/access_level.rs). The **AccessLevel** enum specifies four distinct permission tiers:

- **View** – Read-only access to the entity
- **Comment** – Ability to view and add comments  
- **Edit** – Full modification rights without ownership transfer
- **Owner** – Full control including permission management and deletion

These levels enforce a one-way privilege escalation; an operation requiring `Edit` access will reject requests from users holding only `View` or `Comment` permissions.

## Permission Lookup and Validation Flow

Every permission update follows a consistent three-step flow implemented across the database client modules:

### Step 1: Lookup

Services retrieve the existing permission ID using `macro_db_client::share_permission::get::get_share_permission_id`. This function queries the database to locate the `SharePermission` record associated with the target entity.

### Step 2: Validation

The system compares the requester's current **AccessLevel** against the requirements of the requested operation. For example, a user must hold `Edit` or `Owner` privileges to modify document content. The validation logic resides in service layers such as [`services/document_storage_service/src/service/entity_mutation.rs`](https://github.com/macro-inc/macro/blob/main/services/document_storage_service/src/service/entity_mutation.rs).

### Step 3: Persist

Upon validation, the system calls type-specific creation or edit functions. These include `create_project_permission` for new project shares or `edit_thread_permission` for updating existing thread access. All database operations use `sqlx` query macros, ensuring compile-time schema validation and preventing SQL injection vulnerabilities.

## Channel-Specific Sharing

Macro extends the permission model to channels through **ChannelSharePermission** rows defined in [`models_permissions/src/share_permission/channel_share_permission.rs`](https://github.com/macro-inc/macro/blob/main/models_permissions/src/share_permission/channel_share_permission.rs). These rows map a channel identifier to a share permission ID, enabling fine-grained access control for collaborative spaces.

The `channel_permission` module within `macro_db_client` handles insertion and updates. The function `insert_channel_share_permission` creates these associations, binding a channel to a specific permission level such as `AccessLevel::Comment`.

## Code Implementation Examples

### Creating a New Project Permission

When initializing a project with shared access, services construct a `SharePermissionV2` struct and persist it through the database client:

```rust
use macro_db_client::share_permission::create::create_project_permission;
use models_permissions::share_permission::{SharePermissionV2, LinkShare, AccessLevel};
use uuid::Uuid;

let share_permission = SharePermissionV2 {
    id: Uuid::new_v4(),
    link_share: LinkShare::Public,
    access_level: AccessLevel::Edit,
    // …other fields…
};

create_project_permission(&share_permission).await?;

```

### Fetching and Validating Document Access

Service layers enforce access control by retrieving permissions before executing operations:

```rust
use macro_db_client::share_permission::get::get_document_share_permission;
use models_permissions::share_permission::AccessLevel;

let perm = get_document_share_permission(&document_id).await?;

match perm.access_level {
    AccessLevel::Edit | AccessLevel::Owner => { /* allow edit */ }
    _ => { /* deny with insufficient permissions error */ }
}

```

### Updating Channel Permissions

To grant channel-level access, the system first looks up the permission ID, then inserts a channel-specific mapping:

```rust
use macro_db_client::share_permission::get::get_share_permission_id;
use macro_db_client::share_permission::channel_permission::create::insert_channel_share_permission;
use models_permissions::share_permission::AccessLevel;

let permission_id = get_share_permission_id(&channel_id).await?;

insert_channel_share_permission(
    &permission_id,
    &channel_id,
    AccessLevel::Comment,
).await?;

```

## Key Source Files

The permission system spans multiple crates and modules:

| Component | File Path |
|-----------|-----------|
| Core permission model | [`models_permissions/src/share_permission/mod.rs`](https://github.com/macro-inc/macro/blob/main/models_permissions/src/share_permission/mod.rs) |
| Access level definitions | [`models_permissions/src/share_permission/access_level.rs`](https://github.com/macro-inc/macro/blob/main/models_permissions/src/share_permission/access_level.rs) |
| Channel share structures | [`models_permissions/src/share_permission/channel_share_permission.rs`](https://github.com/macro-inc/macro/blob/main/models_permissions/src/share_permission/channel_share_permission.rs) |
| Database read operations | [`macro_db_client/src/share_permission/get.rs`](https://github.com/macro-inc/macro/blob/main/macro_db_client/src/share_permission/get.rs) |
| Database create operations | [`macro_db_client/src/share_permission/create.rs`](https://github.com/macro-inc/macro/blob/main/macro_db_client/src/share_permission/create.rs) |
| Database update operations | [`macro_db_client/src/share_permission/edit.rs`](https://github.com/macro-inc/macro/blob/main/macro_db_client/src/share_permission/edit.rs) |
| Channel permission DB logic | [`macro_db_client/src/share_permission/channel_permission/create.rs`](https://github.com/macro-inc/macro/blob/main/macro_db_client/src/share_permission/channel_permission/create.rs) |
| Service layer mutations | [`services/document_storage_service/src/service/entity_mutation.rs`](https://github.com/macro-inc/macro/blob/main/services/document_storage_service/src/service/entity_mutation.rs) |
| Outbound mutation handling | [`services/document_storage_service/src/outbound/entity_mutation.rs`](https://github.com/macro-inc/macro/blob/main/services/document_storage_service/src/outbound/entity_mutation.rs) |

## Summary

- **Entity access control and share permission management** in Macro center on the `SharePermission` model, which associates every entity with a UUID-based permission record.
- The **AccessLevel** enum defines a strict hierarchy: view, comment, edit, and owner.
- Authorization follows a three-step pattern: lookup the permission ID, validate the access level, and persist changes through type-safe database functions.
- **ChannelSharePermission** extends the model to collaborative channels, managed through dedicated modules in `macro_db_client`.
- All database interactions use `sqlx` macros for compile-time verification, ensuring schema consistency across the Rust codebase.

## Frequently Asked Questions

### How does Macro verify a user has permission to edit a document?

The system calls `macro_db_client::share_permission::get::get_document_share_permission` to retrieve the permission record, then compares the stored `AccessLevel` against the required level. Only users with `Edit` or `Owner` levels proceed with the operation; others receive an insufficient permissions error.

### What is the difference between SharePermission and ChannelSharePermission?

**SharePermission** defines the access level for individual entities like documents or projects, while **ChannelSharePermission** maps these permissions to entire channels. This allows teams to share access across collaborative spaces while maintaining the same underlying permission ID and access level hierarchy defined in [`models_permissions/src/share_permission/channel_share_permission.rs`](https://github.com/macro-inc/macro/blob/main/models_permissions/src/share_permission/channel_share_permission.rs).

### Where are permission creation functions implemented?

Creation logic resides in [`macro_db_client/src/share_permission/create.rs`](https://github.com/macro-inc/macro/blob/main/macro_db_client/src/share_permission/create.rs), which provides functions like `create_project_permission` for entity-specific shares. Channel-specific mappings use `insert_channel_share_permission` from the `channel_permission` submodule. These functions leverage `sqlx` query macros for compile-time safety.

### Can access levels be customized beyond the four default tiers?

According to the source code in [`models_permissions/src/share_permission/access_level.rs`](https://github.com/macro-inc/macro/blob/main/models_permissions/src/share_permission/access_level.rs), the system uses a fixed enum of view, comment, edit, and owner levels. The current implementation does not support dynamic or custom access levels; all permission checks validate against these four statically defined variants.