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
- Serve the Den (and any claim URLs) over https and update the claims to use https:// URLs
- For local development/evals only, pass allowInsecureUrls: true to signConnectLinkToken
- Audit the source of the claims (env var, config, DB) and correct the http:// value to https://
- 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
- Default all claim URLs to https://
- Keep http URLs confined to local dev with allowInsecureUrls: true
- Validate URL schemes at config-load time, before signing
- Never let http:// values from env/DB flow into production claims
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
- managed MCP egress requires HTTPS
- an HTTPS request cannot redirect to a less secure protocol
- External URL protocol "${parsed.protocol}" is not allowed.
- invalid_payload
- Attachment hostname ${hostname} resolved to a private or res
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/fecbfe393af3e702.
Report an issue: GitHub.