Skip to main content

Overview

Polaris IDE uses Stack Auth for authentication. All API requests must include a valid JWT token in the Authorization header.

Authentication Flow

  1. User signs in via Stack Auth (frontend)
  2. Stack Auth issues a JWT access token
  3. Frontend includes token in API requests
  4. Backend validates token and extracts user identity

Getting Your Access Token

From the Frontend

If you’re building a frontend application, use the Stack Auth SDK:
JavaScript
import { useUser } from '@stackframe/stack';

const YourComponent = () => {
  const user = useUser();
  
  // Get access token
  const token = await user.getAuthJson().then(auth => auth.accessToken);
  
  // Use token in API request
  const response = await fetch('/api/projects/create', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({ name: 'My Project' })
  });
};

For Testing (Development Only)

During development, you can obtain a token from the browser:
  1. Open your Polaris IDE instance
  2. Open browser DevTools (F12)
  3. Run in console:
// Get the current user's token
const token = await window.__STACK__.user.getAuthJson().then(auth => auth.accessToken);
console.log(token);
Never hardcode tokens in production code. Always obtain them dynamically from Stack Auth.

Making Authenticated Requests

Include the JWT token in the Authorization header:
cURL
curl -X POST https://your-domain.com/api/projects/create \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{"name": "My New Project"}'
Fetch API
const response = await fetch('/api/projects/create', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  },
  body: JSON.stringify({ name: 'My Project' })
});

const data = await response.json();
Python
import requests

headers = {
    'Content-Type': 'application/json',
    'Authorization': f'Bearer {token}'
}

response = requests.post(
    'https://your-domain.com/api/projects/create',
    headers=headers,
    json={'name': 'My Project'}
)

data = response.json()

Authentication Errors

401 Unauthorized

Returned when the token is missing, invalid, or expired:
{
  "error": "Unauthorized"
}
Common causes:
  • Missing Authorization header
  • Invalid or expired JWT token
  • Token not properly formatted (should be Bearer TOKEN)
Solution:
  • Ensure the token is included in the header
  • Obtain a fresh token from Stack Auth
  • Check token format

403 Forbidden

Returned when authenticated but lacking permissions:
{
  "error": "GitHub not connected. Please connect GitHub in your account settings."
}
Or when project limits are reached:
{
  "error": "Project limit reached. Please upgrade to Pro for unlimited projects.",
  "currentUsage": 10,
  "limit": 10,
  "allowed": false
}

Environment Configuration

For self-hosted instances, configure Stack Auth in your environment:
.env
# Stack Auth
NEXT_PUBLIC_STACK_PUBLISHABLE_KEY=your_publishable_key
STACK_SECRET_KEY=your_secret_key

Backend Implementation

If you’re building integrations or want to understand how authentication works internally:

requireAuth() Helper

All API routes use the requireAuth() helper from src/lib/stack-auth-api.ts:
import { requireAuth } from '@/lib/stack-auth-api';

export async function POST(request: Request) {
  const { user, userId, response } = await requireAuth();
  
  // If not authenticated, return early
  if (!user) {
    return response; // Returns 401 error
  }
  
  // User is authenticated, proceed with logic
  // userId contains the Stack Auth user ID
}

Token Validation

Stack Auth validates tokens automatically. The requireAuth() function:
  1. Extracts the JWT from the Authorization header
  2. Validates the token signature and expiration
  3. Returns user object with ID and metadata
  4. Returns 401 error response if invalid

Security Best Practices

Always use HTTPS to prevent token interception. Never send tokens over unencrypted HTTP connections.
Never hardcode or commit tokens to version control. Use environment variables and secure secret management.
JWT tokens have expiration times. Implement token refresh logic in your application.
Always validate tokens server-side. Never trust client-side validation alone.

Migration from Clerk

Polaris IDE was migrated from Clerk to Stack Auth. If you’re maintaining an older version, update to use Stack Auth for better integration.
The database schema still maintains clerkId for backward compatibility during migration:
users: defineTable({
  stackUserId: v.string(),      // Current - Stack Auth ID
  clerkId: v.optional(v.string()), // Legacy - for migration
  // ...
})

Next Steps

Projects API

Start creating projects

Messages API

Send AI conversation messages

Build docs developers (and LLMs) love