vercel / vercel/vercel-plugin

deployments-cicd skill: document PKCS#8 key requirement for GitHub Apps on Node.js 20 / OpenSSL 3

Open Beginner friendly
#67 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
287
Forks
58
Avg merge
1d 1h
Merged PRs (30d)
17

Description

Summary

When deploying a GitHub App to Vercel (Node.js 20 runtime / OpenSSL 3), using the PKCS#1 private key that GitHub issues by default causes a silent, hard-to-diagnose failure. The deployments-cicd and vercel-functions skills have no mention of this footgun.

What GitHub Issues vs. What Works

GitHub App settings generate and download private keys in PKCS#1 format:

-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----

universal-github-app-jwt (a dependency of octokit) tries to convert PKCS#1 → PKCS#8 at JWT-signing time using createPrivateKey, but this fails on Node.js 20 with OpenSSL 3:

Error: error:1E08010C:DECODER routines::unsupported
  ERR_OSSL_UNSUPPORTED
  at createPrivateKey (node:internal/crypto/keys:797:12)
  at convertPrivateKey (universal-github-app-jwt/lib/crypto-node.js:11:10)

Why It's Hard to Diagnose

  1. Webhook signature verification uses HMAC-SHA256 — the private key is only needed when calling getInstallationOctokit(). The bot acknowledges every webhook with HTTP 202 and appears healthy in GitHub's delivery history.

  2. The error is async — with waitUntil (the correct Vercel pattern for background work after response), the failure only surfaces in function logs, not the HTTP response.

  3. vercel logs defaults to branch-filtered outputvercel logs --environment production returns "No logs found" due to an implicit branch filter. You need --no-branch to see logs across all deployments. This masked the error across multiple debugging sessions.

Fix

Convert the private key to PKCS#8 immediately after downloading from GitHub:

openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
  -in your-app.private-key.pem \
  -out your-app.private-key.pkcs8.pem

The result starts with -----BEGIN PRIVATE KEY----- (no RSA). Use this value in GITHUB_APP_PRIVATE_KEY.

Suggested Skill Addition

The deployments-cicd or vercel-functions skill (or a new github-apps skill) should include:

GitHub App private keys must be in PKCS#8 format. GitHub issues PKCS#1 keys (BEGIN RSA PRIVATE KEY). Vercel's Node.js 20 runtime (OpenSSL 3) cannot load them via createPrivateKey. Convert before storing:

openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in key.pem -out key.pkcs8.pem

The converted file starts with -----BEGIN PRIVATE KEY-----.

Also worth adding: use vercel logs --no-branch for production log access — the default branch filter silently excludes logs in many setups.

Environment

  • Vercel runtime: Node.js 20 (default as of 2025)
  • octokit: 4.x → universal-github-app-jwt: 2.2.2
  • Verified fix: PKCS#8 key resolved the ERR_OSSL_UNSUPPORTED error

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Locate the deployments-cicd and vercel-functions skill documents, then read their existing GitHub App and Vercel logging guidance. Document the PKCS#8 requirement, conversion command, expected PEM header, and --no-branch logging note; done when the troubleshooting path and working key format are clear to a reader.

Written by the indexing model from the issue text.

Assessment

Tech stack
github, node.js
Domain
cloud, devops, documentation
Issue type
Documentation
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.