feat(cutover): Plan 8b — point void.hynesy.com at Void 2 (alpha.18)

CF Access multi-aud: CF_ACCESS_AUD now accepts a comma-separated
allow-list so requests through either the void.hynesy.com or
void2-app.hynesy.com CF Access app are honoured as owner. Fails
closed; unlisted auds rejected. Adds multi-aud test.

Void 1 (CT 301) becomes legacy but stays running untouched as an
instant rollback. -alpha tag kept pending owner sign-off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-05 00:50:57 +10:00
parent 191790098a
commit 147b4f514c
5 changed files with 19 additions and 3 deletions

View File

@@ -49,7 +49,12 @@ export async function verifyAccessJwt(jwt, { teamDomain, aud, fetchImpl = fetch,
const claims = b64urlJson(p);
const auds = Array.isArray(claims.aud) ? claims.aud : [claims.aud];
if (!auds.includes(aud)) throw new Error('aud mismatch');
// `aud` may be a single value or a comma-separated list (multiple CF Access
// apps front the same origin — e.g. void.hynesy.com and void2-app.hynesy.com
// during the 8b cutover). Accept the token if it carries ANY allowed aud.
const wanted = (Array.isArray(aud) ? aud : String(aud).split(','))
.map((a) => a.trim()).filter(Boolean);
if (!auds.some((a) => wanted.includes(a))) throw new Error('aud mismatch');
const t = Math.floor(now() / 1000);
if (claims.exp && t > claims.exp) throw new Error('expired');
if (claims.nbf && t < claims.nbf - 60) throw new Error('not yet valid');