All plugin docs

The Entitlement token

When the proxy calls a paid plugin, it sends a short-lived token that proves the profile is entitled to it:

Authorization: Bearer <token>

Free plugins are called with no token. A paid plugin should refuse any call without a valid one, so nobody can use it by calling your server directly.

What is in it

The token is a JWT signed with ES256. Its header names the signing key (kid); its claims are:

Claim Meaning
iss Always streamiva.
plugin_id Your plugin's id.
profile_token The install's opaque profile token: the same value as the request_id in the request body.
kind Why the profile is entitled: trial, monthly, one_time, legacy (grandfathered) or owner (you, testing).
iat When it was issued.
exp When it expires: a few minutes after iat.

The published key

The public keys are a JWKS at:

https://streamiva.net/v1/entitlements/jwks.json

Cache it, and fetch it again when a token names a kid you do not have: keys rotate.

Verifying it

Check, in this order:

  1. The signature, against the JWKS key named by kid, with ES256 only.
  2. iss is streamiva and exp has not passed.
  3. plugin_id is your plugin's id.
  4. profile_token equals the request's request_id, so a token cannot be replayed for another profile.

If any check fails, answer 401 and do nothing else.

Python

With PyJWT (pip install "pyjwt[crypto]"):

import jwt

JWKS_URL = "https://streamiva.net/v1/entitlements/jwks.json"
PLUGIN_ID = "your-plugin-id"

_jwks = jwt.PyJWKClient(JWKS_URL, cache_keys=True, lifespan=3600)


def verify_entitlement(authorization: str | None, request_id: str) -> dict | None:
    """The token's claims when the call is entitled, otherwise None."""
    if not authorization or not authorization.startswith("Bearer "):
        return None
    token = authorization.removeprefix("Bearer ")
    try:
        key = _jwks.get_signing_key_from_jwt(token)
        claims = jwt.decode(
            token,
            key.key,
            algorithms=["ES256"],
            issuer="streamiva",
            options={"require": ["exp", "iat", "iss", "plugin_id", "profile_token"]},
        )
    except jwt.PyJWTError:
        return None
    if claims["plugin_id"] != PLUGIN_ID or claims["profile_token"] != request_id:
        return None
    return claims

In a FastAPI handler:

claims = verify_entitlement(request.headers.get("authorization"), body.request_id)
if claims is None:
    raise HTTPException(401, "Not entitled")

Node

With jose (npm install jose):

import { createRemoteJWKSet, jwtVerify } from "jose";

const JWKS = createRemoteJWKSet(new URL("https://streamiva.net/v1/entitlements/jwks.json"));
const PLUGIN_ID = "your-plugin-id";

export async function verifyEntitlement(authorization, requestId) {
  if (!authorization?.startsWith("Bearer ")) return null;
  try {
    const { payload } = await jwtVerify(authorization.slice(7), JWKS, {
      issuer: "streamiva",
      algorithms: ["ES256"],
      requiredClaims: ["exp", "iat", "plugin_id", "profile_token"],
    });
    if (payload.plugin_id !== PLUGIN_ID || payload.profile_token !== requestId) return null;
    return payload;
  } catch {
    return null;
  }
}