Teams & Permissions

Ebla supports team-based collaboration with fine-grained access controls. Share libraries with team members while maintaining control over who can read, write, or administer content.

Teams

Creating a Team

# Create a new team
$ ebla team create "Engineering"
Team created successfully

  ID:          team_abc123
  Name:        Engineering
  Owner:       you@example.com
  Members:     1
  Libraries:   0

# With description
$ ebla team create "Engineering" --description "Core engineering team"

Team Roles

Each team member has a role that determines their permissions:

Role Manage Members Manage Libraries Write Files Read Files
Owner Yes Yes Yes Yes
Admin Yes Yes Yes Yes
Member No Yes Yes Yes
Viewer No No No Yes

Inviting Members

# Invite by email
$ ebla team invite team_abc123 alice@example.com
Invitation sent to alice@example.com

# Invite with specific role
$ ebla team invite team_abc123 bob@example.com --role admin

# List pending invitations
$ ebla team invitations team_abc123
EMAIL                ROLE      SENT          EXPIRES
alice@example.com    member    2 hours ago   in 5 days
bob@example.com      admin     5 minutes ago in 7 days

# Revoke invitation
$ ebla team revoke-invite team_abc123 alice@example.com

Accepting Invitations

# Accept via token (from email link)
$ ebla team accept abc123-invitation-token

Joined team "Engineering" as member

Managing Members

# List team members
$ ebla team members list team_abc123
USER                 ROLE      JOINED
you@example.com      owner     2026-01-01
alice@example.com    member    2026-01-15
bob@example.com      admin     2026-01-15

# Change member role
$ ebla team members role team_abc123 alice@example.com --role admin

# Remove member
$ ebla team members remove team_abc123 alice@example.com

Transferring Ownership

# Transfer team ownership to another member
$ ebla team transfer team_abc123 alice@example.com

Are you sure you want to transfer ownership of "Engineering" to alice@example.com?
This action cannot be undone. [y/N]: y

Ownership transferred. You are now an admin of this team.

Library Sharing

Personal vs Team Libraries

Creating a Team Library

# Create library owned by team
$ ebla library create "Shared Documents" --team team_abc123

Library created successfully
  ID:      lib_xyz789
  Name:    Shared Documents
  Team:    Engineering
  Access:  All team members (based on role)

Assigning Personal Library to Team

# Move personal library to team
$ ebla library assign lib_xyz789 --team team_abc123

Library "My Documents" is now owned by team "Engineering"

Viewing Team Libraries

# List team's libraries
$ ebla team libraries team_abc123

ID        NAME              FILES    SIZE      ACCESS
lib_001   Shared Documents  1,234    5.2 GB    team
lib_002   Code Repo         456      128 MB    team
lib_003   Design Assets     89       2.1 GB    team (read-only)

Access Control Lists (ACLs)

Permission Levels

Fine-grained control over library access:

Level View Download Sync/Write Manage ACLs
Admin Yes Yes Yes Yes
Write Yes Yes Yes No
Read Yes Yes No No
None No No No No

Setting ACLs via API

# Grant user access
curl -X POST http://server:6333/api/v1/libraries/lib_xyz789/acls \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "subject_type": "user",
    "subject_id": "usr_alice123",
    "permission": "write"
  }'

# Grant role-based access (all team admins)
curl -X POST http://server:6333/api/v1/libraries/lib_xyz789/acls \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "subject_type": "role",
    "subject_id": "team_abc123:admin",
    "permission": "admin"
  }'

Permission Precedence

When multiple rules apply, the most specific wins:

  1. User ACL - Direct user permission
  2. Role ACL - Permission based on team role
  3. Team Owner - Owners always have admin
  4. Library Owner - Original creator has admin

Permission Tracing

Understand why a user has access:

# API: Explain user's effective permission
curl "http://server:6333/admin/api/permissions/explain?library_id=lib_xyz&user_id=usr_alice" \
  -H "Authorization: Bearer $TOKEN"

{
  "user": "alice@example.com",
  "library": "Shared Documents",
  "effective_permission": "write",
  "sources": [
    {
      "type": "role_acl",
      "role": "member",
      "team": "Engineering",
      "permission": "write"
    }
  ]
}

Internal Share Links

Share files with other Ebla users via secure links:

# Create share link (requires login)
POST /api/v1/libraries/:id/shares
{
  "path": "documents/report.pdf",
  "permission": "view",  // view or download
  "expires_in": "7d"     // 1d, 7d, 30d, or never
}

# Response
{
  "token": "abc123xyz",
  "url": "https://server:6333/s/abc123xyz",
  "expires_at": "2026-01-22T00:00:00Z"
}

External Share Links (Enterprise)

Share with anyone, even without an account:

# Create public share link
POST /api/v1/libraries/:id/shares/external
{
  "path": "documents/report.pdf",
  "password": "optional-password",
  "one_time": false,
  "max_downloads": 10,
  "expires_in": "7d",
  "allowed_emails": ["client@example.com"],  // optional restriction
  "watermark": true                           // add watermark to previews
}

# Response
{
  "token": "pub_xyz789",
  "url": "https://server:6333/p/pub_xyz789",
  "password_protected": true,
  "expires_at": "2026-01-22T00:00:00Z"
}

Share Analytics

# View share analytics
GET /api/v1/shares/:token/analytics

{
  "views": 15,
  "downloads": 3,
  "unique_visitors": 8,
  "access_log": [
    {
      "timestamp": "2026-01-15T10:30:00Z",
      "action": "view",
      "ip": "203.0.113.45",
      "user_agent": "Chrome/120"
    }
  ]
}

Revoking Shares

# Revoke a share link
DELETE /api/v1/shares/:token

# Link immediately stops working

Audit Logging

What's Logged

All team actions are recorded for compliance:

Viewing Audit Logs

# CLI: View team audit log
$ ebla team audit team_abc123

TIMESTAMP            USER                 ACTION              DETAILS
2026-01-15 10:30     you@example.com      member_added        alice@example.com (member)
2026-01-15 10:35     you@example.com      role_changed        alice@example.com → admin
2026-01-15 11:00     alice@example.com    library_created     "Shared Documents"
2026-01-15 11:05     alice@example.com    acl_added           bob@example.com → write

# Filter by time range
$ ebla team audit team_abc123 --since 24h
$ ebla team audit team_abc123 --since 2026-01-01 --until 2026-01-15

# Filter by user
$ ebla team audit team_abc123 --user alice@example.com

Admin UI Audit Log

The admin dashboard provides a rich audit log interface:

Access at: http://your-server:6333/admin/audit

Admin UI for Permissions

ACL Editor

Manage permissions visually at /admin/permissions:

Add User Modal

When adding a user:

  1. Search for user by email
  2. Select permission level (3-column role cards)
  3. Set expiration (optional)
  4. Preview effective access before saving

Best Practices

Team Structure

Library Organization

Sharing