Skip to main content
rule

clerk — Cursor rule: secure Clerk integration

A Cursor rule that pins down how Clerk auth should be wired: PKCE, server-side checks, short-lived tokens. Useful once Clerk is already in your stack.

Install into Cursor · Manually: put the files in place All methods and platforms ↓
.cursor/rules/clerk.mdc
Open on GitHub

What clerk does

The file .cursor/rules/clerk.mdc applies to every file in the project (**/*) and feeds Cursor a fixed set of conventions whenever it writes auth code. It splits into two parts: security, and sessions with tokens. Each item comes with a bad example and a good one.

The security section bans the implicit grant in favour of Authorization Code Flow with PKCE, pushes every authorization decision to the server through Clerk's backend SDKs, and keeps API keys and secrets in a managed secrets manager instead of source files. HTTPS is required throughout. Password policy follows NIST SP 800-63B: at least 8 characters with MFA or 15 without, a maximum of at least 64, breached-password detection, MFA for all users. JWTs get checked on signature, aud, iss and exp, signed with RS256 or ES256.

Sessions are configured around short-lived access tokens refreshed by refresh tokens, and the rule tells you to leave JWT parsing to the SDK rather than doing it by hand. This one assumes Clerk is your identity provider — point it at a project running something else and the examples stop matching your code.

What it helps with

  • strip hardcoded Clerk secrets out of the codebase
  • move role checks from the client to the server
  • switch from implicit grant to PKCE
  • set a password policy and turn on MFA
  • verify JWT signature and claims in a custom backend

Example prompts for the agent

  • Check my Clerk auth code against the clerk rule and list the violations
  • Rewrite this API route so the role check happens server-side with Clerk
  • Configure the Clerk session to use short-lived access tokens with refresh

How to install clerk

Manually: put the files in place

.cursor/rules/clerk.mdc

Frontmatter: description, globs, alwaysApply

Step by step, with commands for each platform: Cursor rules: .mdc files, four modes and what replaced .cursorrules

Questions about clerk

How do I install the clerk rule in Cursor?

Create .cursor/rules/clerk.mdc in your project root and paste the rule contents into it. Cursor picks it up on its own, since the globs field is **/*.

What does the clerk rule do?

It gives Cursor a checklist for Clerk integration: PKCE, server-side authorization, secret storage, password policy, MFA and JWT validation. The agent follows it while writing or editing auth code.

Do I need Clerk in my project for this rule to apply?

Yes. Every example and requirement targets Clerk and its SDKs such as @clerk/nextjs and @clerk/clerk-sdk-node. Swap in another auth provider and they no longer fit.

Source text

clerk.mdc · CC0-1.0
---
description: This guide establishes definitive best practices for integrating Clerk, focusing on robust security, efficient session management, and secure token handling in line with modern OAuth 2.0 (RFC 9700) and JWT (RFC 8725) standards.
globs: **/*
---
# Clerk Best Practices

Integrating Clerk requires a security-first mindset. Authentication is a primary attack surface; therefore, all Clerk integrations MUST adhere to the strictest security standards. This guide provides actionable, opinionated best practices to ensure your application's identity layer is robust and future-proof.

## 1. Security Best Practices

### 1.1. Enforce Authorization Code Flow with PKCE

**NEVER** use the implicit grant flow. RFC 9700 explicitly deprecates it due to inherent security weaknesses. Always use the Authorization Code Flow with Proof Key for Code Exchange (PKCE). Clerk's client-side SDKs handle PKCE automatically when correctly configured.

❌ **BAD: Relying on deprecated flows (e.g., implicit grant)**
```javascript
// Avoid configuring Clerk in ways that force implicit grants
// (e.g., older SDK versions or misconfigurations)
// Ensure your Clerk application settings are configured for PKCE.
```

✅ **GOOD: Utilize Clerk's Authorization Code Flow with PKCE (default for modern SDKs)**
```javascript
// Clerk's modern SDKs (v5.x+) use PKCE by default.
// Ensure your Clerk application is configured to require PKCE.
// Example: Initializing Clerk in a Next.js app
import { ClerkProvider } from '@clerk/nextjs';

function MyApp({ Component, pageProps }) {
  return (
    <ClerkProvider {...pageProps}>
      <Component {...pageProps} />
    </ClerkProvider>
  );
}
```

### 1.2. Centralize Authentication Logic

All authentication and authorization checks MUST occur server-side and be handled by a centralized, security-vetted library (Clerk's backend SDKs). Never perform critical authentication decisions solely on the client.

❌ **BAD: Client-side authorization decisions**
```javascript
// In a React component:
if (clerk.user.publicMetadata.role === 'admin') {
  // Render admin-only content
}
// This is easily bypassed by manipulating client-side state.
```

✅ **GOOD: Server-side authorization with Clerk's backend SDKs**
```typescript
// In a Next.js API route or server component:
import { getAuth } from '@clerk/nextjs/server';
import { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { userId, orgRole } = getAuth(req);

  if (!userId) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  if (orgRole !== 'admin') {
    return res.status(403).json({ error: 'Forbidden' });
  }

  // Proceed with admin-only logic
  res.status(200).json({ message: 'Welcome, admin!' });
}
```

### 1.3. Securely Store API Keys and Secrets

API keys, client secrets, and Clerk private keys MUST NEVER be hardcoded or stored directly in source code or configuration files. Use a managed Secrets Manager (e.g., AWS Secrets Manager, Azure Key Vault, HashiCorp Vault) and reference them at runtime via environment variables.

❌ **BAD: Hardcoding secrets**
```javascript
// .env
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY='pk_test_YOUR_PUBLISHABLE_KEY' // OK for client-side
CLERK_SECRET_KEY='sk_test_YOUR_SECRET_KEY_HARDCODED' // DANGER!

// app/api/webhook.ts
const clerkSecretKey = 'sk_test_YOUR_SECRET_KEY_HARDCODED'; // NEVER DO THIS
```

✅ **GOOD: Using environment variables and a Secrets Manager**
```javascript
// .env.local (for local development, not committed)
CLERK_SECRET_KEY=${CLERK_SECRET_KEY_FROM_SECRETS_MANAGER}

// In production, CLERK_SECRET_KEY is injected from your Secrets Manager.
// app/api/webhook.ts
const clerkSecretKey = process.env.CLERK_SECRET_KEY;
if (!clerkSecretKey) {
  throw new Error('CLERK_SECRET_KEY is not set.');
}
// Use clerkSecretKey for server-side operations
```

### 1.4. Enforce HTTPS Everywhere

All communication involving authentication credentials or sensitive data MUST occur over HTTPS. This is non-negotiable. Configure your application and infrastructure to redirect all HTTP traffic to HTTPS.

❌ **BAD: Allowing HTTP connections**
```
http://your-app.com/login // Insecure
```

✅ **GOOD: Requiring HTTPS**
```
https://your-app.com/login // Secure
```

### 1.5. Implement Strong Password Policies and MFA

Leverage Clerk's robust password policy configuration to enforce NIST SP 800-63B guidelines:
*   Minimum length: 8 characters with MFA, 15 without MFA.
*   Maximum length: At least 64 characters (allow passphrases).
*   Allow all characters (unicode, whitespace).
*   Block common/breached passwords (Clerk integrates with services like HaveIBeenPwned).
*   Enable Multi-Factor Authentication (MFA) for all users, especially for high-risk actions or sensitive accounts.

❌ **BAD: Weak password policy**
```javascript
// Clerk dashboard configured for:
// Minimum password length: 6
// No MFA required
```

✅ **GOOD: Robust password policy and MFA**
```javascript
// Clerk dashboard configured for:
// Minimum password length: 15 (or 8 with mandatory MFA)
// MFA required for all users
// Password complexity rules enabled
// Breached password detection enabled
```

### 1.6. Validate JWTs Rigorously

When handling Clerk's JWT-based sessions (e.g., in custom backend services), always validate the token's signature, audience (`aud`), issuer (`iss`), and expiration (`exp`). Use strong signing algorithms (RS256 or ES256). Clerk's backend SDKs handle this automatically; avoid manual JWT parsing and validation unless absolutely necessary and with extreme caution.

❌ **BAD: Trusting JWTs without full validation**
```javascript
// In a custom backend:
const token = req.headers.authorization?.split(' ')[1];
// const decoded = jwt.decode(token); // DANGER: Does not verify signature or claims
// if (decoded.userId) { /* grant access */ }
```

✅ **GOOD: Using Clerk's verified session/token validation**
```typescript
// In a custom backend (e.g., Express middleware):
import { ClerkExpressWithAuth } from '@clerk/clerk-sdk-node';

app.use(
  ClerkExpressWithAuth({
    jwtKey: process.env.CLERK_JWT_VERIFICATION_KEY, // Use JWKS or Clerk's provided key
  }),
  (req, res, next) => {
    // req.auth will contain validated userId, sessionId, etc.
    if (!req.auth.userId) {
      return res.status(401).json({ error: 'Unauthorized' });
    }
    next();
  }
);
```

## 2. Session Management and Token Handling

### 2.1. Enforce Short-Lived Access Tokens

Configure Clerk sessions to use short-lived access tokens. This minimizes the window of opportunity for token compromise. Refresh tokens should be used to obtain new access tokens.

❌ **BAD: Long-lived access tokens**
```javascript
// Clerk session configuration allowing very long access token lifetimes (e.g., days)
```

✅ **GOOD: Short-lived access tokens**
```javascript
// Clerk session configuration with access token lifetimes in minutes/hours, not days.
// Clerk handles refresh token rotation automatically for its SDKs.
```

### 2.2. Keep Clerk SDKs Up-to-Date

Regularly update your Clerk client and server SDKs to the latest stable versions. This ensures you benefit from security patches, performance improvements, and adherence to the latest best practices. As of early 2025, the CDN release is 5.62.0.

❌ **BAD: Sticking to old SDK versions**
```json
// package.json
"dependencies": {
  "@clerk/nextjs": "^4.x.x", // Outdated, missing critical updates
}
```

✅ **GOOD: Updating Clerk SDKs regularly**
```json
// package.json
"dependencies": {
  "@clerk/nextjs": "^5.x.x", // Always use the latest major/minor version
}
// Run `npm update @clerk/nextjs` or `yarn upgrade @clerk/nextjs`
```

## 3. Code Organization and Vulnerability Prevention

### 3.1. Isolate Clerk Initialization

Initialize Clerk at the highest possible level in your application (e.g., `_app.js` in Next.js, `main.tsx` in React). This ensures consistent behavior and avoids re-initialization issues.

❌ **BAD: Multiple Clerk initializations or conditional loading**
```javascript
// In multiple components:
// const clerk = new Clerk('pk_...'); // Inefficient and error-prone
```

✅ **GOOD: Single, top-level Clerk initialization**
```javascript
// pages/_app.tsx (Next.js)
import { ClerkProvider } from '@clerk/nextjs';
import type { AppProps } from 'next/app';

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ClerkProvider {...pageProps}>
      <Component {...pageProps} />
    </ClerkProvider>
  );
}

export default MyApp;
```

### 3.2. Implement Automated Security Scans and Code Reviews

Integrate static analysis tools, linters, and dependency scanners into your CI/CD pipeline. Require mandatory code reviews for any changes touching authentication flows, Clerk integration, or security-sensitive areas.

❌ **BAD: Manual, ad-hoc security checks**
```
// Relying solely on manual testing for security vulnerabilities.
```

✅ **GOOD: Automated and human-verified security**
```yaml
# .github/workflows/ci.yml
name: CI/CD Pipeline

jobs:
  security-scan:
    steps:
      - uses: actions/checkout@v3
      - name: Run ESLint
        run: npm run lint
      - name: Run Snyk/Dependabot
        run: snyk test # or dependabot/npm_and_yarn
      # ... other security checks
```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Similar IDE rules

Everything for Security →

From the same set69

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor