different-ai/openwork · error

connect-link claims contain a non-https URL: ${insecure}

Error message

connect-link claims contain a non-https URL: ${insecure}

What it means

signConnectLinkToken refuses to sign connect-link JWTs whose claims reference non-https URLs (e.g. the den or logo URL) unless allowInsecureUrls is explicitly set. The check runs findInsecureConnectLinkUrl over the parsed claims before signing. This prevents production connect links from pointing desktop clients at plaintext HTTP endpoints.

Source

Thrown at packages/connect-link/src/node.ts:59

  } catch {
    return null
  }
}

export type SignConnectLinkTokenInput = {
  claims: ConnectLinkClaims
  privateKeyPem: string
  kid: string
  /** Permit non-https den/logo URLs (local development and evals only). */
  allowInsecureUrls?: boolean
}

export function signConnectLinkToken(input: SignConnectLinkTokenInput): string {
  const claims = connectLinkClaimsSchema.parse(input.claims)
  if (!input.allowInsecureUrls) {
    const insecure = findInsecureConnectLinkUrl(claims)
    if (insecure) {
      throw new Error(`connect-link claims contain a non-https URL: ${insecure}`)
    }
  }
  const header = { alg: CONNECT_LINK_ALGORITHM, typ: "JWT", kid: input.kid }
  const signingInput = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(claims))}`
  // new Uint8Array(...) keeps the calls assignable across the @types/node
  // versions in this workspace (Buffer's backing store is typed as
  // ArrayBufferLike on older lib combinations).
  const signature = sign(null, new Uint8Array(Buffer.from(signingInput, "utf8")), createPrivateKey(input.privateKeyPem))
  return `${signingInput}.${signature.toString("base64url")}`
}

export type VerifyConnectLinkTokenInput = {
  token: string
  /** kid → SPKI PEM public key. Only keys in this map are trusted. */
  publicKeys: Record<string, string>
  nowEpochSeconds?: number
  clockSkewSeconds?: number
  /** Accept http URLs when every insecure target is loopback (dev only). */

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Serve the Den (and any claim URLs) over https and update the claims to use https:// URLs
  2. For local development/evals only, pass allowInsecureUrls: true to signConnectLinkToken
  3. Audit the source of the claims (env var, config, DB) and correct the http:// value to https://
  4. If the URL is loopback-only dev traffic, keep it out of production-signed tokens

Example fix

// before
const token = signConnectLinkToken({ claims: { den: 'http://den.internal' }, privateKeyPem, kid })
// after
const token = signConnectLinkToken({ claims: { den: 'https://den.internal' }, privateKeyPem, kid })
// or, local dev only:
signConnectLinkToken({ claims, privateKeyPem, kid, allowInsecureUrls: true })
Defensive patterns

Strategy: validation

Validate before calling

function assertHttpsClaims(claims) {
  for (const key of ['den', 'logo']) {
    const url = claims[key];
    if (typeof url === 'string' && !url.startsWith('https://')) {
      throw new Error(`claim '${key}' must be https: ${url}`);
    }
  }
}
// run before signConnectLinkToken, or pass allowInsecureUrls: true in dev only

Type guard

function isHttpsUrl(u: unknown): u is string {
  if (typeof u !== 'string') return false;
  try { return new URL(u).protocol === 'https:'; } catch { return false; }
}

Try / catch

try {
  const token = signConnectLinkToken({ claims, privateKeyPem, kid })
} catch (e) {
  if (e instanceof Error && e.message.startsWith('connect-link claims contain a non-https URL')) {
    // fix claims to https or set allowInsecureUrls for local dev
  } else throw e
}

Prevention

When it happens

Trigger: Calling signConnectLinkToken with claims containing an http:// URL and no allowInsecureUrls flag; the thrown message names the offending URL.

Common situations: Local development against a localhost Den server over http; staging environments without TLS; forgetting to set allowInsecureUrls in dev/eval harnesses; a config or DB row holding an http:// den URL that leaked into production signing.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/fecbfe393af3e702. Report an issue: GitHub.