Authentication overview

Stream's architecture for authenticating requests relies on a combination of API keys and client-side user tokens. This dual approach differentiates between server-to-server communication, which often uses API keys for administrative tasks, and client-to-server interaction, which uses time-limited, user-specific tokens. The client-side tokens are crucial for ensuring that individual users can only access their permitted resources within the application, such as their chat messages or activity feed data, without exposing sensitive server-side credentials directly to end-user devices Stream JavaScript client authentication guide.

The core principle involves the application backend generating a user token (a JSON Web Token or JWT) for each authenticated user within the application. This token is then passed to the client-side Stream SDK, which uses it to authenticate all subsequent API calls. API keys, in contrast, are typically used by the backend server for operations that require higher privileges, such as creating new users or channels, and must never be exposed publicly Stream backend token generation documentation.

Supported authentication methods

Stream primarily supports two authentication methods for its Chat, Feeds, and Video APIs:

  • API Keys: Used for identifying the application making the request. These keys are typically public but are paired with a secret for server-side operations that require signing user tokens or making administrative API calls.
  • User Tokens (JWT): JSON Web Tokens are generated server-side by the application and provided to the client-side Stream SDKs. These tokens contain information about the user, their permissions, and an expiration time. They are signed with the application's API secret, ensuring their authenticity and integrity Stream Node.js token explanation.

The choice of method depends on the context of the API call:

  • Client-Side (e.g., mobile apps, web browsers): Always use user tokens. The Stream SDKs handle the attachment of these tokens to API requests, ensuring that client applications do not directly expose the application's API secret.
  • Server-Side (e.g., backend services, webhooks): May use a combination of API keys and API secrets for administrative tasks, or to generate user tokens. Direct API key usage for server-to-server calls often involves signing requests or including the secret in an Authorization header, depending on the specific API endpoint and SDK Stream Python SDK authentication guide.

Authentication methods overview

Method When to Use Security Level
API Key (Public) Client-side identification (often paired with a user token for authorization), generally visible in requests. Low (Identifies application, not sufficient for authorization alone)
API Secret Server-side for signing JWTs, administrative API calls, never exposed client-side. High (Critical for token integrity and application control)
User Token (JWT) Client-side authorization for specific users; generated server-side, short-lived. High (Encapsulates user identity and permissions securely)

Getting your credentials

Your Stream API credentials, including your API Key and API Secret, are managed within the Stream Dashboard. These credentials are project-specific and are essential for initializing Stream SDKs and generating user tokens.

  1. Access the Stream Dashboard: Log in to your Stream account Stream Dashboard login.
  2. Navigate to your Project: From the dashboard, select the specific project you are working on (e.g., Chat, Feeds, or Video).
  3. Locate API Keys: Within your project settings, you will find a section dedicated to API keys. Here, your application's API Key (public identifier) and API Secret (private key) are displayed Stream client-side authentication guide.

Important Security Note:

  • The API Key is generally considered public and can be included in client-side code to identify your application.
  • The API Secret must be kept strictly confidential and only used on your trusted backend servers. Exposing your API Secret client-side would compromise the security of your application, allowing unauthorized users to impersonate others or manipulate data Stream security warning on API secret.

Authenticated request example

Authenticating with Stream involves two main steps: generating a user token on your server and then using that token with a client-side SDK. The following example demonstrates how to generate a token using a Node.js backend and then initialize a Stream Chat client in JavaScript with that token.

Server-side token generation (Node.js)

This Node.js example shows how to use the stream-chat server SDK to create a user token. Replace YOUR_API_KEY and YOUR_API_SECRET with your actual credentials, and user_id with the ID of the user you want to authenticate.


const StreamChat = require('stream-chat').StreamChat;

const api_key = 'YOUR_API_KEY';
const api_secret = 'YOUR_API_SECRET';

const serverClient = StreamChat.getInstance(api_key, api_secret);

// user_id should be unique to your application's user
const user_id = 'jessica_smith';

// Generate a token for the user
const token = serverClient.createToken(user_id);

console.log('Generated token:', token);
// This token should be sent to your client-side application.

Client-side initialization (JavaScript)

Once your backend provides the token, your client-side JavaScript application can initialize the Stream Chat client. This example assumes you have the public api_key and the generated token available in your client-side environment.


import { StreamChat } from 'stream-chat';

const api_key = 'YOUR_API_KEY'; // Your public API Key
const user_id = 'jessica_smith'; // Must match the user_id used to generate the token
const token = 'GENERATED_TOKEN_FROM_YOUR_SERVER'; // The token received from your backend

const client = StreamChat.getInstance(api_key);

// Connect the user using the token
await client.connectUser(
  { id: user_id, name: 'Jessica Smith', image: 'https://getstream.io/random_png/' },
  token,
);

console.log('Stream Chat client connected:', client.connectedUsers.current.id);
// Now you can interact with Stream's chat APIs securely.

This separation ensures that sensitive credentials remain server-side, while client applications operate with limited, time-bound access Stream JavaScript client connection guide.

Security best practices

Adhering to security best practices is essential when integrating Stream's APIs into your application. Proper authentication and authorization help protect user data and maintain the integrity of your services.

  • Keep your API Secret confidential: Never expose your Stream API Secret in client-side code, public repositories, or environment variables accessible to the client. It should only reside on your secure backend servers Stream's explicit security warning.
  • Generate user tokens server-side: Always generate JWTs for client-side authentication on your trusted backend. This ensures that the token is signed with your API Secret securely and that you have full control over the user's permissions and lifespan of the token.
  • Use short-lived user tokens: Configure your user tokens to have a reasonable expiration time. If a token is compromised, its utility to an attacker is limited by its short lifespan. Stream's createToken method allows specifying an expiration, typically 1 to 24 hours Stream token generation options.
  • Implement proper access control: When generating user tokens, define the specific permissions each user truly needs. Stream's tokens support granular permissions, allowing you to restrict actions like reading, writing, or managing channels Stream custom token permissions.
  • Secure API Key storage: While the API Key is public, it's still good practice to store it securely, perhaps using environment variables or a configuration management system, rather than hardcoding it directly into client-side build artifacts.
  • Regularly rotate API Secrets: Periodically rotate your API Secret in the Stream Dashboard and update it in your backend services. This mitigates risks in case a secret is inadvertently exposed.
  • Utilize HTTPS/TLS: All communication with Stream's APIs occurs over HTTPS, ensuring data in transit is encrypted. Verify that your application also enforces HTTPS for all client-server communication, especially when transmitting user tokens Mozilla's TLS definition.
  • Validate webhooks: If you use Stream webhooks, ensure you validate incoming requests to confirm they originate from Stream. This typically involves verifying a signature provided in the webhook header.