Skip to main content

Authentication

All Traces API endpoints require authentication via Clerk JWT tokens.

Overview

Traces uses Clerk for authentication. Every request must include a valid JWT token in the Authorization header.

Getting a Token

From the Web Application

When using Traces in a browser, the Clerk SDK automatically handles authentication. API requests made from the frontend include the token automatically.

For API Access

For programmatic access, obtain a token through the Clerk API or SDK:

import { auth } from '@clerk/nextjs/server';

// In a server component or API route
const { getToken } = auth();
const token = await getToken();

Making Authenticated Requests

Include the JWT token in the Authorization header:

curl -X GET https://api.traces.io/api/collections \
-H "Authorization: Bearer <your-jwt-token>" \
-H "Content-Type: application/json"

Role-Based Access Control (RBAC)

Traces implements RBAC with three roles:

RoleDescriptionAccess Level
CustomerExternal users collecting dataOwn resources only
AnalystInternal team managing collectionsAll resources
AdminSystem administratorsFull access + admin functions

Permission Matrix

ResourceCustomerAnalystAdmin
Collections (own)Read, CreateFullFull
Collections (all)-FullFull
ConnectorsReadFullFull
Credentials (own)FullFullFull
Credentials (all)-ReadFull
CustomersOwn profileFullFull

Authentication Flow

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Client │────▶│ Clerk │────▶│ Traces │
│ │ │ │ │ API │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
│ 1. Sign in │ │
│──────────────────▶│ │
│ │ │
│ 2. JWT Token │ │
│◀──────────────────│ │
│ │ │
│ 3. API Request + Token │
│──────────────────────────────────────▶│
│ │ │
│ │ 4. Verify Token │
│ │◀──────────────────│
│ │ │
│ │ 5. User Info │
│ │──────────────────▶│
│ │ │
│ 6. Response │
│◀──────────────────────────────────────│

Implementation Example

Server-Side Authentication Check

import { auth } from '@clerk/nextjs/server';
import { prisma } from '@/lib/prisma';

export async function GET(req: Request) {
// Check authentication
const { userId } = auth();
if (!userId) {
return new Response('Unauthorized', { status: 401 });
}

// Get user role from database
const user = await prisma.user.findUnique({
where: { id: userId }
});

// Check authorization
if (user.role !== 'analyst' && user.role !== 'admin') {
return new Response('Forbidden', { status: 403 });
}

// Proceed with route logic
// ...
}

Error Responses

401 Unauthorized

Returned when no token is provided or the token is invalid:

{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required"
}
}

403 Forbidden

Returned when the user doesn't have permission for the requested resource:

{
"error": {
"code": "FORBIDDEN",
"message": "You do not have permission to access this resource"
}
}

Security Best Practices

  1. Never share tokens - JWT tokens provide full access to your account
  2. Token expiration - Tokens expire automatically; the Clerk SDK handles refresh
  3. HTTPS only - All API requests must use HTTPS in production
  4. Minimal scopes - Request only the permissions you need

Notes on Endpoint Authorization

Most read endpoints now require authentication. In particular:

  • GET /api/connectors requires an analyst/admin session (the connector catalog is internal data, not anonymously enumerable).
  • GET /api/connectors/{id} requires any authenticated user (customers read connector details when creating collections).
  • Connector mutations (PATCH, DELETE, versions, headers, test-auth) require the analyst/admin role.

Unauthenticated requests receive 401; authenticated requests lacking the required role receive 403.