Milestone 0: import zappier billing, Verae middleware, and Zapier research

Compose-ready workspace: packages/zappier (rate card, portal, Stripe),
packages/verae-zapier-middleware (timestamp + NATS), packages/verae-zapier
(CLI app), vendor/zapier-platform, and research/zapier vendor corpus.

Gate 0 structure checks pass. Product code and research are not yet wired.
This commit is contained in:
George Lambert 2026-09-09 02:37:36 -04:00
commit b4150c8250
1364 changed files with 6814366 additions and 0 deletions

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="1100" height="560"
viewBox="0 0 1100 560" role="img" aria-label="Two-hop authentication">
<title>Two-hop authentication</title>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5"
markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#1A6B6B"/>
</marker>
<marker id="arrow-navy" viewBox="0 0 10 10" refX="9" refY="5"
markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#0F2744"/>
</marker>
<marker id="arrow-accent" viewBox="0 0 10 10" refX="9" refY="5"
markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#C2410C"/>
</marker>
</defs>
<rect width="100%" height="100%" fill="#F8FAFC"/>
<text x="24" y="28" font-family="Helvetica, Arial, sans-serif" font-size="11" font-weight="700" fill="#1A6B6B" text-anchor="start">AUTHENTICATION</text>
<text x="24" y="50" font-family="Helvetica, Arial, sans-serif" font-size="20" font-weight="700" fill="#0F2744" text-anchor="start">Two hops · Zapier never sees the Verae JWT</text>
<rect x="20" y="80" width="1060" height="220" rx="12" fill="#E8F1F8" fill-opacity="1" stroke="#C5D6E8" stroke-width="1.4"/>
<text x="40" y="106" font-family="Helvetica, Arial, sans-serif" font-size="13" font-weight="700" fill="#1A6B6B" text-anchor="start">HOP 1 · end user → middleware</text>
<rect x="48" y="126" width="220" height="148" rx="8" fill="#FFFFFF" fill-opacity="1" stroke="#0F2744" stroke-width="1.4"/>
<text x="158" y="156" font-family="Helvetica, Arial, sans-serif" font-size="13" font-weight="700" fill="#0F2744" text-anchor="middle">User in Zapier</text>
<text x="158" y="178" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">username + password</text>
<text x="158" y="192" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">or zmw_ API key</text>
<text x="158" y="206" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">api_base_url</text>
<text x="158" y="220" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">default :3100</text>
<rect x="320" y="126" width="280" height="148" rx="8" fill="#FFFFFF" fill-opacity="1" stroke="#0F2744" stroke-width="1.8"/>
<text x="460" y="156" font-family="Helvetica, Arial, sans-serif" font-size="13" font-weight="700" fill="#0F2744" text-anchor="middle">POST /zapier/v1/auth/login</text>
<text x="460" y="178" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">loginWithCredentials</text>
<text x="460" y="192" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">or loginWithApiKey</text>
<text x="460" y="206" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">returns accessToken</text>
<text x="460" y="220" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">stored as sessionKey (TS)</text>
<rect x="650" y="126" width="200" height="148" rx="8" fill="#FFFFFF" fill-opacity="1" stroke="#0F2744" stroke-width="1.4"/>
<text x="750" y="156" font-family="Helvetica, Arial, sans-serif" font-size="13" font-weight="700" fill="#0F2744" text-anchor="middle">Tokens issued</text>
<text x="750" y="178" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">zmw_ tenant API key</text>
<text x="750" y="192" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">zmt_ HMAC session</text>
<text x="750" y="206" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">TOKEN_SECRET</text>
<text x="750" y="220" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">never commit</text>
<rect x="880" y="126" width="176" height="148" rx="8" fill="#FFFFFF" fill-opacity="1" stroke="#0F2744" stroke-width="1.4"/>
<text x="968" y="156" font-family="Helvetica, Arial, sans-serif" font-size="13" font-weight="700" fill="#0F2744" text-anchor="middle">Auth test</text>
<text x="968" y="178" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">GET /auth/me</text>
<text x="968" y="192" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">tenant + plan</text>
<text x="968" y="206" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">usage</text>
<text x="968" y="220" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">401 → refresh</text>
<line x1="268" y1="200" x2="320" y2="200" stroke="#1A6B6B" stroke-width="1.8" marker-end="url(#arrow)"/>
<line x1="600" y1="200" x2="650" y2="200" stroke="#1A6B6B" stroke-width="1.8" marker-end="url(#arrow)"/>
<line x1="850" y1="200" x2="880" y2="200" stroke="#1A6B6B" stroke-width="1.8" marker-end="url(#arrow)"/>
<rect x="20" y="320" width="1060" height="216" rx="12" fill="#E8F6EE" fill-opacity="1" stroke="#B7DCC7" stroke-width="1.4"/>
<text x="40" y="346" font-family="Helvetica, Arial, sans-serif" font-size="13" font-weight="700" fill="#15803D" text-anchor="start">HOP 2 · middleware → Verae (server-side only)</text>
<rect x="48" y="366" width="300" height="148" rx="8" fill="#FFFFFF" fill-opacity="1" stroke="#0F2744" stroke-width="1.4"/>
<text x="198" y="396" font-family="Helvetica, Arial, sans-serif" font-size="13" font-weight="700" fill="#0F2744" text-anchor="middle">veraeClient</text>
<text x="198" y="418" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">POST /auth/login on Verae</text>
<text x="198" y="432" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">or MOCK_VERAE=true</text>
<text x="198" y="446" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">JWT held in process</text>
<text x="198" y="460" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">redacted in DEBUG_VERAE</text>
<rect x="400" y="366" width="300" height="148" rx="8" fill="#FFFFFF" fill-opacity="1" stroke="#0F2744" stroke-width="1.8"/>
<text x="550" y="396" font-family="Helvetica, Arial, sans-serif" font-size="13" font-weight="700" fill="#0F2744" text-anchor="middle">api.veraetime.net</text>
<text x="550" y="418" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">Authorization: Bearer &lt;JWT&gt;</text>
<text x="550" y="432" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">timestamp / status / verify</text>
<text x="550" y="446" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">source of truth</text>
<text x="550" y="460" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">not reachable from Zapier</text>
<rect x="752" y="366" width="300" height="148" rx="8" fill="#FFFFFF" fill-opacity="1" stroke="#C2410C" stroke-width="1.8"/>
<text x="902" y="396" font-family="Helvetica, Arial, sans-serif" font-size="13" font-weight="700" fill="#C2410C" text-anchor="middle">Do not leak</text>
<text x="902" y="418" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">no Verae JWT in Zapier</text>
<text x="902" y="432" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">no JWT in NATS (use tokenRef)</text>
<text x="902" y="446" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">no secrets in git</text>
<text x="902" y="460" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="400" fill="#334155" text-anchor="middle">no secrets in debug logs</text>
<line x1="348" y1="440" x2="400" y2="440" stroke="#1A6B6B" stroke-width="1.8" marker-end="url(#arrow)"/>
<line x1="700" y1="440" x2="752" y2="440" stroke="#1A6B6B" stroke-width="1.8" marker-end="url(#arrow)"/>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB