How Permissions and Share Permissions Are Managed in the Macro Codebase

Macro implements a fine-grained permission system through the SharePermissionV2 model in the macro_db_client crate, combining link-based defaults with optional per-channel overrides.

The Macro repository uses a database-backed share permission architecture to control access across projects, chats, channels, and calls. This system separates global link permissions from contextual channel permissions, enabling both public sharing and scoped collaboration. The implementation resides primarily in the macro_db_client crate and supporting tooling.


Core Data Model: SharePermissionV2

The permission system centers on SharePermissionV2, a struct with three controlling fields:

Field Purpose
link_share Defines link visibility via the LinkShare enum (Public, Private, or limited audience)
link_share_access_level Default access granted through links: View, Comment, or Edit
channel_share_permissions Optional per-channel overrides stored as separate database rows

These fields work together to determine effective permissions at runtime. The LinkShare and AccessLevel enums define the permission vocabulary used throughout the system.


Permission Creation Flow

Step 1: Create the Base Share Permission

When entities are persisted, the system first creates a SharePermissionV2 record. In tooling/seed_cli/src/service/db/mod.rs, the create_project_link_share_permission function handles this:

// Creates project-wide share permission at lines 424-428
macro_db_client::share_permission::create::create_project_permission(
    &share_permission,
)
.await?;

This pattern applies across entity types—projects, chats, calls—establishing the foundational permission record before entity creation completes.

Step 2: Map High-Level Concepts to Concrete Permissions

The tooling/seed_cli/src/entity/scenario/apply.rs file contains a share_permission helper (around line 492) that translates scenario-based ShareLevel values into AccessLevel variants:

// Mapping at lines 494-504
match share_level {
    ShareLevel::View => AccessLevel::View,
    ShareLevel::Comment => AccessLevel::Comment,
    ShareLevel::Edit => AccessLevel::Edit,
}

This abstraction layer separates business logic from database storage details.

Step 3: Attach Permission ID to Entities

The generated share_permission_id becomes a foreign key on the created entity. Consumers resolving share links query this ID to determine access rights.


Channel-Specific Permission Overrides

For entities appearing within channels, Macro supports channel share permissions that override the global link default.

Creating Channel Overrides

The insert_channel_share_permission function in tooling/seed_cli/src/service/db/mod.rs (line 206) inserts these records:

let channel_sp = ChannelSharePermission {
    share_permission_id,
    channel_id,
    access_level: AccessLevel::Comment, // Override: comment-only in this channel
};

macro_db_client::share_permission::channel_permission::create::insert_channel_share_permission(
    &channel_sp,
).await?;

Upsert Pattern for Idempotency

The upsert_channel_share_permission function (lines 335-345) implements create-or-update semantics, ensuring safe concurrent modifications:

// Handles existing rows gracefully
service::db::upsert_channel_share_permission(ctx, permission).await?;

Permission Synchronization on Mentions

When entities are mentioned in channel messages, update_share_permissions_for_mention (lines 191-204) automatically creates or updates channel permissions to keep access in sync with the mention context.

Duplicate Handling

The insertion functions are designed to be idempotent. insert_channel_share_permission logs a warning and continues if a permission already exists (line 214), preventing failures from race conditions.


JWT Integration and Runtime Enforcement

Permissions flow through the authentication layer via JWT claims.

Token Decoding

The decode_jwt crate parses tokens and extracts permission-related claims. This crate lives at crates/decode_jwt/src/lib.rs and serves as the entry point for permission validation in service boundaries.

Unfurl Service Claims Enrichment

The services/unfurl_service/src/unfurl/mod.rs file contains Macro-specific JWT claim handling. At line 461, a comment references ticket M-3421, indicating where custom permission claims are injected into tokens for downstream services.

This integration allows permission checks to occur at the edge, reducing database load for repeated requests.


Complete Permission Example

Here's a runnable example combining the key operations:

use macro_db_client::share_permission::{SharePermissionV2, LinkShare, AccessLevel};
use macro_db_client::share_permission::channel_permission::ChannelSharePermission;

// Create base permission with public edit access
let base_permission = SharePermissionV2 {
    link_share: Some(LinkShare::Public),
    link_share_access_level: Some(AccessLevel::Edit),
    channel_share_permissions: None,
};

let share_permission_id = macro_db_client::share_permission::create::create_project_permission(
    &base_permission,
).await?;

// Add restrictive channel override
let channel_override = ChannelSharePermission {
    share_permission_id,
    channel_id: "channel_123".into(),
    access_level: AccessLevel::Comment, // Narrow to comment-only in this channel
};

macro_db_client::share_permission::channel_permission::create::upsert_channel_share_permission(
    &channel_override,
).await?;

Key Implementation Files

File Path Responsibility
tooling/seed_cli/src/service/db/mod.rs Core CRUD operations for share permissions, channel overrides, and mention-triggered updates
tooling/seed_cli/src/entity/scenario/apply.rs High-level permission construction and ShareLevel to AccessLevel mapping
crates/decode_jwt/src/lib.rs JWT parsing and permission claim extraction
services/unfurl_service/src/unfurl/mod.rs Token enrichment with Macro-specific permission claims (M-3421)

Summary

  • SharePermissionV2 is the canonical permission model with link_share, link_share_access_level, and optional channel_share_permissions fields.
  • Link-based access defaults are created first, then channel overrides provide contextual restrictions.
  • Idempotent operations (insert_channel_share_permission, upsert_channel_share_permission) handle concurrent updates safely.
  • JWT integration (decode_jwt, unfurl_service) embeds permissions in authentication tokens for distributed enforcement.
  • Mention synchronization (update_share_permissions_for_mention) keeps channel permissions consistent with message references.

Frequently Asked Questions

Link share permissions define the default access level for anyone using a share link to the entity, controlled by link_share and link_share_access_level. Channel share permissions are optional overrides that apply when the entity appears within a specific channel, allowing narrower access (e.g., comment-only) than the global default. These are stored separately and resolved at runtime based on context.

How does Macro handle concurrent permission updates?

The system uses idempotent upsert operations. Functions like upsert_channel_share_permission either create new records or update existing ones, while insert_channel_share_permission logs warnings and continues on duplicate key errors. This design prevents race conditions from causing failures during high-concurrency scenarios.

Where are permissions enforced in the request lifecycle?

Permissions enter the request lifecycle through JWT claims. The decode_jwt crate parses tokens at service boundaries, and the unfurl_service enriches tokens with Macro-specific permission data. Downstream services validate these claims without requiring additional database queries, enabling scalable distributed enforcement.

No. The system assumes link permissions represent the maximum access level. Channel permissions are designed to restrict access further for specific contexts. If broader channel access is needed, the base link_share_access_level must be updated accordingly.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →