User Isolation Guide

Complete guide to user_isolation: enforced - automatic user data protection in Fiberwise applications.

✅ user_isolation: enforced

Status: IMPLEMENTED - The Fiberwise platform now provides complete, automatic user data isolation.

What is user_isolation: enforced?

When enabled, user_isolation: enforced provides database-level user data protection that:

  • Automatically filters all queries by the current user's ID
  • Prevents data leakage between users at the database level
  • Works transparently - no code changes required
  • Cannot be bypassed - even malicious code cannot access other users' data

The user_id System Field

User isolation is built around a single system field: user_id

is_system_field("user_id")

The platform identifies user_id as the system field using the is_system_field() function:

# In fiberwise-common/schemas.py
def is_system_field(field_name: str) -> bool:
    """Check if a field is the system user_id field."""
    return field_name.lower() == "user_id"

# Usage in models
if is_system_field("user_id"):
    # This field gets automatic user isolation treatment
    pass

Automatic Field Management

  • Auto-population: user_id is automatically set on record creation
  • Protection: user_id cannot be modified by users
  • Filtering: All queries automatically include WHERE user_id = current_user
  • Validation: Users can only access records with their user_id

How to Enable User Isolation

1. App Manifest Configuration

Add user_isolation: enforced to your models in app_manifest.yaml:

models:
  - name: Customer Data
    model_slug: customers
    user_isolation: enforced  # ✅ Enables automatic user isolation
    fields:
      - name: Customer Name
        field_column: name
        type: text
        required: true
      
      # System field - automatically added
      - name: User ID
        field_column: user_id
        type: integer
        required: true
        default: CURRENT_USER
        is_system_field: true
        description: "User ID for automatic isolation"
        
      - name: Created At
        field_column: created_at
        type: timestamp
        default: CURRENT_TIMESTAMP
        is_system_field: true

2. Database Schema

The platform automatically ensures your tables include the user_id field:

-- Automatically generated schema
CREATE TABLE app_customers (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    user_id INTEGER NOT NULL REFERENCES users(id),  -- System field
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    -- App sets up foreign key constraint automatically
    CONSTRAINT fk_customer_user FOREIGN KEY (user_id) REFERENCES users(id)
);

3. Zero-Code Implementation

Once configured, user isolation works automatically:

// Your app code - NO filtering needed!
const customers = await FIBER.data.getItems('customers', {
    // No user filtering required - happens automatically!
});

// Platform automatically converts this to:
// SELECT * FROM app_customers WHERE user_id = [current_user_id]

// Creating records - user_id automatically assigned
const newCustomer = await FIBER.data.createItem('customers', {
    name: 'ACME Corp'
    // user_id automatically set to current user
});

Security Guarantees

🔒 Complete Data Protection

user_isolation: enforced provides unbreakable security:

✅ Database-Level Enforcement

All SQL queries automatically include user_id filtering at the database level

✅ Application-Independent

Security works even if app code is malicious or has bugs

✅ Zero-Trust Architecture

No way for applications to bypass user isolation

✅ Automatic Protection

Developers get security by default without code changes

Complete Examples

Multi-Tenant SaaS Application

# app_manifest.yaml
app:
  name: Customer CRM
  app_slug: customer-crm
  version: 1.0.0

models:
  - name: Company
    model_slug: companies
    user_isolation: enforced  # Each user sees only their companies
    fields:
      - name: Company Name
        field_column: name
        type: text
        required: true
      - name: Industry
        field_column: industry
        type: text
      # user_id field automatically added

  - name: Contact
    model_slug: contacts  
    user_isolation: enforced  # Each user sees only their contacts
    fields:
      - name: Contact Name
        field_column: name
        type: text
        required: true
      - name: Email
        field_column: email
        type: email
      - name: Company
        field_column: company_id
        type: integer
        references: companies
      # user_id field automatically added

Personal Data Application

# Personal note-taking app
models:
  - name: Note
    model_slug: notes
    user_isolation: enforced  # Notes are private to each user
    fields:
      - name: Title
        field_column: title
        type: text
        required: true
      - name: Content
        field_column: content
        type: text
      - name: Category
        field_column: category
        type: text
      # user_id automatically ensures privacy

Technical Implementation Details

Platform Components

  • fiberwise-common: Core is_system_field() function and DataIsolationConfig
  • fiber-sdk-python: User isolation utilities and model protection
  • fiberwise-core-web: Database query filtering and install service enforcement
  • fiberwise CLI: Isolation validation and CLI-level protection

Database Operations

All database operations are automatically modified:

# Install service automatically enforces user isolation
@enforce_user_isolation
async def process_app_from_manifest(conn, manifest, current_user):
    # All queries automatically include user filtering
    pass

# Routes automatically filter by user
def enforce_user_isolation_query(base_query: str, current_user) -> str:
    if "WHERE" in base_query.upper():
        return base_query + f" AND user_id = '{current_user.id}'"
    else:
        return base_query + f" WHERE user_id = '{current_user.id}'"

Configuration

# Default isolation configuration
DEFAULT_ISOLATION_CONFIG = DataIsolationConfig(
    user_isolation="enforced",
    auto_user_assignment=True,
    protect_user_id=True
)

Migration Guide

Updating Existing Apps

To enable user isolation on existing applications:

  1. Add user_isolation to manifest: Set user_isolation: enforced on models
  2. Add user_id field: Include the system field in your model definition
  3. Update database: Run migration to add user_id column to existing tables
  4. Remove manual filtering: Remove user filtering code from your app (now automatic)

Before (Manual Filtering)

// OLD: Manual user filtering required
const userTasks = await FIBER.data.getItems('tasks', {
    where: {
        created_by: currentUser.id  // Manual filtering
    }
});

After (Automatic Isolation)

// NEW: Automatic user isolation
const userTasks = await FIBER.data.getItems('tasks', {
    // No filtering needed - automatic user isolation!
});

// Platform automatically adds: WHERE user_id = [current_user_id]

Best Practices

✅ Do

  • Always use user_isolation: enforced for user-specific data
  • Mark user_id field with is_system_field: true
  • Let the platform handle user_id assignment and filtering
  • Remove manual filtering code once isolation is enabled
  • Test isolation by logging in as different users

❌ Don't

  • Don't manually set user_id - it's automatically managed
  • Don't add manual user filtering when isolation is enforced
  • Don't modify user_id values - they're protected
  • Don't use multiple user fields - stick to the single user_id system field

🎉 Ready to Use!

user_isolation: enforced is fully implemented and ready for production use. Simply add it to your app manifest and enjoy automatic, unbreakable user data protection!