Skip to content

Serving Tokens

A Production Guide for Developers

This guide provides production-ready strategies to securely serve PulseBeam tokens to your users. Choose the method that aligns with your infrastructure and platform needs.

Why should I care about tokens?

Tokens allow your users to access PulseBeam. They are essential for maintaining a security.

Why should I care about Security

Exposing your secret key (sk_...) in client-side code (as we did in our quickstart) compromises all users (+ can affect your usage and bills)

Production environments must serve tokens via secure backend methods.

Key Risks to Avoid:

  • 🚫 Client-side secret key exposure
  • 🚫 Overprivileged token policies
  • 🚫 Unsecured endpoints

How to serve tokens?

In our quickstart, we have learned one way to get tokens to your users:

  1. ❗ Publish your project’s secret key into your client (absolutely insecure, you should not expose your secret key in your clients, this is for development only)

There are several ways to securely serve tokens:

  1. JS Server SDK (@pulsebeam/server package) for Node / Deno / Cloudflare environments.
  2. Use our rust src
  3. PulseBeam CLI. This can be used for development or for token generation where there is no other SDK available.

Implementation Options

Use Case: Existing JavaScript/TypeScript backend.

@pulsebeam/server Example usage

const { API_KEY, API_SECRET } = process.env;
const app = new AccessToken(API_KEY, API_SECRET);
router.post('/auth', (req, res) => {
const claims = new PeerClaims("myGroup1", "myPeer1");
const policy = new PeerPolicy("myGroup*", "*");
claims.setAllowPolicy(policy);
const ttlSeconds = 3600;
const token = app.createToken(claims, ttlSeconds);
res.json({ groupId: "myGroup1", token });
});

For more, checkout the @pulsebeam/server SDK documentation

Supported Platforms:

  • βœ… Node.js
  • βœ… Deno
  • βœ… Cloudflare Page Functions

Hosting Options:

  • Node/Deno Servers: Express, Fastify, etc.
  • Serverless: AWS Lambda, Cloudflare Page Functions, etc
  • Edge Networks: Fly.io, Vercel Edge, etc

Steps:

  1. Install SDK
  2. Create an API Endpoint
  3. Secure Your Endpoint
  4. Serve tokens

Security Notes:

  • πŸ”’ Always validate user sessions before issuing tokens
  • πŸ”’ Restrict token TTL (e.g., 1 hour instead of 24)
  • πŸ”’ Use environment variables for secrets

Example node.js http server

  1. Revisiting our Quickstart

    In our quickstart project we generated tokens client-side by embedding our secret key into the browser. For production, we cannot embed our secret key in our clients.

    So if you go back to that project, get your keys (or create new ones). This time were going to create our own auth endpoint.

  2. Serve it

    Terminal window
    git clone [email protected]:PulseBeamDev/pulsebeam-js.git
    cd pulsebeam-js/demo-cdn
    npm i
    export PULSEBEAM_API_KEY="kid_..."
    export PULSEBEAM_API_SECRET="sk_..."
    npm run start

    You should now have a server running locally on port 3000

  3. See it

    • Go to your browser open two tabs:
    • On the second tab enter peer-29 in the first text box. Then click connect.
    • Type text in the bottom text box in either tab. Changes will synchronize between peers in real-time using WebRTC data channels.

    Here’s what you should see:

  4. Understand it

    The same as our quickstart, we

    1. Started a server

      HTTP Server (localhost:3000)
      β”œβ”€β”€ / -> index.html - frontend code
      └── /auth - endpoint for token generation
    2. Experienced a Token Request Workflow

      index.html instructs browser to make a request to /auth for a token.

      Browser β†’ GET / -> index.html
      Browser β†’ Request Token from /auth

      Before the browser was accepting the private key. Which it used to call a remote PulseBeam endpoint instead of embedding the key in your server - local /auth endpoint

    3. Created tokens

      /auth uses @pulsebeam/server SDK with your environment variables to generate tokens.

      /auth β†’ @pulsebeam/server SDK β†’ Token β†’ Browser

Cloudflare Page Functions

  1. Follow Cloudflare setup to host on Cloudflare page functions. See Cloudflare docs.
  2. Create a Cloudflare Function. Checkout our example page function.
  3. Configure Environment Variables, add PulseBeam Keys.
  4. Secure Your Endpoint
  5. Serve tokens

2. Rust Direct Integration

Use Case: Existing Rust server, love πŸ¦€, High-performance, or compile to another WASM-compatible environment.

Checkout our Rust source.

Fun fact, our JS SDK @pulsebeam/server is compiled to WASM from this Rust src.

WASM-compatible environments:

  • βœ… Go
  • βœ… Java
  • βœ… PHP
  • βœ… C/C++
  • βœ… Python
βœ… More
  • βœ… AssemblyScript (a TypeScript-like syntax)
  • βœ… C#
  • βœ… Cobol
  • βœ… Dart
  • βœ… F#
  • βœ… Haskell
  • βœ… Kotlin
  • βœ… Moonbit
  • βœ… Swift
  • βœ… Scala.js
  • βœ… D
  • βœ… Pascal
  • βœ… RemObjects Elements
  • βœ… Zig
  • βœ… Grain
  • βœ… Scheme
  • βœ… Ada
  • βœ… Haskell

Example Rust usage

pub const SANDBOX_API_KEY: &str = "kid_<...>";
pub const SANDBOX_API_SECRET: &str = "sk_<...>";
pub const SANDBOX_DEFAULT_TTL: u32 = 3600;
pub fn router() -> Router {
let cors = CorsLayer::new()
.allow_methods([Method::POST])
.allow_headers([CONTENT_TYPE, ACCEPT_ENCODING, AUTHORIZATION])
.allow_origin(AllowOrigin::mirror_request())
.max_age(Duration::from_secs(86400));
Router::new().route("/token", post(token)).layer(cors)
}
#[derive(Deserialize, Debug, Validate)]
#[serde(rename_all = "camelCase")]
pub struct TokenForm {
pub api_key: String,
pub api_secret: String,
#[validate(regex(path = *RE_ID))] //^[a-zA-Z0-9_-]{1,36}$
pub group_id: String,
#[validate(regex(path = *RE_ID))]
pub peer_id: String,
}
async fn token(
ValidatedForm(form): ValidatedForm<TokenForm>,
) -> Result<impl IntoResponse, AppError> {
let claims = pulsebeam_core::PeerClaims {
group_id: form.group_id,
peer_id: form.peer_id,
allow_policy: Some(pulsebeam_core::PeerPolicy {
group_id: String::from("*"),
peer_id: String::from("*"),
}),
};
let token = pulsebeam_core::App::new(&form.api_key, &form.api_secret)
.create_token(&claims, SANDBOX_DEFAULT_TTL)
.context("failed to create sandbox token")?;
Ok(token)
}

Steps:

  1. (Optional) compile to your target language
  2. Import
  3. Create an API Endpoint
  4. Secure Your Endpoint
  5. Serve tokens

Security Notes:

  • πŸ”’ Always validate user sessions before issuing tokens
  • πŸ”’ Restrict token TTL (e.g., 1 hour instead of 24)
  • πŸ”’ Use environment variables for secrets

3. CLI for Non-JS Environments

Use Case: Nothing else works for me

See PulseBeam CLI Docs

You may want to wrap in a language of your choice.

Python example:

import subprocess
def create_pulsebeam_token(
api_key: str,
api_secret: str,
peer_id: str,
group_id: str,
allow_policy: str
) -> subprocess.CompletedProcess:
command = [
"./target/debug/pulsebeam-cli",
"--api-key", api_key,
"--api-secret", api_secret,
"create-token",
"--peer-id", peer_id,
"--group-id", group_id,
"--allow-policy", allow_policy
]
try:
result = subprocess.run(
command,
check=True,
text=True,
capture_output=True
)
return result
except subprocess.CalledProcessError as e:
print(f"Command failed with error: {e.stderr}")
raise

Example usage:

if __name__ == "__main__":
try:
response = create_pulsebeam_token(
api_key="your_api_key",
api_secret="your_api_secret",
peer_id="peer-1",
group_id="test",
allow_policy="test:peer-*"
)
print("Token created successfully!")
print(response.stdout)
except Exception as e:
print(f"Error creating token: {str(e)}")

Security Alert: πŸ” Avoid storing secrets in scripts. Use temporary credential injection

Security Best Practices

Mandatory Checks

  • Secret Management
  • Token Policies
    • Follow least privilege: PeerPolicy("chat:room-12", "user-*")
    • Avoid wildcard overuse: PeerPolicy("*", "*") when possible
  • Network Security
    • Serve tokens over HTTPS only
    • Rate-limit token endpoints (e.g., 10 requests/minute per user)
  • Monitoring
    • Alert on unexpected token volume spikes
    • Log token creation metadata (user ID, IP, policy)

Checkout our Full Security Checklist

πŸ” Remember: Your security is our priority, and a shared responsibility.

Troubleshooting

IssueSolution
Invalid secret formatCheck your key format or rotate your key
Token ExpiredImplement client-side renewal logic and/or extend TTL
Invalid PolicyValidate policy syntax and string format
Unauthorized Peer ConnectionsDouble-check policy rules, group, and peer IDs check PulseBeam Project usage and limits

Need Help?

  • Want an official SDK for your language/platform? Tell us.
  • Discuss ideas and designs? Book a call
  • Need platform-specific advice?
  • Contributions? See Repository

-> Contact us