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:
- Tagging Resources: Tools, assistants, and templates can be assigned one or more tags
- Tag Access Control: Each tag has its own access control rules (who can see/use tagged resources)
- Permission Checking: Users must have access to at least one of a resource’s tags to use it
- 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 resourcesprivate: Only tag creator can access tagged resourcesdomain: Users from same domain as tag creatordomains: 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
- No Tags: If a resource has no tags, it’s available to everyone (backward compatibility)
- Owner Access: Resource owners always have access regardless of tag restrictions
- Tag Access: Users need access to at least one tag to access the resource
- 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
- Principle of Least Privilege: Start with restrictive tags and expand access as needed
- Regular Audits: Periodically review tag assignments and access lists
- Tag Naming: Use clear, descriptive tag names that indicate their purpose
- 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
- Tag Hierarchies: Parent/child tag relationships
- Temporary Access: Time-based tag permissions
- Conditional Access: Access based on user attributes
- Tag Analytics: Usage tracking and reporting
- Bulk Management UI: Admin interface for tag operations
Integration Opportunities
- RBAC Integration: Connect with role-based access control
- SSO Integration: Sync tags with identity provider groups
- Audit Logging: Track tag permission changes
- 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.