Files
skills/docs/networking/drive/drive-template/src/cdn/upload-token.md
2026-05-29 08:20:56 +01:00

2.7 KiB

upload-token

Purpose

Implements CdnUploadToken issuance and verification (DTP-19). Tokens authorise a single chunk write to the CDN and carry a server signature over the canonical bytes plus a content-hash binding so the CDN can refuse to store anything other than what the server attested.

Features

  • signUploadToken(token, serverSecretKey, options?) — fills expiresAt from the injected Clock + ttlMs and signs.
  • verifyUploadToken(token, serverPubkeyHex, clock) — full check: expiry, hex decode, Ed25519 verify.
  • canonicalSerializeUploadToken(token) — deterministic byte-level encoding shared by issuer and verifier.
  • UPLOAD_TOKEN_TTL_DEFAULT_MS (60 s), UPLOAD_TOKEN_TTL_MAX_MS (300 s) — pinned constants the spec dashboards can reference.

Usage: Basic Example

import {
    signUploadToken,
    verifyUploadToken,
} from "@suaveplan/drive-template";

const tok = signUploadToken(
    {
        fileId,
        chunkId: 0,
        chunkHash: "blake3:abc",
        uploaderPubkey: peerId,
    } as never,
    serverSecretKey,
    { clock: () => Date.now() }
);
verifyUploadToken(tok, serverPubkeyHex, () => Date.now());

Usage: Advanced Example

import {
    DTP_CODES,
    DriveTemplateError,
    signUploadToken,
    verifyUploadToken,
} from "@suaveplan/drive-template";

async function handleCdnUpload(token, body) {
    try {
        verifyUploadToken(token, serverPubkeyHex, () => Date.now());
    } catch (err) {
        if (err instanceof DriveTemplateError && err.code === DTP_CODES.CDN_BAD_SIGNATURE) {
            return new Response("forbidden", { status: 403 });
        }
        throw err;
    }
    if (`blake3:${blake3Hex(body)}` !== token.chunkHash) {
        return new Response("hash mismatch", { status: 422 });
    }
    return store(token.fileId, token.chunkId, body);
}

API Reference

  • signUploadToken(token, serverSecretKey, options?: { clock: Clock; ttlMs?: number }): CdnUploadToken.
  • verifyUploadToken(token: CdnUploadToken, serverPubkeyHex: string, clock: Clock): true.
  • canonicalSerializeUploadToken(token: Omit<CdnUploadToken, "serverSignature">): Uint8Array.
  • Constants: UPLOAD_TOKEN_TTL_DEFAULT_MS, UPLOAD_TOKEN_TTL_MAX_MS.

Implementation Notes

The TTL upper bound is enforced at sign time to prevent a misconfigured caller from minting tokens that outlive the request that asked for them. Verification trusts @noble/curves to return false for malformed signatures — there's no separate try/catch, which removes a dead branch and keeps the success path branch-free in the hot path. The CDN-side replay protection (the (fileId, chunkId, nonce) short LRU mentioned in DTP-19) lives in the CDN service rather than this module; the protocol only mandates the token shape.