Tag Permission System

The Tag Permission System provides fine-grained access control for tools, assistants, and templates by allowing resources to be tagged and restricting access based on user permissions for those tags.

Overview

The system works by:

  1. Tagging Resources: Tools, assistants, and templates can be assigned one or more tags
  2. Tag Access Control: Each tag has its own access control rules (who can see/use tagged resources)
  3. Permission Checking: Users must have access to at least one of a resource’s tags to use it
  4. Hierarchical Access: Resource owners always have access regardless of tags

Architecture

Core Components

1. Tag Interface

interface Tag {
  id: string;
  name: string;
  description?: string;
  accessControl: AccessControl;
  createdBy: string;
  createdAt: number;
  updatedAt: number;
}

2. Access Control Types

Tags support all the same access control types as assistants:

  • public: Everyone can access tagged resources
  • private: Only tag creator can access tagged resources
  • domain: Users from same domain as tag creator
  • domains: Users from specified domains (array)
  • specific: Specific email addresses (array)
  • group: Members of predefined groups (array)

3. Tagged Resources

Resources that support tags include an optional tags field:

// Tools
interface Tool {
  id: string;
  name: string;
  // ... other fields
  tags?: string[]; // Array of tag IDs
}

// Assistants  
interface Assistant {
  assistantId: string;
  // ... other fields
  tags?: string[]; // Array of tag IDs
}

// Templates
interface Template {
  templateId: string;
  // ... other fields
  tags?: string[]; // Array of tag IDs
}

Permission Logic

Access Rules

  1. No Tags: If a resource has no tags, it’s available to everyone (backward compatibility)
  2. Owner Access: Resource owners always have access regardless of tag restrictions
  3. Tag Access: Users need access to at least one tag to access the resource
  4. Unknown Tags: If a tag doesn’t exist in the system, access is denied

Permission Checking Flow

1. Check if resource has tags
   ├─ No tags → Allow access
   └─ Has tags → Continue to step 2

2. Check if user is resource owner
   ├─ Is owner → Allow access
   └─ Not owner → Continue to step 3

3. Check tag permissions
   ├─ User has access to ≥1 tag → Allow access
   └─ User has no tag access → Deny access

Implementation

Frontend Components

1. TagSelector Component

  • Manages tag selection for resources
  • Supports autocomplete and custom tag creation
  • Shows tag descriptions and access levels

2. TagAccessDialog Component

  • Creates and edits tags
  • Configures tag access permissions
  • Uses existing AccessSelector component

3. Tool Filtering

  • ToolSelector automatically filters tools based on tag permissions
  • Users only see tools they have access to
  • Categories update dynamically based on available tools

Backend Integration

1. Firebase Service Methods

// Tag Management
FirebaseService.createTag(tag)
FirebaseService.updateTag(tagId, updates)
FirebaseService.deleteTag(tagId)
FirebaseService.getAllTags()
FirebaseService.getTag(tagId)

// Initialization
FirebaseService.initializeAdminToolsTag(adminEmail)

2. Access Control Functions

// Check tag access
checkTagAccess(tags, availableTags, user, ownerEmail)

// Filter resources by tags
filterResourcesByTagAccess(resources, availableTags, user)

// Get accessible tags
getAccessibleTags(tags, user)

3. Backend Tool Permissions

# Python backend functions
check_tag_permissions(user_email, tags, tag_permissions)
filter_tools_by_tags(user_email, tools, tool_tags, tag_permissions)

Usage Examples

Example 1: Admin Tools Restriction

// 1. Create admin-tools tag
const adminTag = await FirebaseService.createTag({
  name: 'admin-tools',
  description: 'Administrative tools and features',
  accessControl: {
    type: 'specific',
    emails: ['admin@company.com']
  },
  createdBy: 'admin@company.com'
});

// 2. Tag the code_execution tool
const codeExecutionTool = {
  id: 'code_execution',
  name: 'Code Execution',
  tags: ['admin-tools'], // Restricted to admin users
  // ... other properties
};

// Result: Only admin@company.com can see/use code_execution

Example 2: Department-Specific Assistants

// 1. Create department tags
const financeTag = await FirebaseService.createTag({
  name: 'finance',
  description: 'Finance department resources',
  accessControl: {
    type: 'specific',
    emails: ['alice@company.com', 'bob@company.com']
  },
  createdBy: 'alice@company.com'
});

// 2. Tag assistants
const budgetAssistant = {
  name: 'Budget Analyzer',
  tags: ['finance'],
  // ... other properties
};

// Result: Only Alice and Bob can access the Budget Analyzer

Example 3: Domain-Based Access

// 1. Create company tag
const companyTag = await FirebaseService.createTag({
  name: 'internal-tools',
  description: 'Internal company tools',
  accessControl: {
    type: 'domain',
    domain: 'company.com'
  },
  createdBy: 'admin@company.com'
});

// 2. Tag multiple tools
const internalTools = [
  { id: 'hr-assistant', tags: ['internal-tools'] },
  { id: 'expense-tracker', tags: ['internal-tools'] },
  { id: 'project-manager', tags: ['internal-tools'] }
];

// Result: Only @company.com users can access these tools

Tag Management

Manual Tag Creation (Firestore Console)

1. Create Tag Document

Navigate to Firestore Console → tags collection → Add Document:

{
  "id": "admin-tools",
  "name": "admin-tools", 
  "description": "Administrative tools restricted to specific users",
  "accessControl": {
    "type": "specific",
    "emails": ["admin@example.com"]
  },
  "createdBy": "admin@example.com",
  "createdAt": 1703875200000,
  "updatedAt": 1703875200000
}

2. Tag Resources

Update tool/assistant/template documents to include tags:

{
  "tags": ["admin-tools", "power-users"]
}

Scripted Tag Management

1. Initialization Script

Use the provided initialization script:

import { initializeAdminTags } from '@/scripts/initializeAdminTags';

// Run once to set up initial tags
await initializeAdminTags();

2. Bulk Tag Creation

// Create multiple tags at once
const tags = [
  {
    name: 'admin-tools',
    description: 'Administrative tools',
    accessControl: { type: 'specific', emails: ['admin@company.com'] },
    createdBy: 'admin@company.com'
  },
  {
    name: 'finance-tools', 
    description: 'Finance department tools',
    accessControl: { type: 'domain', domain: 'finance.company.com' },
    createdBy: 'finance-admin@company.com'
  }
];

for (const tag of tags) {
  await FirebaseService.createTag(tag);
}

3. Bulk Resource Tagging

// Tag multiple tools
const adminTools = ['code_execution', 'system-monitor', 'user-manager'];
for (const toolId of adminTools) {
  // Update tool definition in AVAILABLE_TOOLS array
  const tool = AVAILABLE_TOOLS.find(t => t.id === toolId);
  if (tool) {
    tool.tags = ['admin-tools'];
  }
}

Security Considerations

Best Practices

  1. Principle of Least Privilege: Start with restrictive tags and expand access as needed
  2. Regular Audits: Periodically review tag assignments and access lists
  3. Tag Naming: Use clear, descriptive tag names that indicate their purpose
  4. Owner Responsibility: Tag creators are responsible for managing access

Access Patterns

  • Admin Tags: Highly restricted, specific emails only
  • Department Tags: Domain or group-based access
  • Project Tags: Temporary access for specific teams
  • Public Tags: Open access for general tools

Firestore Security Rules

Ensure Firestore rules protect tag documents:

// Allow read access to tags for authenticated users
// Allow write access only to tag owners or admins
match /tags/{tagId} {
  allow read: if request.auth != null;
  allow write: if request.auth != null && 
    (request.auth.token.email == resource.data.createdBy ||
     request.auth.token.email in getAdminEmails());
}

Testing and Validation

1. Test Tag Access

// Test user access to tags
const user = getAuth().currentUser;
const tags = await FirebaseService.getAllTags();
const accessibleTags = getAccessibleTags(tags, user);
console.log('User can access tags:', accessibleTags.map(t => t.name));

2. Test Tool Filtering

// Test tool visibility
const allTools = AVAILABLE_TOOLS;
const visibleTools = allTools.filter(tool => 
  checkTagAccess(tool.tags, availableTags, user)
);
console.log('Visible tools:', visibleTools.map(t => t.name));

3. Validation Checklist

  • Tags are created with proper access controls
  • Resources are tagged correctly
  • Users see only permitted resources
  • Resource owners can always access their resources
  • Tag permissions are enforced in both frontend and backend
  • Firestore security rules protect tag documents

Common Use Cases

1. Administrative Tools

  • Tags: admin-tools
  • Access: Specific admin emails
  • Resources: code_execution, system monitoring, user management

2. Department Isolation

  • Tags: finance, hr, engineering
  • Access: Department domain or specific emails
  • Resources: Department-specific assistants and tools

3. Customer Tiers

  • Tags: premium, enterprise
  • Access: Customer domain or group membership
  • Resources: Advanced features and assistants

4. Beta Features

  • Tags: beta-testers
  • Access: Specific beta user emails
  • Resources: Experimental tools and features

5. Geographic Restrictions

  • Tags: us-only, eu-compliant
  • Access: Domain-based (e.g., @company-us.com)
  • Resources: Region-specific tools and data

Troubleshooting

Common Issues

1. Tool Not Visible

  • Check if tool has tags assigned
  • Verify user has access to at least one tag
  • Confirm tag exists in Firestore
  • Check tag access control configuration

2. Tag Access Denied

  • Verify user email in tag’s access control
  • Check domain matching for domain-based access
  • Confirm group membership for group-based access
  • Validate tag creator permissions

3. Performance Issues

  • Tags are cached in ToolSelector component
  • Consider lazy loading for large tag lists
  • Monitor Firestore read operations

Debug Commands

// Check user's accessible tags
const accessibleTags = await getAccessibleTags(allTags, user);
console.log('Accessible tags:', accessibleTags);

// Check specific tag access
const hasAccess = checkTagAccess(['admin-tools'], allTags, user);
console.log('Has admin access:', hasAccess);

// Check tool filtering
const filteredTools = filterResourcesByTagAccess(tools, allTags, user);
console.log('Available tools:', filteredTools);

Future Enhancements

Planned Features

  1. Tag Hierarchies: Parent/child tag relationships
  2. Temporary Access: Time-based tag permissions
  3. Conditional Access: Access based on user attributes
  4. Tag Analytics: Usage tracking and reporting
  5. Bulk Management UI: Admin interface for tag operations

Integration Opportunities

  1. RBAC Integration: Connect with role-based access control
  2. SSO Integration: Sync tags with identity provider groups
  3. Audit Logging: Track tag permission changes
  4. API Access: REST API for external tag management

Conclusion

The Tag Permission System provides a flexible, scalable approach to access control that can grow with your organization’s needs. By starting with simple use cases and gradually expanding, you can create a comprehensive permission system that keeps sensitive tools and resources secure while maintaining ease of use for authorized users.