From aa6a604be0e73d7124a58023653b83b4fc29ebc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20Falco=CC=81n?= Date: Fri, 17 Jul 2026 18:26:05 +0200 Subject: [PATCH] chore(mcp): provision Passport signing keys everywhere Passport signs OAuth tokens with keys that were only ever generated by a local install:api run and are gitignored. Generate them in CI (tests + browser jobs), on production boot (docker entrypoint, unless provided via PASSPORT_* env), and in worktree.sh, and document the PASSPORT_* env in .env.example. Without this the token endpoint fails in CI and production. --- .env.example | 6 ++++++ .github/workflows/ci.yml | 6 ++++++ docker/entrypoint.sh | 10 ++++++++++ worktree.sh | 6 ++++++ 4 files changed, 28 insertions(+) diff --git a/.env.example b/.env.example index 6291949f..b372bc48 100644 --- a/.env.example +++ b/.env.example @@ -8,6 +8,12 @@ APP_LOCALE=en APP_FALLBACK_LOCALE=en APP_FAKER_LOCALE=en_US +# Passport OAuth signing keys for the MCP OAuth server. Leave blank to use the +# keys generated by `php artisan passport:keys` under storage/. Set both (PEM +# contents) to share one key pair across multiple app instances. +PASSPORT_PRIVATE_KEY= +PASSPORT_PUBLIC_KEY= + APP_MAINTENANCE_DRIVER=file # APP_MAINTENANCE_STORE=database diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7ecb5c39..398d0f9d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,6 +64,9 @@ jobs: - name: Generate Application Key run: php artisan key:generate + - name: Generate Passport Keys + run: php artisan passport:keys --force + - name: Tests # --parallel splits the suite across workers via paratest. Each # worker creates its own "testing_test_" database; the mysql @@ -144,6 +147,9 @@ jobs: - name: Generate Application Key run: php artisan key:generate + - name: Generate Passport Keys + run: php artisan passport:keys --force + - name: Browser Tests run: ./vendor/bin/pest --testsuite=Browser --ci --shard=${{ matrix.shard }}/6 env: diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index e1914625..25f234c6 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -82,6 +82,16 @@ echo "MySQL is ready!" echo "Running migrations..." php artisan migrate --force +# Ensure Passport signing keys exist (OAuth for MCP connectors). Keys provided +# via PASSPORT_PRIVATE_KEY/PASSPORT_PUBLIC_KEY env take precedence; otherwise +# generate them into storage/ (a persisted volume) so issued tokens survive +# restarts. NOTE: for a multi-instance deployment, provide the keys via env so +# every instance validates tokens with the same key. +if [ -z "$PASSPORT_PRIVATE_KEY" ] && [ ! -f /app/storage/oauth-private.key ]; then + echo "Generating Passport keys..." + php artisan passport:keys --force +fi + # Cache configuration echo "Caching configuration..." php artisan config:cache diff --git a/worktree.sh b/worktree.sh index 4d84ad88..2e935102 100755 --- a/worktree.sh +++ b/worktree.sh @@ -5,5 +5,11 @@ ROOT_PATH=$1 cp "$ROOT_PATH/.env" .env cp -r "$ROOT_PATH/storage/keys" ./storage/keys +# Passport OAuth signing keys (for the MCP OAuth server). Reuse the main repo's +# keys if present, otherwise generate a fresh pair after deps are installed. +cp "$ROOT_PATH"/storage/oauth-*.key ./storage/ 2>/dev/null || true + bun i composer install + +[ -f ./storage/oauth-private.key ] || php artisan passport:keys