{"record":{"id":"9e202e58b66aca22","repo":"paperclipai/paperclip","slug":"cloud-runtime-identity-assertion-is-not-a-compact","errorCode":null,"errorMessage":"Cloud runtime identity assertion is not a compact JWS","messagePattern":"Cloud runtime identity assertion is not a compact JWS","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/cloud-runtime-identity.ts","lineNumber":267,"sourceCode":"    const key = candidate as JsonWebKey & { kid?: unknown };\n    return key.kid === kid;\n  });\n  if (matches.length !== 1) throw new Error(\"Cloud runtime identity uses an unknown signing key\");\n  const jwk = matches[0];\n  if (jwk.kty !== \"OKP\" || jwk.crv !== \"Ed25519\" || jwk.use !== \"sig\" || jwk.alg !== \"EdDSA\" || !jwk.x || jwk.d) {\n    throw new Error(\"Cloud runtime identity signing key is invalid\");\n  }\n  return createPublicKey({ key: jwk, format: \"jwk\" });\n}\n\nfunction verifyClaims(input: {\n  compactJws: string;\n  env: NodeJS.ProcessEnv;\n  now: Date;\n}): RuntimeIdentityClaims {\n  const parts = input.compactJws.split(\".\");\n  if (parts.length !== 3 || parts.some((part) => part.length === 0)) {\n    throw new Error(\"Cloud runtime identity assertion is not a compact JWS\");\n  }\n  const [encodedHeader, encodedPayload, encodedSignature] = parts;\n  const header = decodeJsonPart(encodedHeader, \"protected header\");\n  if (\n    header.alg !== \"EdDSA\"\n    || header.typ !== CLOUD_RUNTIME_IDENTITY_JWS_TYPE\n    || typeof header.kid !== \"string\"\n    || !header.kid\n  ) {\n    throw new Error(\"Cloud runtime identity protected header is invalid\");\n  }\n  const key = publicKeyForKid(input.env, header.kid);\n  const signature = Buffer.from(encodedSignature, \"base64url\");\n  const signingInput = Buffer.from(`${encodedHeader}.${encodedPayload}`, \"ascii\");\n  if (!verify(null, signingInput, key, signature)) {\n    throw new Error(\"Cloud runtime identity signature is invalid\");\n  }\n","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/cloud-runtime-identity.ts#L249-L285","documentation":"Thrown by verifyClaims when the assertion string is not a three-part compact JWS. The verifier splits on '.' and requires exactly 3 non-empty segments (header.payload.signature); any other shape is rejected before any decoding happens.","triggerScenarios":"verifyCloudRuntimeIdentityAssertion receives a token that is empty, a raw JSON blob, a JWT with missing signature segment, a token containing extra dots (e.g. embedded in a larger string), or segments that are empty strings.","commonSituations":"Passing the wrong env var/config value (e.g. the JWKS itself) where the assertion is expected; truncated token from log copying; double-embedding the token in an envelope that adds characters; newline or whitespace included and split logic encounters an empty part.","solutions":["Confirm you are passing the signed assertion token (header.payload.signature), not a JWKS or claims JSON","Trim whitespace/newlines from the token before verification","Re-issue the assertion from the Cloud control plane if it was truncated in transport or logs","Count the dot-separated segments: there must be exactly 3, all non-empty"],"exampleFix":"// before: passing claims JSON instead of the signed assertion\nverifyCloudRuntimeIdentityAssertion({ compactJws: JSON.stringify(claims), expectedPreviousOrigin: prev });\n// after: pass the JWS string as issued\nverifyCloudRuntimeIdentityAssertion({ compactJws: process.env.PAPERCLIP_CLOUD_IDENTITY_ASSERTION!.trim(), expectedPreviousOrigin: prev });","handlingStrategy":"validation","validationCode":"function isCompactJws(token: unknown): token is string {\n  if (typeof token !== \"string\") return false;\n  const parts = token.trim().split(\".\");\n  return parts.length === 3 && parts.every(p => p.length > 0 && /^[A-Za-z0-9_-]+$/.test(p));\n}\nif (!isCompactJws(assertion)) throw new Error(\"refusing to verify: not a compact JWS\");","typeGuard":null,"tryCatchPattern":"try {\n  verifyCloudRuntimeIdentityAssertion({ compactJws: assertion, expectedPreviousOrigin: prev });\n} catch (e) {\n  if (String((e as Error).message).includes(\"not a compact JWS\")) {\n    logger.warn(\"Assertion missing or malformed; requesting a fresh assertion\", { error: e });\n    assertion = await controlPlaneClient.mintIdentityAssertion(stackId);\n  } else throw e;\n}","preventionTips":["Type-check inputs: only accept string assertions from a single, named config source","Never confuse the JWKS env var with the assertion env var — name them distinctly","Trim surrounding whitespace only; never alter token contents","Add a smoke test verifying a freshly minted assertion passes shape validation"],"tags":["jwt","format-validation","compact-jws"],"backgroundTag":"invalid-argument-format","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}