Tag-Based Tool Configuration

This guide explains how to use tags to control not just tool access, but also specific configuration options within tools. This allows fine-grained control over which buckets, datastores, or other resources users can access.

Overview

The tag-based configuration system allows:

  • Tool-level access: Completely hide tools from users without proper tags
  • Option filtering: Show only specific options in dropdown menus based on tags
  • Field visibility: Hide entire configuration fields based on tags
  • Dynamic defaults: Set different default values based on user’s tags
  • Validation rules: Apply different validation constraints based on tags

How It Works

1. Tag Configuration Options

Configuration options (like bucket names or datastore IDs) can be tagged:

options: [
  { label: 'Public Bucket', value: 'public-bucket' }, // No tags = public
  { label: 'Internal Docs', value: 'internal-docs', tags: ['company-wide'] },
  { label: 'Finance Reports', value: 'finance-reports', tags: ['finance-team', 'admin-tools'] },
]

2. Access Logic

  • No tags: Option is available to everyone
  • With tags: User must have access to at least ONE of the option’s tags
  • Multiple tags: Acts as OR logic (user needs ANY of the tags)

3. User Experience

  • Users only see options they have access to
  • Restricted options are completely hidden from dropdowns
  • No error messages about “insufficient permissions” for hidden options

Examples

File Browser Buckets

The file browser tool now has tagged bucket options:

{
  key: 'bucketUrl',
  label: 'Storage Bucket',
  type: 'select',
  options: [
    // Public bucket - available to everyone
    { label: 'Aitana Public Bucket', value: 'aitana-public-bucket' },
    
    // Internal bucket - requires company-wide or internal-access tag
    { label: 'Aitana Documents Bucket', value: 'aitana-documents-bucket', 
      tags: ['company-wide', 'internal-access'] },
    
    // Finance bucket - requires finance-team or admin-tools tag
    { label: 'Finance Reports Bucket', value: 'finance-reports-bucket', 
      tags: ['finance-team', 'admin-tools'] },
    
    // Engineering bucket - requires engineering-team tag
    { label: 'Engineering Assets Bucket', value: 'engineering-assets-bucket', 
      tags: ['engineering-team'] },
  ]
}

Vertex Search Datastores

Similar configuration for vertex search datastores:

{
  key: 'datastore_id',
  label: 'Data Store ID',
  type: 'select',
  options: [
    // Public datastore
    { label: 'Aitana Public Welcome', value: 'aitana_public_welcome' },
    
    // Energy team datastore
    { label: 'Our New Energy Documents', value: 'aitana3', 
      tags: ['energy-team', 'company-wide'] },
    
    // Support team datastore
    { label: 'Customer Support KB', value: 'support_kb', 
      tags: ['support-team', 'admin-tools'] },
    
    // Legal team datastore
    { label: 'Legal Documents', value: 'legal_docs', 
      tags: ['legal-team', 'admin-tools'] },
  ]
}

Setting Up Tag-Based Configurations

1. Create the Required Tags

First, create tags for your teams/groups in the admin interface (/admin/tags):

  • company-wide: For all company employees
  • finance-team: For finance department
  • engineering-team: For engineering department
  • support-team: For customer support
  • admin-tools: For administrators

2. Assign Users to Tags

Edit each tag and add the appropriate user emails:

{
  "name": "finance-team",
  "accessControl": {
    "type": "specific",
    "emails": [
      "cfo@company.com",
      "accountant1@company.com",
      "accountant2@company.com"
    ]
  }
}

3. Update Tool Configurations

Add tags to the configuration options in ToolSelector.tsx:

options: [
  { label: 'Public Option', value: 'public' },
  { label: 'Restricted Option', value: 'restricted', tags: ['special-access'] }
]

Advanced Features

Field-Level Restrictions

Hide entire configuration fields based on tags:

{
  key: 'advanced_settings',
  label: 'Advanced Settings',
  type: 'text',
  fieldTags: ['admin-tools'], // Only admins see this field
}

Tag-Based Defaults

Set different default values based on user’s tags:

{
  key: 'result_limit',
  label: 'Result Limit',
  type: 'number',
  tagDefaults: [
    { tags: ['admin-tools'], defaultValue: 1000 },
    { tags: ['power-users'], defaultValue: 500 },
    // Default for everyone else is 100
  ],
  placeholder: '100'
}

Tag-Based Validation

Apply different validation rules based on tags:

{
  key: 'query_depth',
  label: 'Query Depth',
  type: 'number',
  tagValidation: [
    { 
      tags: ['basic-users'], 
      max: 3, 
      message: 'Basic users limited to depth 3' 
    },
    { 
      tags: ['power-users'], 
      max: 10, 
      message: 'Power users limited to depth 10' 
    }
    // Admins have no limit
  ]
}

Common Patterns

1. Tiered Access

// Basic tier - public resources only
{ label: 'Public Data', value: 'public' },

// Standard tier - company resources
{ label: 'Company Data', value: 'company', tags: ['company-wide'] },

// Premium tier - sensitive resources
{ label: 'Sensitive Data', value: 'sensitive', tags: ['executives', 'admin-tools'] }

2. Department Isolation

// Each department only sees their own resources
{ label: 'Finance Reports', value: 'finance', tags: ['finance-team'] },
{ label: 'HR Documents', value: 'hr', tags: ['hr-team'] },
{ label: 'Engineering Specs', value: 'eng', tags: ['engineering-team'] }

3. Progressive Disclosure

// Basic options for everyone
{ label: 'Standard Search', value: 'standard' },

// Advanced options for power users
{ label: 'Advanced Search', value: 'advanced', tags: ['power-users'] },

// Experimental options for beta testers
{ label: 'Experimental Search', value: 'experimental', tags: ['beta-testers'] }

Troubleshooting

Options Not Showing

  1. Check if user has required tags:
    const userTags = getUserTagNames(availableTags, user);
    console.log('User tags:', userTags);
    
  2. Verify tag exists in the system:
    const allTags = await FirebaseService.getAllTags();
    console.log('System tags:', allTags.map(t => t.name));
    
  3. Check option configuration:
    console.log('Option tags:', option.tags);
    

Validation Issues

If validation seems incorrect:

  1. Check which tags the user has
  2. Verify validation rules are properly configured
  3. Ensure backend validates the same rules

Security Notes

Frontend Filtering

The tag-based filtering happens on the frontend for user experience. This is NOT a security measure by itself.

Backend Validation Required

ALWAYS validate on the backend that users have access to the resources they’re trying to use:

# Backend validation example
def validate_bucket_access(user_email, bucket_name, tag_permissions):
    bucket_tags = BUCKET_TAGS.get(bucket_name, [])
    if not bucket_tags:
        return True  # Public bucket
    
    user_tags = get_user_tags(user_email, tag_permissions)
    return any(tag in user_tags for tag in bucket_tags)

Audit Trail

Consider logging when users access restricted resources:

  • Which user accessed which resource
  • When the access occurred
  • Which tag granted the access

Best Practices

1. Clear Naming

Use descriptive names for restricted options:

{ label: 'Finance Reports (Restricted)', value: 'finance-reports', tags: ['finance-team'] }

2. Consistent Tag Usage

Use the same tags across related resources:

  • finance-team for all finance-related resources
  • admin-tools for all administrative functions

3. Documentation

Document which tags grant access to which resources:

## Resource Access Matrix

| Resource | Required Tags | Description |
|----------|--------------|-------------|
| finance-reports bucket | finance-team, admin-tools | Financial documents |
| legal-docs datastore | legal-team, admin-tools | Legal documents |
| customer-data preset | support-team, sales-team | Customer information |

4. Regular Reviews

Periodically review:

  • Which users have which tags
  • Which resources are restricted
  • Whether restrictions are still appropriate

Future Enhancements

Planned Features

  1. Tag Combinations: Require multiple tags (AND logic)
    tags: { all: ['finance-team', 'managers'] } // Requires both tags
    
  2. Excluded Tags: Deny access if user has certain tags
    tags: { not: ['contractors'] } // Not available to contractors
    
  3. Dynamic Options: Load options based on user’s tags
    options: async (userTags) => {
      return loadOptionsForTags(userTags);
    }
    
  4. Time-Based Access: Options available only during certain times
    tags: ['business-hours-only'],
    availability: { start: '09:00', end: '17:00' }
    

Migration Guide

To migrate existing tools to tag-based configuration:

  1. Identify Restricted Resources: List which buckets/datastores should be restricted

  2. Create Tags: Create appropriate tags in the admin interface

  3. Update Tool Definitions: Add tags to configuration options

  4. Test Access: Verify users see only appropriate options

  5. Update Backend: Ensure backend validates the new restrictions

  6. Document Changes: Update documentation with new access requirements