Skip to content

[SIP] Proposal for Guest User Attributes in Embedded Dashboards #33922

Open
@Yash2412

Description

@Yash2412

[SIP] Proposal for Guest User Attributes in Embedded Dashboards

Motivation

Currently, embedded Superset dashboards using guest tokens have limited capabilities for user-specific data filtering. While Row Level Security (RLS) provides some filtering mechanisms, there's no way to pass dynamic user attributes that can be used in dataset SQL queries through Jinja templating.

This limitation affects:

  • Multi-tenant SaaS applications that need tenant-specific data filtering
  • Enterprise deployments requiring role-based or department-based data access
  • Geographic restrictions where data should be filtered by user's region/country
  • Personalized analytics where data should be customized per user context

The current workaround of using RLS rules is static and doesn't allow for dynamic, user-context-aware filtering that can be controlled at the application level when generating guest tokens.

Proposed Change

Add support for user attributes in guest tokens and corresponding Jinja macro to access these attributes in dataset queries.

Backend Changes

  1. Extend Guest Token Schema: Add attributes field to guest token structure
  2. Update GuestUser Class: Store attributes in the GuestUser instance
  3. API Schema Updates: Add validation for the new attributes field

Frontend/Templating Changes

  1. New Jinja Macro: Add get_guest_user_attribute(attribute_name, default=None) macro
  2. Cache Integration: Ensure attributes are properly included in cache keys

Usage Example

Guest Token Creation:

guest_token = security_manager.create_guest_access_token(
    user={
        "username": "external_user",
        "attributes": {
            "tenant_id": "company_123",
            "region": "us-west",
            "access_level": "standard"
        }
    },
    resources=[{"type": "dashboard", "id": "dashboard-uuid"}],
    rls=[]
)

SQL Query Usage:

SELECT * FROM sales_data 
WHERE tenant_id = '{{ get_guest_user_attribute("tenant_id") }}'
  AND region = '{{ get_guest_user_attribute("region", "global") }}'
  AND access_level >= {{ get_guest_user_attribute("access_level", "1") }}

New or Changed Public Interfaces

REST API Changes

  • Guest Token API (/api/v1/security/guest_token/): Accept optional attributes field in user object
  • Request Schema: Update UserSchema to include attributes field validation

Python API Changes

  • GuestTokenUser TypedDict: Add attributes: Dict[str, Any] field
  • GuestUser Class: Add self.attributes property
  • create_guest_access_token(): Support attributes in user parameter

Jinja Template Interface

  • New Macro: get_guest_user_attribute(attribute_name, default=None)
  • Cache Key Integration: Attributes automatically included in query cache keys

No Changes Required

  • No changes to existing visualizations, dashboards, or React components
  • No changes to Superset CLI or deployment process

New Dependencies

No new dependencies required.

This feature uses existing Python standard library functionality:

  • Type hints (already used throughout codebase)
  • JSON serialization (already used for guest tokens)
  • Jinja2 templating (already core dependency)

Migration Plan and Compatibility

Backward Compatibility

  • Fully backward compatible: New attributes field is optional
  • Existing guest tokens continue to work without modification
  • Default behavior: get_guest_user_attribute() returns None for non-guest users
  • Graceful degradation: Missing attributes return default values

Migration Steps

  1. Phase 1: Deploy backend changes (guest token structure)
  2. Phase 2: Deploy Jinja macro support
  3. Phase 3: Update documentation and examples

No Database Migrations Required

  • Guest tokens are JWT-based (stateless)
  • No database schema changes needed
  • No stored URL updates required

Rejected Alternatives

Alternative 1: Extend RLS Rules

Approach: Add dynamic parameters to RLS rules
Rejected because:

  • RLS rules are meant for security, not dynamic filtering
  • Would complicate RLS rule syntax
  • Less flexible than Jinja templating approach

Alternative 2: Add to Request Headers

Approach: Pass attributes via HTTP headers
Rejected because:

  • Headers are not cached with query results
  • Less secure than JWT-embedded attributes
  • Would require changes to all client implementations

Alternative 3: Database-stored User Attributes

Approach: Store guest user attributes in database
Rejected because:

  • Violates stateless nature of guest tokens
  • Adds complexity with user management
  • Creates dependency on database for embedded use cases

Alternative 4: Configuration-based Attributes

Approach: Define attributes in Superset configuration
Rejected because:

  • Not dynamic per user
  • Requires Superset restart for changes
  • Doesn't solve multi-tenant use case

The proposed solution provides the best balance of:

  • Flexibility: Any JSON-serializable attributes
  • Security: Embedded in signed JWT tokens
  • Performance: Proper cache key integration
  • Simplicity: Minimal code changes, no new dependencies
  • Compatibility: Fully backward compatible

Metadata

Metadata

Assignees

No one assigned

    Labels

    change:backendRequires changing the backendchange:frontendRequires changing the frontendglobal:jinjaRelated to Jinja templatingsipSuperset Improvement Proposal

    Type

    No type

    Projects

    Status

    Pre-discussion

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions