OAuth Integration

Security & Data Integrity

How Euler Stream OAuth protects user sessions with envelope encryption and zero-knowledge architecture.

Security is at the core of the Euler Stream OAuth system. This document explains our security architecture, why your users' TikTok sessions are protected even in worst-case scenarios, and what this means for your integration.

Zero-Knowledge Session Storage

When a user authenticates via QR code, their TikTok session credentials are never stored in plaintext — not in our database, not in logs, not anywhere. Here's why this matters:

The Problem with Traditional Storage

In a typical OAuth system, session credentials are stored in a database, possibly encrypted with a master key. If an attacker gains database access and the master key, they can decrypt all user sessions.

Our Solution: Envelope Encryption

Euler Stream uses envelope encryption where the decryption keys are derived from the tokens themselves:

What This Means

  1. Database breach = useless data: If an attacker compromises our database, they get encrypted blobs that cannot be decrypted without the corresponding tokens (which are only held by your application).

  2. Zero-knowledge architecture: Even we, the operators of Euler Stream, cannot decrypt user sessions. We do not have access to the tokens stored in your application.

  3. Decryption only in memory: The session ID only exists in decrypted form in RAM during active API requests. It is never written to disk, logs, or persistent storage in plaintext.

  4. Per-session isolation: Each user's session has a unique DEK. Compromising one doesn't affect others.

  5. Dual-key recovery: Both the access token and refresh token can independently decrypt the session. This means refreshing your access token doesn't break session access, and API requests work with just the access token.

Security Implications for Your Application

Because of this architecture, you are responsible for secure token storage:

Token Security Best Practices

// ❌ BAD: Storing tokens in plaintext
await db.users.update({
  id: userId,
  tiktokAccessToken: tokens.access_token,
  tiktokRefreshToken: tokens.refresh_token,
});

// ✅ GOOD: Encrypt tokens at rest
import { createCipheriv, createDecipheriv, randomBytes } from 'crypto';

const ENCRYPTION_KEY = process.env.TOKEN_ENCRYPTION_KEY!; // 32 bytes

function encryptToken(token: string): string {
  const iv = randomBytes(16);
  const cipher = createCipheriv('aes-256-gcm', Buffer.from(ENCRYPTION_KEY, 'hex'), iv);

  let encrypted = cipher.update(token, 'utf8', 'hex');
  encrypted += cipher.final('hex');

  const authTag = cipher.getAuthTag();

  return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
}

function decryptToken(encryptedData: string): string {
  const [ivHex, authTagHex, encrypted] = encryptedData.split(':');

  const decipher = createDecipheriv(
    'aes-256-gcm',
    Buffer.from(ENCRYPTION_KEY, 'hex'),
    Buffer.from(ivHex, 'hex')
  );

  decipher.setAuthTag(Buffer.from(authTagHex, 'hex'));

  let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');

  return decrypted;
}

Additional Security Measures

  1. Use environment variables for client secrets, never commit them
  2. Implement rate limiting on your OAuth callback endpoint
  3. Validate the state parameter to prevent CSRF attacks
  4. Use HTTPS everywhere (required for redirect URIs except localhost)
  5. Rotate your client secret periodically via the dashboard
  6. Audit access logs to detect suspicious activity

What Happens If...

Your Database Is Breached

If your application's database is compromised and tokens are stolen:

  1. The attacker can use the tokens to make API requests as your users
  2. Immediately regenerate your client secret in the Euler Stream dashboard
  3. Revoke compromised tokens via the revoke endpoint
  4. Users will need to re-authorize

Euler Stream's Database Is Breached

If Euler Stream's database is compromised:

  1. Attackers get encrypted session blobs
  2. These cannot be decrypted without your users' tokens
  3. No user sessions are compromised
  4. No action required from you (but we'd notify you anyway)

A User's Tokens Are Leaked

If a specific user's tokens are leaked:

  1. Revoke those tokens immediately via the revoke endpoint
  2. The user must re-authorize
  3. Other users are unaffected

Token Transmission Security

HTTPS Requirement

All OAuth endpoints use HTTPS. Redirect URIs must also use HTTPS in production (localhost is exempt for development convenience, per RFC 8252).

Logging and Debugging

What We Log

  • Request metadata (timestamp, endpoint, response code)
  • Client ID (to identify your application)
  • Error messages (without sensitive data)

What We Never Log

  • Access tokens or refresh tokens
  • Session IDs (encrypted or plaintext)
  • QR code contents
  • User credentials of any kind

Your Logging

Ensure your application doesn't accidentally log tokens:

// ❌ BAD: Logging the full response
console.log('Token response:', tokenResponse);

// ✅ GOOD: Log only safe data
console.log('Token exchange successful', {
  expiresIn: tokenResponse.expires_in,
  scopes: tokenResponse.scopes,
});

Security Summary

LayerProtection
Session StorageEnvelope encryption with per-session DEK
Database Breach (Euler Stream)Sessions unrecoverable without client tokens
Database Breach (Your App)Depends on your encryption implementation
Developer AccessZero-knowledge: we cannot access user sessions
Token RecoveryEither access OR refresh token can decrypt session
In MemorySessions decrypted only in RAM during requests

Reporting Security Issues

If you discover a security vulnerability:

  1. Do not disclose it publicly
  2. Email security concerns to the development team
  3. Include steps to reproduce
  4. We'll respond within 48 hours