Edge

Shield

Offline Token Verification

Shield response tokens are Ed25519-signed JWTs. The public key is published at a standard JWKS endpoint, so your server can verify tokens locally — no network round trip, no added latency, no dependency on shield.edge.network being reachable.

The Key Endpoint

GET https://shield.edge.network/.well-known/jwks.json

{
  "keys": [
    {
      "kty": "OKP",
      "crv": "Ed25519",
      "x": "…",
      "kid": "a1b2c3d4e5f60718",
      "alg": "EdDSA",
      "use": "sig"
    }
  ]
}

Cache the key set for up to an hour. If you encounter a token with an unknown kid header, refetch once — that's how key rotation propagates. Keys rotate automatically roughly every 60 days, and the retiring public key stays in the key set for 24 hours after rotation, so an hourly cache never verifies against a stale set.

Verifying a Token

Any JWT library that supports EdDSA works. With jose in Node:

import { createRemoteJWKSet, jwtVerify } from 'jose'

const JWKS = createRemoteJWKSet(
  new URL('https://shield.edge.network/.well-known/jwks.json')
)

async function verifyOffline(token, sitekey) {
  const { payload } = await jwtVerify(token, JWKS, {
    issuer: 'edge-shield',
    subject: sitekey, // REQUIRED — binds the token to YOUR widget
  })
  return {
    score: payload.score,      // 1–100 humanity score
    hostname: payload.hn,      // hostname the widget ran on
    agent: payload.agt || null // verified agent domain, if declared
  }
}

Your verification must check, in order:

  1. The signature, against a JWKS key matching the token's kid
  2. iss equals edge-shield
  3. sub equals your sitekey — without this check, a token minted for any Shield widget anywhere would pass
  4. exp — tokens live 5 minutes
  5. Optionally, that hn is one of your hostnames

The claims you get back:

{
  "iss": "edge-shield",
  "sub": "es_...",              // the widget's sitekey
  "jti": "b3f9…",               // unique token id (replay ledger key)
  "iat": 1785459151,
  "exp": 1785459451,            // 5-minute lifetime
  "score": 92,                  // 1–100 humanity score
  "hn": "example.com",          // hostname the widget ran on
  "agt": "crawler.example",     // optional: verified agent domain
  "agm": "web-bot-auth"         // optional: agent verification method
}

The Trade-Off: No Single-Use Guarantee

The one thing offline verification cannot give you is replay protection. The ledger of spent tokens lives on Shield's servers, so only siteverify guarantees that a token verifies exactly once. Verified offline, the same token is valid for its full 5-minute lifetime, as many times as it's presented.

Use offline verification for high-throughput, lower-stakes endpoints — search, previews, read APIs — where latency matters more than strict single-use. Keep siteverify for signups, logins, payments, and anything a farmed token shouldn't touch.

You can narrow the replay window further by rejecting tokens whose iat is older than your form could plausibly take to submit — 60 seconds is a common choice.

Next Steps