Skip to main content
The publishes its public signing keys at a standard JWKS (JSON Web Key Set) endpoint. Use this to verify the signatures on JWTs issued by the token exchange service.
The JWKS endpoint is in early access and the specification below is the shape it will ship with. Partners integrating now can validate their JWKS caching, rotation, and signature-verification logic against the launch contract — contact your account manager for a sandbox hand-off.

Endpoint

GET /v0/sis/.well-known/jwks.json
Authentication: None required. This endpoint is publicly accessible.

Response

The endpoint returns a standard RFC 7517 JWK Set containing the SIS’s active signing keys:
{
  "keys": [
    {
      "kty": "EC",
      "crv": "P-256",
      "kid": "sis-2026-02",
      "use": "sig",
      "alg": "ES256",
      "x": "...",
      "y": "..."
    }
  ]
}
FieldDescription
ktyKey type — EC for ECDSA keys
crvCurve — P-256 for ES256
kidKey ID — matches the kid header in issued JWTs
useKey usage — always sig (signing)
algAlgorithm — ES256 (ECDSA with P-256 and SHA-256)

Signing Algorithm

The SIS signs JWTs using ES256 (ECDSA P-256). When verifying, ensure your JWT library is configured to accept ES256 and reject other algorithms to prevent algorithm confusion attacks.

Fetching the JWKS

Most JWT libraries handle JWKS fetching and caching automatically. Here are examples using popular libraries:

TypeScript (jose)

import * as jose from "jose";

const JWKS_URL = "https://sis.sumvin.com/v0/sis/.well-known/jwks.json";
const jwks = jose.createRemoteJWKSet(new URL(JWKS_URL));

// Use in JWT verification
const { payload } = await jose.jwtVerify(token, jwks, {
  algorithms: ["ES256"],
  audience: "your-audience-id",
});
The jose library’s createRemoteJWKSet handles caching and key rotation automatically. It fetches keys on first use and refreshes them when it encounters a JWT with an unknown kid.

Python (PyJWT)

import jwt
from jwt import PyJWKClient

JWKS_URL = "https://sis.sumvin.com/v0/sis/.well-known/jwks.json"
jwks_client = PyJWKClient(JWKS_URL)

# Fetch the signing key matching the JWT's kid header
signing_key = jwks_client.get_signing_key_from_jwt(token)

payload = jwt.decode(
    token,
    signing_key.key,
    algorithms=["ES256"],
    audience="your-audience-id",
)

Caching

The JWKS response includes standard HTTP cache headers. Follow these guidelines: Cache the JWKS response. Fetching the JWKS on every request adds unnecessary latency. Most JWT libraries cache automatically — let them handle it. Respect Cache-Control headers. The SIS sets cache lifetimes that balance key rotation speed with client performance. Do not override these with longer TTLs. Refetch on unknown kid. If you encounter a JWT whose kid doesn’t match any cached key, refetch the JWKS before rejecting the token. This handles key rotations gracefully. Recommended TTL: If you implement your own cache, a 5-minute TTL provides a good balance. The SIS will never rotate keys faster than this window allows.

Key Rotation

The SIS rotates signing keys periodically. During a rotation:
  1. The new key is added to the JWKS before any JWTs are signed with it
  2. Both old and new keys appear in the JWKS simultaneously
  3. The old key is removed from the JWKS only after all JWTs signed with it have expired
This overlap period ensures you never encounter a valid JWT whose signing key has already been removed from the JWKS. If your library caches keys and refetches on unknown kid values, rotations are seamless.