Embedding Scoop

Embed Scoop dashboards in your SaaS application using JWT tokens

Developer Guide: Embedding Scoop

Scoop provides a secure, token-based system for embedding analytics dashboards (Canvases) directly into your own SaaS application. This allows you to present Scoop's powerful visualizations to your users without them needing a separate Scoop login.

🚀 How It Works

The embedding system uses JSON Web Tokens (JWT) signed with an RSA key pair (RS256).

  1. Generate Key Pair: You generate an RSA Key Pair. You keep the Private Key secret on your backend. You upload the Public Key to Scoop Admin.
  2. Sign Token: When your user visits your app, your backend generates a JWT signed with your Private Key. This token asserts the user's identity and permissions (e.g., "User X has read access to Workspace Y").
  3. Frontend Handshake: Your frontend passes this token to the Scoop Embed SDK.
  4. Validation: Scoop verifies the token signature using your uploaded Public Key and grants access.

🔑 1. Token Payload Structure

Your backend must generate a JWT with the following claims:

ClaimTypeDescription
issStringIssuer. Must match your Scoop App ID (e.g., my-saas-app).
subStringSubject. The unique User ID in your system (e.g., user_123).
workspace_idStringThe Scoop Workspace ID this user should access (e.g., W517).
inbox_idString(Optional) The specific Dataset ID to focus on.
permissionsArrayList of permissions. Usually ["read", "query"].
expNumberExpiration Time. Unix timestamp. We recommend short-lived tokens (e.g., 1 hour).
iatNumberIssued At. Unix timestamp.
jtiStringJWT ID. A unique nonce to prevent replay attacks.

Example Payload

{
  "iss": "my-saas-app",
  "sub": "user_88",
  "workspace_id": "W517",
  "permissions": ["read", "query"],
  "exp": 1735689600,
  "iat": 1735686000,
  "jti": "unique-request-id-555"
}

💻 2. Generating the Token (Python Example)

Here is a Python script using PyJWT to generate a valid token.

import jwt
import time
import uuid

# Your RSA Private Key (PEM format)
PRIVATE_KEY = """-----BEGIN RSA PRIVATE KEY-----
... your private key content ...
-----END RSA PRIVATE KEY-----"""

def generate_embed_token(user_id, workspace_id):
    payload = {
        "iss": "my-saas-app",
        "sub": user_id,
        "workspace_id": workspace_id,
        "permissions": ["read", "query"],
        "iat": int(time.time()),
        "exp": int(time.time()) + 3600, # Expires in 1 hour
        "jti": str(uuid.uuid4())
    }
    
    # Sign with RS256
    token = jwt.encode(payload, PRIVATE_KEY, algorithm="RS256")
    return token

# Usage
token = generate_embed_token("user_123", "W517")
print(token)

🎨 3. Frontend Integration

Once your backend generates the token, pass it to your frontend. Use the Scoop React SDK (or an iFrame) to render the canvas.

import { ScoopCanvas } from '@scoop-analytics/react-embed';

function MyAnalyticsDashboard({ embedToken }) {
  return (
    <div style={{ height: '800px' }}>
      <ScoopCanvas 
        token={embedToken}
        canvasId="C_SALES_DASHBOARD"
        width="100%"
        height="100%"
      />
    </div>
  );
}

🔒 Security Best Practices

  • Never expose your Private Key in frontend code. Token generation must happen server-side.
  • Use short expiration times (exp). If a token is leaked, it should become useless quickly.
  • Restrict Workspace IDs. Ensure your code only issues tokens for the Workspace ID associated with that specific customer tenant.