Privacy & Security
Control what browser context is captured, how it's filtered, and who can access it
Privacy is foundational to Periscope's design, not an afterthought. Browser context contains sensitive information — browsing history, form inputs, text selections — so Periscope applies privacy filtering at two layers before data reaches any agent.
For the full conceptual guide to Periscope's privacy architecture, see the Privacy Model.
Privacy Levels
Every browser context synced through Periscope has a privacy level that controls how it can be accessed and what processing is applied.
| Level | Behavior | Use case |
|---|---|---|
public | Context available to all agents associated with the user. Content stored as-is after standard PII redaction. | General browsing, documentation, public websites |
private | Context available only to the user's own direct requests. Not shared with third-party agents. | Personal email, social media, private documents |
restricted | Context available only to explicitly authorized agents. Requires agent-level permissions. | Workplace tools, internal dashboards |
filtered | Content heavily sanitized before storage. Form data stripped, selections anonymized, URLs preserved but content removed. | Banking, healthcare, any sensitive domain |
How Privacy Levels Are Assigned
Privacy levels are set through three mechanisms, in order of precedence:
- Domain rules — The browser extension matches URL patterns against configured rules (e.g.,
*.bank.com → filtered,mail.google.com → private) - Extension defaults — If no domain rule matches, the extension's default privacy level applies (configurable in extension settings)
- Manual override — The sync API accepts a
privacyLevelfield, allowing custom integrations to set levels explicitly
See the Extension Setup Guide for configuring domain-based privacy rules.
Two-Layer Filtering Pipeline
Periscope filters sensitive data at two independent layers. Even if one layer is bypassed (e.g., a custom integration skipping the extension), the service layer catches sensitive content before it's stored or served.
Layer 1: Extension-Side Filtering
Before any data leaves the browser, the extension:
- Blocks restricted domains entirely (configurable URL patterns that are never captured)
- Strips form passwords — Password fields (
type="password") are never captured - Removes hidden fields — Hidden form inputs are excluded
- Applies domain rules — Maps URLs to privacy levels based on configured patterns
- Filters by content type — Optionally excludes images, media, or specific element types
This layer runs in the extension's content script and service worker, so sensitive data never leaves the browser for blocked domains.
Layer 2: Service-Side Filtering
When context arrives at the Periscope service (via REST or WebSocket), additional filtering is applied:
- PII redaction — Detects and redacts patterns matching email addresses, phone numbers, SSNs, credit card numbers, and API keys
- Content sanitization — For
filteredprivacy level, strips content body and retains only URL and title metadata - Form data filtering — Removes form field values, keeping only field names and types (for understanding form structure without capturing user input)
- URL parameter scrubbing — Removes sensitive query parameters (
token,key,password,secret,auth) from stored URLs
PII Patterns
The service-side filter detects these patterns by default:
| Pattern | Example | Redacted to |
|---|---|---|
| Email addresses | user@example.com | [EMAIL_REDACTED] |
| Phone numbers | +1-555-123-4567 | [PHONE_REDACTED] |
| SSN / Tax IDs | 123-45-6789 | [SSN_REDACTED] |
| Credit card numbers | 4111-1111-1111-1111 | [CC_REDACTED] |
| API keys / tokens | sk-abc123... | [KEY_REDACTED] |
PII redaction applies to all privacy levels including public. The patterns use regular expressions and are not exhaustive — they catch common formats but may miss edge cases. For maximum privacy, use filtered or restricted privacy levels on sensitive domains.
User Isolation
Periscope enforces strict user isolation at every layer:
- Users can only access their own browser contexts — there is no cross-user access
- API keys are scoped to a single user
- WebSocket connections are authenticated per-user
- Context queries are automatically filtered by the authenticated user's ID
- Even admin APIs cannot access user context without explicit authorization
Attempting to access another user's context returns a 403 Forbidden error.
Data Retention
Browser context data follows these retention policies:
| Data type | Default retention | Configurable | Notes |
|---|---|---|---|
| Full page content | 30 days | Yes | Text content, selections, form metadata |
| URL and title metadata | 90 days | Yes | Lightweight metadata preserved longer for search |
| Tab events | 7 days | Yes | Tab open/close/activate events |
| Search index | 30 days | Yes | Full-text search index entries |
Contexts can be deleted at any time using DELETE /context/{contextId}. Deletion is permanent and removes the context from all storage layers including the search index.
Authentication
All API access requires authentication via Bearer token:
Authorization: Bearer YOUR_API_KEY
- API keys are generated through the Lovelace Developer Portal
- Keys can be scoped to specific Periscope operations (
read,write,delete) - Keys can be rotated without downtime — issue a new key before revoking the old one
- Failed authentication attempts are rate-limited to prevent brute-force attacks
Transport Security
| Control | Details |
|---|---|
| TLS | All production traffic uses TLS 1.3 |
| WebSocket | Production connections require wss:// (TLS-encrypted WebSocket) |
| API keys | Transmitted only in Authorization header, never in URLs or response bodies |
| CORS | Restricted to allowed origins; the browser extension bypasses CORS via its service worker |
| Local development | http://localhost:* origins are allowed when the service runs in development mode |
Rate Limiting
To prevent abuse, Periscope enforces per-user rate limits:
| Endpoint category | Limit | Scope |
|---|---|---|
Context sync (POST /context/sync) | 60 requests/minute | Per user |
Context queries (GET /context/*) | 120 requests/minute | Per user |
| WebSocket messages | 100 messages/minute | Per connection |
Rate limit headers are included in all REST responses:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 115
X-RateLimit-Reset: 1709380800
When you receive a 429 response, check the X-RateLimit-Reset header (Unix timestamp) and retry after that time. The SDKs handle rate limiting automatically with exponential backoff.
Security Best Practices
- Use scoped API keys — Create keys with only the permissions your agent needs (
readfor most agents) - Configure domain rules — Block sensitive domains (banking, healthcare) at the extension level
- Prefer
restrictedorfiltered— For any domain where content sensitivity is uncertain - Rotate keys regularly — Issue new keys periodically and revoke old ones
- Monitor access patterns — Unusual spikes in context queries may indicate key compromise
- Don't log context content — Avoid logging raw page content in your agent; log only metadata (URL, title, context type)
Next Steps
- Privacy Model — Deep dive into the four privacy levels and filtering pipeline
- Extension Setup — Configure domain rules and privacy defaults
- Getting Started — Set up Periscope and make your first API call
- REST API Reference — Full endpoint documentation