Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Volly gated-app origin verification — reference implementation

Your app stays where it is hosted today; Volly gates who reaches it. Every request Volly proxies to your origin carries a short-lived, ES256-signed JWT in the X-Volly-Jwt header identifying the signed-in viewer. Your origin is the enforcement point: Volly does not sit between your origin and the open internet, so a request without a valid token must be rejected by your code.

This directory is the canonical, dependency-free implementation of that check. Copy verify.mjs into your project (or let your coding agent reproduce it in your framework — see SKILL.md).

The verification contract

Reject the request unless ALL of these hold:

Check What skipping it means
A token is present in X-Volly-Jwt anyone on the internet reaches your app
Its signature verifies against Volly's published JWKS anyone can forge a viewer token
aud equals your app's canonical URL a token minted for another gated app grants access here
It is not expired a leaked token works forever

Volly's activation gate probes your origin for exactly these four behaviors — your app will not serve traffic through Volly until all of them pass.

Configuration

  • JWKS URL: https://app.volly.so/.well-known/volly-jwks.json
  • Issuer (iss): https://volly.so
  • Audience (aud): your app's canonical URL, https://{org}-{app}.volly.so — shown on your project's settings page. Pin it as a constant; never accept any other value.
  • Token lifetime: ≤ 5 minutes, minted per proxied request. Cache the JWKS (the reference implementation caches for 5 minutes) but never cache a verification result across requests.

Verified claims

After verification the token's payload gives you the viewer's identity:

{
  "sub": "viewer@customer.com",
  "email": "viewer@customer.com",
  "org_id": "",
  "app_id": "",
  "iss": "https://volly.so",
  "aud": "https://acme-crm.volly.so",
  "iat": 1710000000,
  "exp": 1710000300
}

Use email for per-user behavior; it is verified by Volly's viewer gate.

Usage

import { createVollyVerifier } from "./verify.mjs";

const verifyVollyToken = createVollyVerifier({
  audience: "https://acme-crm.volly.so", // YOUR app's URL — pin it
});

// Express-style middleware
app.use(async (req, res, next) => {
  const viewer = await verifyVollyToken(req.get("x-volly-jwt"));
  if (!viewer) {
    return res.status(401).send("Unauthorized");
  }
  req.viewer = viewer; // { sub, email, org_id, app_id }
  next();
});

Any framework works the same way: read the X-Volly-Jwt header, call the verifier, respond 401 when it returns null. Apply it to every route — including static assets, API routes, and health endpoints you don't want public. A single unprotected route is an unprotected app.

What this code will never do

No telemetry, no phone-home, no dependencies. It fetches Volly's public JWKS and nothing else. Read it — it is one file.

About

Example code for verifying a Volly gated app

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages