Skip to content

feat(astro): [WIP] Add support for keyless mode#7800

Closed
wobsoriano wants to merge 13 commits intomainfrom
rob/astro-keyless-mode
Closed

feat(astro): [WIP] Add support for keyless mode#7800
wobsoriano wants to merge 13 commits intomainfrom
rob/astro-keyless-mode

Conversation

@wobsoriano
Copy link
Member

@wobsoriano wobsoriano commented Feb 7, 2026

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Dev-mode keyless fallback for obtaining/claiming API keys with logging
    • File-based local key storage and a keyless service for Astro
    • Public env var for disabling keyless and per-request public URLs exposed to the client
  • Behavior

    • Publishable and secret keys optional in dev; resolved keys and keyless URLs injected per-request and exposed to the client when available
    • Keyless enabled only in dev when filesystem support is present and not disabled
  • Tests

    • End-to-end tests and helpers covering keyless UI, claiming, and env-key restart
  • Chores

    • Development tooling updated (vite added)

@changeset-bot
Copy link

changeset-bot bot commented Feb 7, 2026

⚠️ No Changeset found

Latest commit: 11ed1ee

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Feb 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
clerk-js-sandbox Skipped Skipped Feb 8, 2026 7:53pm

Request Review

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 7, 2026

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7800

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7800

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7800

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7800

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7800

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7800

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7800

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7800

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7800

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7800

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7800

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7800

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7800

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7800

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7800

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7800

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7800

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7800

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7800

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7800

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7800

commit: 11ed1ee

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 7, 2026

📝 Walkthrough

Walkthrough

Adds keyless authentication support to the Astro integration. Exposes a new optional public env flag PUBLIC_CLERK_KEYLESS_DISABLED and makes PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY optional in the env schema. Introduces per-request keyless resolution in middleware (calls resolveKeysWithKeylessFallback), stores resolved keyless data on context.locals (keylessClaimUrl, keylessApiKeysUrl, keylessPublishableKey), and propagates internal keyless URLs into ClerkOptions. Adds Node file-based keyless storage, a lazy keyless service entrypoint, keyless utilities, a canUseKeyless feature flag, Playwright tests/helpers, and minor build/dev tooling updates.

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(astro): [WIP] Add support for keyless mode' accurately describes the main change: introducing keyless mode support to the Astro integration.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


No actionable comments were generated in the recent review. 🎉


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/astro/src/env.d.ts`:
- Around line 23-25: The InternalEnv interface is missing CLERK_KEYLESS_DISABLED
which causes a TypeScript error when feature-flags.ts reads
import.meta.env.CLERK_KEYLESS_DISABLED; add a declaration for this env var to
the InternalEnv interface (e.g., include readonly CLERK_KEYLESS_DISABLED?:
string;) alongside the other env entries in packages/astro/src/env.d.ts so the
type system recognizes import.meta.env.CLERK_KEYLESS_DISABLED.

In `@packages/astro/src/server/keyless/index.ts`:
- Line 46: PACKAGE_VERSION is referenced in the object literal
(frameworkVersion: PACKAGE_VERSION) but not declared or imported, causing a
runtime ReferenceError; fix by adding a proper import or declaration for
PACKAGE_VERSION at the top of the file (e.g., import PACKAGE_VERSION from the
module that exports the package version or read the version from package.json)
so that frameworkVersion uses a defined symbol PACKAGE_VERSION.

In `@packages/astro/src/server/keyless/utils.ts`:
- Around line 14-67: Add unit tests for resolveKeysWithKeylessFallback that
cover the three main paths: (1) keyless disabled by setting canUseKeyless false
and asserting it returns the configured keys unchanged and does not call
keyless(), (2) runningWithClaimedKeys where keylessService.readKeys() returns
matching publishableKey — mock keyless() to return a service with readKeys() and
completeOnboarding(), stub clerkDevelopmentCache.run/log and assert
completeOnboarding is attempted, clerkDevelopmentCache.log called with
createConfirmationMessage and the original keys are returned, and (3) keyless
generation where no configured keys exist so keylessService.getOrCreateKeys()
returns an AccountlessApplication — mock getOrCreateKeys() to return app, assert
returned publishableKey/secretKey/claimUrl/apiKeysUrl match and
clerkDevelopmentCache.log called with createKeylessModeMessage. Use spies/mocks
for keyless(), keylessService methods, clerkDevelopmentCache, and any helpers
(createConfirmationMessage/createKeylessModeMessage) to verify behavior and
side-effect logging in each test.

Comment on lines 23 to 25
readonly PUBLIC_CLERK_KEYLESS_CLAIM_URL?: string;
readonly PUBLIC_CLERK_KEYLESS_API_KEYS_URL?: string;
readonly PUBLIC_CLERK_KEYLESS_DISABLED?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all occurrences of CLERK_KEYLESS_DISABLED in the codebase
rg -n "CLERK_KEYLESS_DISABLED" packages/astro/src

Repository: clerk/javascript

Length of output: 473


🏁 Script executed:

#!/bin/bash
# Read the full env.d.ts file to understand structure
cat -n packages/astro/src/env.d.ts

Repository: clerk/javascript

Length of output: 1753


🏁 Script executed:

#!/bin/bash
# Check feature-flags.ts implementation
cat -n packages/astro/src/utils/feature-flags.ts

Repository: clerk/javascript

Length of output: 758


Add CLERK_KEYLESS_DISABLED to InternalEnv to avoid TypeScript errors.

feature-flags.ts (line 15) reads import.meta.env.CLERK_KEYLESS_DISABLED, but this property is not declared in the InternalEnv interface, causing a type error.

🛠️ Suggested fix
 interface InternalEnv {
   readonly PUBLIC_CLERK_FRONTEND_API?: string;
   readonly CLERK_API_KEY?: string;
   readonly CLERK_API_URL?: string;
   readonly CLERK_API_VERSION?: string;
   readonly CLERK_JWT_KEY?: string;
   readonly CLERK_SECRET_KEY?: string;
   readonly CLERK_MACHINE_SECRET_KEY?: string;
+  readonly CLERK_KEYLESS_DISABLED?: string;
   readonly PUBLIC_CLERK_DOMAIN?: string;
🤖 Prompt for AI Agents
In `@packages/astro/src/env.d.ts` around lines 23 - 25, The InternalEnv interface
is missing CLERK_KEYLESS_DISABLED which causes a TypeScript error when
feature-flags.ts reads import.meta.env.CLERK_KEYLESS_DISABLED; add a declaration
for this env var to the InternalEnv interface (e.g., include readonly
CLERK_KEYLESS_DISABLED?: string;) alongside the other env entries in
packages/astro/src/env.d.ts so the type system recognizes
import.meta.env.CLERK_KEYLESS_DISABLED.

},
},
framework: '@clerk/astro',
frameworkVersion: PACKAGE_VERSION,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

PACKAGE_VERSION is undefined and will cause a runtime ReferenceError.

The constant PACKAGE_VERSION is used but never imported or declared in this file. This will crash keyless service initialization at runtime.

🐛 Proposed fix

Add the missing import at the top of the file:

 import { createKeylessService } from '@clerk/shared/keyless';
 import type { APIContext } from 'astro';
 
+import { version as PACKAGE_VERSION } from '../../../package.json';
 import { clerkClient } from '../clerk-client';
 import { createFileStorage } from './file-storage.js';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
frameworkVersion: PACKAGE_VERSION,
import { createKeylessService } from '@clerk/shared/keyless';
import type { APIContext } from 'astro';
import { version as PACKAGE_VERSION } from '../../../package.json';
import { clerkClient } from '../clerk-client';
import { createFileStorage } from './file-storage.js';
🤖 Prompt for AI Agents
In `@packages/astro/src/server/keyless/index.ts` at line 46, PACKAGE_VERSION is
referenced in the object literal (frameworkVersion: PACKAGE_VERSION) but not
declared or imported, causing a runtime ReferenceError; fix by adding a proper
import or declaration for PACKAGE_VERSION at the top of the file (e.g., import
PACKAGE_VERSION from the module that exports the package version or read the
version from package.json) so that frameworkVersion uses a defined symbol
PACKAGE_VERSION.

Comment on lines 14 to 67
export async function resolveKeysWithKeylessFallback(
configuredPublishableKey: string | undefined,
configuredSecretKey: string | undefined,
): Promise<KeylessResult> {
let publishableKey = configuredPublishableKey;
let secretKey = configuredSecretKey;
let claimUrl: string | undefined;
let apiKeysUrl: string | undefined;

if (!canUseKeyless) {
return { publishableKey, secretKey, claimUrl, apiKeysUrl };
}

const keylessService = await keyless();
const locallyStoredKeys = keylessService.readKeys();

const runningWithClaimedKeys =
Boolean(configuredPublishableKey) && configuredPublishableKey === locallyStoredKeys?.publishableKey;

if (runningWithClaimedKeys && locallyStoredKeys) {
try {
await clerkDevelopmentCache?.run(() => keylessService.completeOnboarding(), {
cacheKey: `${locallyStoredKeys.publishableKey}_complete`,
onSuccessStale: 24 * 60 * 60 * 1000,
});
} catch {
// noop
}

clerkDevelopmentCache?.log({
cacheKey: `${locallyStoredKeys.publishableKey}_claimed`,
msg: createConfirmationMessage(),
});

return { publishableKey, secretKey, claimUrl, apiKeysUrl };
}

if (!publishableKey && !secretKey) {
const keylessApp: AccountlessApplication | null = await keylessService.getOrCreateKeys();

if (keylessApp) {
publishableKey = keylessApp.publishableKey;
secretKey = keylessApp.secretKey;
claimUrl = keylessApp.claimUrl;
apiKeysUrl = keylessApp.apiKeysUrl;

clerkDevelopmentCache?.log({
cacheKey: keylessApp.publishableKey,
msg: createKeylessModeMessage(keylessApp),
});
}
}

return { publishableKey, secretKey, claimUrl, apiKeysUrl };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add tests for keyless fallback paths (required before merge).
This PR introduces new keyless resolution behavior but adds no tests. Please include coverage for disabled keyless, claimed keys, and generated keyless keys.

🤖 Prompt for AI Agents
In `@packages/astro/src/server/keyless/utils.ts` around lines 14 - 67, Add unit
tests for resolveKeysWithKeylessFallback that cover the three main paths: (1)
keyless disabled by setting canUseKeyless false and asserting it returns the
configured keys unchanged and does not call keyless(), (2)
runningWithClaimedKeys where keylessService.readKeys() returns matching
publishableKey — mock keyless() to return a service with readKeys() and
completeOnboarding(), stub clerkDevelopmentCache.run/log and assert
completeOnboarding is attempted, clerkDevelopmentCache.log called with
createConfirmationMessage and the original keys are returned, and (3) keyless
generation where no configured keys exist so keylessService.getOrCreateKeys()
returns an AccountlessApplication — mock getOrCreateKeys() to return app, assert
returned publishableKey/secretKey/claimUrl/apiKeysUrl match and
clerkDevelopmentCache.log called with createKeylessModeMessage. Use spies/mocks
for keyless(), keylessService methods, clerkDevelopmentCache, and any helpers
(createConfirmationMessage/createKeylessModeMessage) to verify behavior and
side-effect logging in each test.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/astro/src/utils/feature-flags.ts`:
- Around line 14-16: The KEYLESS_DISABLED constant reads process.env at
module-eval time and can throw when process is undefined in browser/edge builds;
update the evaluation in feature-flags.ts so env is accessed only via a safe
guard (e.g. check typeof process !== 'undefined' or globalThis?.process?.env)
before calling isTruthy on PUBLIC_CLERK_KEYLESS_DISABLED or
CLERK_KEYLESS_DISABLED, or move the logic into a function that performs the
guarded read at call time (referencing KEYLESS_DISABLED and isTruthy to locate
the code).

