← ClaudeAtlas

ekx-cloudflare-streamlisted

Signed video delivery with Cloudflare Stream for a paid course platform — RS256 JWT signing with jose, the PKCS#1 key gotcha, IP-pinned access rules, direct creator uploads, and the customer-code embed URL. Use when serving paid or gated video, minting a playback token, uploading video from an admin UI, or debugging a 401 on a Stream iframe.
Ekinoxis-evm/claude-skills · ★ 0 · DevOps & Infrastructure · score 60
Install: claude install-skill Ekinoxis-evm/claude-skills
# Cloudflare Stream Video delivery for a course platform. Courses are **paid**, so every video sits behind a signed URL; nothing is public. ## Setup ```bash npm i jose ``` ``` CF_STREAM_ACCOUNT_ID= # Cloudflare account id CF_STREAM_API_TOKEN= # API token with Stream:Edit CF_STREAM_KEY_ID= # signing key id CF_STREAM_PEM= # signing private key, BASE64-encoded CF_STREAM_CUSTOMER_CODE= # the customer-<code> subdomain ``` All server-only. `CF_STREAM_PEM` is base64 because a PEM's newlines do not survive most env-var UIs intact. ## Signing a playback token ```ts import { SignJWT } from "jose"; import { createPrivateKey } from "node:crypto"; export async function signStreamToken(videoUid: string, opts: { clientIp?: string } = {}) { const pem = Buffer.from(process.env.CF_STREAM_PEM!, "base64").toString("utf-8"); const privateKey = createPrivateKey(pem); const payload: Record<string, unknown> = { kid: process.env.CF_STREAM_KEY_ID }; if (opts.clientIp && opts.clientIp !== "unknown") { payload.accessRules = [ { type: "ip.src", ip: [`${opts.clientIp}/32`], action: "allow" }, { type: "any", action: "block" }, ]; } return new SignJWT(payload) .setProtectedHeader({ alg: "RS256", kid: process.env.CF_STREAM_KEY_ID }) .setSubject(videoUid) .setExpirationTime("1h") .setNotBefore(Math.floor(Date.now() / 1000) - 5) .sign(privateKey); } ``` ### Three non-obvious require