Skip to main content
Desktop capture handles sensitive data. Nothing records without explicit user consent. This page covers permission patterns, storage controls, and privacy-first design.

Quick Example

from videodb.capture import CaptureClient

client = CaptureClient(client_token=token)

# Request explicit permissions (OS dialogs appear)
await client.request_permission("microphone")
await client.request_permission("screen_capture")

# User must grant permission before capture can start
channels = await client.list_channels()

Trust Model

Two-Component Architecture

Security is built into the architecture:
ComponentHas API KeyCan See Media
BackendYesNo (receives events only)
Desktop ClientNo (uses token)Yes (captures locally)
  • API key never leaves your backend
  • Desktop client uses short-lived tokens (10-15 min expiry recommended)
  • Compromised tokens have limited blast radius

Token Pattern

# Backend (holds API key)
conn = videodb.connect()  # Uses VIDEODB_API_KEY

# Generate short-lived token for client
token = conn.generate_client_token(expires_in=600)  # 10 minutes

# Send token to desktop app (never send API key)

Permission Handling

Request Before Capture

# Each permission triggers an OS dialog
await client.request_permission("microphone")
await client.request_permission("screen_capture")
# For system audio on macOS
await client.request_permission("system_audio")

Required UX Elements

Your desktop client must include:
  • Recording indicator - Visual cue that capture is active
  • Pause button - Let users temporarily stop
  • Stop button - Let users end the session

Storage Control

Ephemeral Mode

Process in real-time without persisting media:
await client.start_session(
    capture_session_id=cap_id,
    channels=[
        {"name": "mic:default", "store": False},       # Process only
        {"name": "display:1", "store": False},         # Process only
        {"name": "system_audio:default", "store": False}
    ]
)
Use ephemeral mode when:
  • Processing sensitive content
  • Storage isn’t needed
  • Privacy regulations require it
  • Building real-time assistants only

Selective Storage

Store only what you need:
await client.start_session(
    capture_session_id=cap_id,
    channels=[
        {"name": "mic:default", "store": True},        # Keep for search
        {"name": "display:1", "store": False},         # Don't store screen
        {"name": "system_audio:default", "store": True}
    ]
)

Data Retention

Default Behavior

  • Media stored until explicitly deleted
  • No automatic expiration
  • Indexes and transcripts stored with media

Manual Deletion

# Delete capture session and all associated data
cap = conn.get_capture_session("cap-xxx")
cap.delete()

# Delete specific video
video = coll.get_video("m-xxx")
video.delete()

Implement Data Subject Access

def get_user_data(end_user_id):
    """Get all data for a user (GDPR access request)"""
    sessions = conn.list_capture_sessions(end_user_id=end_user_id)
    return {"sessions": [s.to_dict() for s in sessions]}

def delete_user_data(end_user_id):
    """Delete all user data (GDPR deletion request)"""
    sessions = conn.list_capture_sessions(end_user_id=end_user_id)
    for session in sessions:
        session.delete()

Compliance Patterns

GDPR

  • Implement data access endpoints
  • Implement deletion endpoints
  • Document processing purposes
  • Use ephemeral mode when storage isn’t needed

HIPAA

  • Use ephemeral mode for PHI
  • Implement strict access controls
  • Audit all data access
  • Consider data minimization

General Best Practices

PracticeImplementation
Never expose API keysUse client tokens
Default to ephemeralOnly persist when needed
Short token lifetimes10-15 minutes
Implement deletionHonor user requests
Get consentPermission dialogs before capture
Show indicatorsRecording visible to user

Summary

Key principles:
  • Nothing records without explicit user permission
  • Storage is optional per-channel (store: false)
  • Visible recording indicators are required
  • API key never leaves backend
  • Tokens are short-lived and limited scope

Next Steps