Comment on lines +14 to +16
const KEYLESS_DISABLED =
isTruthy(process.env.PUBLIC_CLERK_KEYLESS_DISABLED) || isTruthy(process.env.CLERK_KEYLESS_DISABLED) || false;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Guard process.env access to avoid runtime ReferenceError in browser/edge builds.

Line 14-16 reads process.env at module evaluation time. In non-Node runtimes, process is undefined, so importing this module can throw before hasFileSystemSupport() is checked. Gate env reads behind a typeof process !== 'undefined' check (or globalThis?.process?.env) so the module loads safely.

Proposed fix
+const readEnv = (name: string): string | undefined =>
+  typeof process !== 'undefined' ? process.env[name] : undefined;
+
 const KEYLESS_DISABLED =
-  isTruthy(process.env.PUBLIC_CLERK_KEYLESS_DISABLED) || isTruthy(process.env.CLERK_KEYLESS_DISABLED) || false;
+  isTruthy(readEnv('PUBLIC_CLERK_KEYLESS_DISABLED')) || isTruthy(readEnv('CLERK_KEYLESS_DISABLED')) || false;
🤖 Prompt for AI Agents
In `@packages/astro/src/utils/feature-flags.ts` around lines 14 - 16, The
KEYLESS_DISABLED constant reads process.env at module-eval time and can throw
when process is undefined in browser/edge builds; update the evaluation in
feature-flags.ts so env is accessed only via a safe guard (e.g. check typeof
process !== 'undefined' or globalThis?.process?.env) before calling isTruthy on
PUBLIC_CLERK_KEYLESS_DISABLED or CLERK_KEYLESS_DISABLED, or move the logic into
a function that performs the guarded read at call time (referencing
KEYLESS_DISABLED and isTruthy to locate the code).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/astro/src/server/keyless/index.ts`:
- Around line 20-39: The calls to clerkClient in createAccountlessApplication
and completeOnboarding pass a second options object but clerkClient only accepts
one argument (context), causing TS2554; fix by either (A) replacing those calls
with createClerkClientWithOptions(mockContext, { secretKey, publishableKey,
apiUrl }) so the options are accepted, or (B) modify the clerkClient function
signature to accept a second optional options parameter and forward it to the
underlying implementation; update the two usages in createAccountlessApplication
and completeOnboarding accordingly to match whichever approach you choose.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/astro/src/integration/create-integration.ts`:
- Around line 58-62: The integration currently logs an error when both
resolvedKeys.publishableKey and resolvedKeys.secretKey are missing but continues
execution, which can cause later failures; update the create-integration logic
(around resolvedKeys checks in createIntegration/createIntegrationConfig in
create-integration.ts) to fail-fast by throwing a descriptive Error after the
logger.error call (or replace the log with a thrown Error) so setup aborts
immediately when neither key is available; ensure the thrown message mirrors the
logged text so callers receive a clear explanation about missing
PUBLIC_CLERK_PUBLISHABLE_KEY / CLERK_SECRET_KEY or keyless mode behavior.
- Around line 30-56: The resolveKeysWithKeylessFallback function contains a
series of unconditional console.log calls prefixed with "[Keyless Debug]" that
must be removed; edit the resolveKeysWithKeylessFallback implementation to
delete all console.log(...) debug statements (the ones with "[Keyless Debug]"
text) and, if runtime diagnostics are still required, replace them with the
appropriate logger calls (e.g., logger.debug) or structured error handling
rather than console.log; ensure no stray console.log remain in that function.

