paperclipai/paperclip · error

invalid_cloud_runtime_identity

invalid_cloud_runtime_identity

Error message

invalid_cloud_runtime_identity

What it means

The middleware verified a Cloud runtime identity assertion via applyCloudRuntimeIdentityAssertion, and the verification threw (bad signature, expired token, wrong issuer/audience, malformed compact JWS). The middleware logs a warning and responds 401 with this code. It means the assertion was present and on the right endpoint, but its cryptographic or semantic contents failed validation.

Source

Thrown at server/src/middleware/cloud-runtime-identity.ts:30

 * header, and possession of the shared tenant-session token cannot mint it.
 */
export function cloudRuntimeIdentityMiddleware(db: Db): RequestHandler {
  return async (req, res, next) => {
    const assertion = req.get(CLOUD_RUNTIME_IDENTITY_HEADER)?.trim();
    if (!assertion) {
      next();
      return;
    }
    if (req.method !== "GET" || req.path !== "/api/health") {
      res.status(400).json({ error: "cloud_runtime_identity_wrong_endpoint" });
      return;
    }
    try {
      await applyCloudRuntimeIdentityAssertion({ db, compactJws: assertion });
      next();
    } catch (error) {
      logger.warn({ err: error }, "Rejected Cloud runtime identity assertion");
      res.status(401).json({ error: "invalid_cloud_runtime_identity" });
    }
  };
}

View on GitHub (pinned to 01ad858492)

Solutions

  1. Check the server logs for the accompanying 'Rejected Cloud runtime identity assertion' warning to see the underlying verification error
  2. Regenerate the runtime identity assertion (fresh signing key, current timestamps) and retry the health request
  3. Verify the issuer's signing keys are present and synced with the verifier (key rotation propagation)
  4. Confirm clock sync (NTP) on the runtime container to avoid premature expiry
  5. Validate the compact JWS is untruncated and not header-escaped before sending

Example fix

// before (stale assertion reused)
const assertion = cachedAssertionFromBoot;
// after (refresh before each health probe)
const assertion = await fetchFreshRuntimeIdentityAssertion();
Defensive patterns

Strategy: try-catch

Validate before calling

function isWellFormedCompactJws(t: string) { const p = t.split('.'); return p.length === 3 && p.every(s => s.length > 0); }

Type guard

null

Try / catch

try { await applyCloudRuntimeIdentityAssertion({ db, compactJws: assertion }); } catch (e) { logger.warn({ err: e }, 'runtime identity rejected'); // fail closed, regenerate assertion and retry once with a fresh token }

Prevention

When it happens

Trigger: applyCloudRuntimeIdentityAssertion({ db, compactJws: assertion }) rejects the compact JWS: signature verification failure, expired assertion, key not found, wrong audience, or a malformed JWT. Thrown for any GET /api/health request carrying an invalid assertion header.

Common situations: Clock skew between the runtime and the identity issuer expires assertions early; rotated signing keys not yet present in the verifier's key set; truncated or re-encoded tokens from header sanitization; a stale runtime reusing an assertion from a previous identity.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/fda955dde9f99a83. Report an issue: GitHub.