Appearance
date: 2026-06-18 tags: [passport, oauth, testing, mcp] status: active graduated_to:
Passport keys are needed even to return a 401 — an HTTP-auth test 500s without them
Symptom — a feature test asserting an unauthenticated request to the OAuth-protected MCP endpoint returns 401 (and one asserting a missing-scope 403) blew up instead with League\OAuth2\Server\CryptKey: Invalid key supplied.
Root cause — the api guard's passport driver boots the OAuth resource server, which loads the public signing key, before it can reject a request. So even the reject path needs the keys present. The keys are generated by passport:keys and are gitignored (only APP_KEY + DB creds live in env), so CI — and any fresh container — starts without them.
Fix — tests/Feature/Mcp/HandoffServerTest.php generates ephemeral keys in beforeEach when they're absent:
php
beforeEach(function () {
if (! file_exists(storage_path('oauth-private.key'))) {
Artisan::call('passport:keys', ['--force' => true]);
}
});Passport::actingAs(...) bypasses real token parsing for the happy path, but the guard itself still needs keys to boot — so the generation can't be skipped.
Guard — the beforeEach above. Any new test that hits a passport-guarded route (even just to assert a 401/403) must ensure keys exist first; don't assume actingAs removes the need.