Comment on lines 58 to 62
if (!resolvedKeys.publishableKey && !resolvedKeys.secretKey) {
logger.error(
'Missing Clerk keys. Set PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY environment variables, or let keyless mode generate them automatically.',
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Error is logged but execution continues, potentially leading to downstream failures.

When neither keys are resolved nor configured, an error is logged but the integration setup continues. This may cause unclear runtime errors later when Clerk operations fail due to missing authentication.

Consider whether this should throw to fail fast, or document clearly that this is intentional for graceful degradation in certain scenarios.

🤖 Prompt for AI Agents
In `@packages/astro/src/integration/create-integration.ts` around lines 58 - 62,
The integration currently logs an error when both resolvedKeys.publishableKey
and resolvedKeys.secretKey are missing but continues execution, which can cause
later failures; update the create-integration logic (around resolvedKeys checks
in createIntegration/createIntegrationConfig in create-integration.ts) to
fail-fast by throwing a descriptive Error after the logger.error call (or
replace the log with a thrown Error) so setup aborts immediately when neither
key is available; ensure the thrown message mirrors the logged text so callers
receive a clear explanation about missing PUBLIC_CLERK_PUBLISHABLE_KEY /
CLERK_SECRET_KEY or keyless mode behavior.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/astro/package.json`:
- Around line 99-100: The package.json currently sets a conflicting
devDependency "vite": "^7.1.0" while "astro": "^5.15.9" expects vite in the 6.x
range; fix this by editing package.json to either remove the "vite"
devDependency so Astro's pinned vite is used, or change the "vite" entry to a
compatible 6.x version such as "^6.4.1"; ensure the modification targets the
"vite" key in package.json and keep "astro" unchanged.

Comment on lines +99 to +100
"astro": "^5.15.9",
"vite": "^7.1.0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check vite latest version and 7.x versions
echo "=== Vite Latest Version ==="
curl -s https://registry.npmjs.org/vite/latest | jq '{name: .name, version: .version}'

echo ""
echo "=== Vite 7.x Versions (last 10) ==="
curl -s "https://registry.npmjs.org/vite" | jq -r '[.versions | keys[] | select(startswith("7."))] | sort | .[-10:][]'

echo ""
echo "=== Astro 5 Vite Dependency Specification ==="
curl -s "https://registry.npmjs.org/astro/5.15.9" | jq '.peerDependencies, .devDependencies | select(. != null) | with_entries(select(.key == "vite"))'

Repository: clerk/javascript

Length of output: 291


🏁 Script executed:

#!/bin/bash
# Check if vite 7.1.0 specifically exists
echo "=== Check vite 7.0.x and 7.1.x versions ==="
curl -s "https://registry.npmjs.org/vite" | jq -r '[.versions | keys[] | select(startswith("7.0.") or startswith("7.1."))] | sort'

echo ""
echo "=== Astro 5.15.9 ALL dependencies ==="
curl -s "https://registry.npmjs.org/astro/5.15.9" | jq '.dependencies, .devDependencies, .peerDependencies, .optionalDependencies' | grep -A 5 vite || echo "No vite found in dependencies"

echo ""
echo "=== Astro 5.15.9 full dependency keys ==="
curl -s "https://registry.npmjs.org/astro/5.15.9" | jq 'keys'

Repository: clerk/javascript

Length of output: 1426


Remove or downgrade vite to version 6.

Astro 5.15.9 specifies vite as a dependency with ^6.4.1. Setting vite@^7.1.0 as a devDependency creates a version conflict that will cause installation to fail. Either remove the vite devDependency to use Astro's pinned version, or downgrade to ^6.4.1 or higher within the 6.x range.

🤖 Prompt for AI Agents
In `@packages/astro/package.json` around lines 99 - 100, The package.json
currently sets a conflicting devDependency "vite": "^7.1.0" while "astro":
"^5.15.9" expects vite in the 6.x range; fix this by editing package.json to
either remove the "vite" devDependency so Astro's pinned vite is used, or change
the "vite" entry to a compatible 6.x version such as "^6.4.1"; ensure the
modification targets the "vite" key in package.json and keep "astro" unchanged.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/astro/src/integration/create-integration.ts`:
- Around line 100-103: Remove the unnecessary injection of the secret key into
Vite's define by deleting the buildEnvVarFromOption invocation that uses
resolvedKeys.secretKey / 'CLERK_SECRET_KEY'; the secret is consumed from
process.env (e.g., in keyless/index.ts) and should not be string-replaced into
import.meta.env via the Vite define option — locate the array where
buildEnvVarFromOption(...) is spread (the entries for
resolvedKeys.publishableKey, resolvedKeys.secretKey, resolvedKeys.claimUrl,
resolvedKeys.apiKeysUrl) and remove the entry referencing resolvedKeys.secretKey
/ 'CLERK_SECRET_KEY' so only publishable/claim/api keys remain defined for
import.meta.env.

Comment on lines 100 to 103
...buildEnvVarFromOption(resolvedKeys.publishableKey, 'PUBLIC_CLERK_PUBLISHABLE_KEY'),
...buildEnvVarFromOption(resolvedKeys.secretKey, 'CLERK_SECRET_KEY'),
...buildEnvVarFromOption(resolvedKeys.claimUrl, 'PUBLIC_CLERK_KEYLESS_CLAIM_URL'),
...buildEnvVarFromOption(resolvedKeys.apiKeysUrl, 'PUBLIC_CLERK_KEYLESS_API_KEYS_URL'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check CLERK_SECRET_KEY usage in astro package
rg -n "CLERK_SECRET_KEY" packages/astro/src/ --type ts -C 2

Repository: clerk/javascript

Length of output: 4576


🏁 Script executed:

# Find buildEnvVarFromOption implementation to understand how it processes secret keys
rg -n "buildEnvVarFromOption" packages/astro/src/ --type ts -A 5 -B 2

Repository: clerk/javascript

Length of output: 3259


🏁 Script executed:

# Check the file containing the integration to understand how Vite define is configured
cat -n packages/astro/src/integration/create-integration.ts | head -120

Repository: clerk/javascript

Length of output: 6385


🏁 Script executed:

# Check for Astro/Vite configuration related to env variable handling
fd -e "astro.config" -e "vite.config" packages/astro/ --type f

Repository: clerk/javascript

Length of output: 425


🏁 Script executed:

# Check if import.meta.env.CLERK_SECRET_KEY is actually used anywhere
rg -n "import\.meta\.env\.CLERK_SECRET_KEY" packages/astro/src/ --type ts

Repository: clerk/javascript

Length of output: 42


🏁 Script executed:

# Check if there's any client-side code that might access the secret
rg -n "import\.meta\.env\." packages/astro/src/ --type ts | grep -i secret

Repository: clerk/javascript

Length of output: 42


🏁 Script executed:

# Verify the actual env access patterns being used
rg -n "process\.env\.CLERK_SECRET_KEY|import\.meta\.env\.CLERK_SECRET_KEY" packages/astro/src/ --type ts

Repository: clerk/javascript

Length of output: 408


🏁 Script executed:

# Check Astro's documentation patterns or comments about env handling
rg -n "context.*server.*secret|access.*secret" packages/astro/src/ --type ts -B 2 -A 2

Repository: clerk/javascript

Length of output: 876


🏁 Script executed:

# Check the full env schema definition to understand how Astro handles context: 'server'
cat -n packages/astro/src/integration/create-integration.ts | sed -n '215,235p'

Repository: clerk/javascript

Length of output: 943


🏁 Script executed:

# Look for how other variables marked as 'server' are handled in Vite define
rg -n "context.*server" packages/astro/src/integration/create-integration.ts -B 2 -A 2

Repository: clerk/javascript

Length of output: 505


🏁 Script executed:

# Check if there's any documentation or patterns about Vite define with Astro env schema
rg -n "vite.*define|define.*vite" packages/astro/src/ --type ts -B 3 -A 3

Repository: clerk/javascript

Length of output: 42


🏁 Script executed:

# Verify if the secret key is actually needed in Vite define or if it's redundant
rg -n "resolvedKeys\." packages/astro/src/integration/create-integration.ts --type ts -A 1 -B 1

Repository: clerk/javascript

Length of output: 1006


Remove unnecessary CLERK_SECRET_KEY injection via Vite define at line 101.

The secret key is injected into Vite's define option but is never accessed via import.meta.env.CLERK_SECRET_KEY. Actual server-side code uses process.env.CLERK_SECRET_KEY instead (seen in keyless/index.ts). This dead code should be removed to eliminate potential exposure risk, especially since Vite's define performs unconditional string replacement at build time regardless of Astro's env schema restrictions.

🤖 Prompt for AI Agents
In `@packages/astro/src/integration/create-integration.ts` around lines 100 - 103,
Remove the unnecessary injection of the secret key into Vite's define by
deleting the buildEnvVarFromOption invocation that uses resolvedKeys.secretKey /
'CLERK_SECRET_KEY'; the secret is consumed from process.env (e.g., in
keyless/index.ts) and should not be string-replaced into import.meta.env via the
Vite define option — locate the array where buildEnvVarFromOption(...) is spread
(the entries for resolvedKeys.publishableKey, resolvedKeys.secretKey,
resolvedKeys.claimUrl, resolvedKeys.apiKeysUrl) and remove the entry referencing
resolvedKeys.secretKey / 'CLERK_SECRET_KEY' so only publishable/claim/api keys
remain defined for import.meta.env.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/astro/src/server/clerk-middleware.ts`:
- Around line 112-114: The empty catch in
packages/astro/src/server/clerk-middleware.ts is swallowing errors from the
keyless initialization try block; update that catch to at minimum log the caught
error in development (e.g., check NODE_ENV or use the module logger) with a
clear message like "keyless init failed" and include the error object, and keep
silent/quiet behavior in production if desired—modify the catch inside the
keyless init try/catch to emit this conditional log so failures are visible
during debugging.

Comment on lines +112 to +114
} catch (error) {
// Silently fail - continue without keyless
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Silent error swallowing hinders debugging.

The empty catch block will make it extremely difficult to diagnose keyless mode failures. At minimum, log the error in development:

       } catch (error) {
-        // Silently fail - continue without keyless
+        // Continue without keyless, but log for debugging
+        if (import.meta.env.DEV) {
+          console.warn('[Clerk] Keyless resolution failed, falling back to configured keys:', error);
+        }
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
// Silently fail - continue without keyless
}
} catch (error) {
// Continue without keyless, but log for debugging
if (import.meta.env.DEV) {
console.warn('[Clerk] Keyless resolution failed, falling back to configured keys:', error);
}
}
🤖 Prompt for AI Agents
In `@packages/astro/src/server/clerk-middleware.ts` around lines 112 - 114, The
empty catch in packages/astro/src/server/clerk-middleware.ts is swallowing
errors from the keyless initialization try block; update that catch to at
minimum log the caught error in development (e.g., check NODE_ENV or use the
module logger) with a clear message like "keyless init failed" and include the
error object, and keep silent/quiet behavior in production if desired—modify the
catch inside the keyless init try/catch to emit this conditional log so failures
are visible during debugging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant