Application Security

Capability Tokens Authorize Actions, Not Merely Identity

Encode resource, action, audience, expiry, and constraints in unforgeable capability tokens for least-privilege screen viewing, one-file receive, and TURN quota.

The dangerous implementation is not one that never works. It is one that works in a demo and loses its boundaries under real networks and real data volume. Identity answers who the actor is; a capability says what its holder can do to a resource. It must be non-amplifiable and audience-bound.

Security review starts with assets, attacker capability, and trust boundaries, then reauthorizes every state transition. Validation, rate limits, and audit complement rather than replace authorization.

Engineering boundaries and tradeoffs

Turn the important choices into durable contracts: validate inputs, assign state ownership, define cleanup, and specify fallback for older peers. Later optimization must not change those semantics.

  • Claims include resourceId, actions, audience, notBefore, expiresAt, and random jti; sensitive capabilities are short lived with revocation or one-time consumption.
  • Define success, degraded, cancelled, and failed terminal states before UI, storage, and metrics consume the same state.
  • Retries need an idempotency key, backoff, and deadline; after the deadline create a new task instead of reviving old callbacks.

The delivery standard for Capability Tokens Authorize Actions, Not Merely Identity is a usable normal path, convergent failures, bounded resources, and a state users can understand. The result is a production capability that can be explained, degraded safely, and rolled back—not a demo that works once.

How it fails in production

Failure and success must share one state model. An error toast that neither releases resources nor propagates a terminal state leaves dirty work for the next recovery attempt.

  • Authorization by an unguessable URL leaks through logs and referrers, while wildcard resources or actions let a view token gain control.
  • Fixing only the UI leaves queues, locks, or expired credentials for the next operation to inherit and fail again.
  • User or task IDs in metric labels create high-cardinality cost and leak unnecessary identity into diagnostics.

Turn testing into a closed loop

Do not stop verification when the final action succeeds. Count side effects, measure wait time, inspect privacy, and prove the next run begins from a clean baseline.

  1. Tamper resource, action, audience, time, and jti, then reuse a one-shot token; every privilege expansion and replay must fail.
  2. Drive the state machine with reordered, duplicate, and delayed messages, proving stale versions are ignored and explicit stop survives recovery.
  3. Use fault injection to prove alerts precede user reports and operators can locate the failing phase from bounded evidence.

The release standard is practical: the normal path is fast, abnormal paths converge, recovery never overrides an explicit user decision, and operators can diagnose faults from limited, privacy-safe evidence.

Put the guide to work

Open uCopy and connect two devices securely from the browser.

Start for free