Authentication
Protect your upload endpoints with authentication
Overview
Clawdy provides two layers of authentication:
- Middleware authentication -- validate users before they can upload files
- API key authentication -- secure server-to-server communication with your Clawdy instance
Middleware Authentication
Use the .middleware() method on your file router to run authentication logic before any upload begins. The middleware receives the request object, allowing you to extract session tokens, cookies, or headers.
import { createClawdy, ClawdyError } from "@clawdyup/core";
const f = createClawdy();
export const uploadRouter = {
profileImage: f({ image: { maxFileSize: "4MB" } })
.middleware(async ({ req }) => {
// Replace with your own auth logic
const user = await auth(req);
if (!user) {
throw new ClawdyError("Unauthorized");
}
// Return metadata that will be available in onUploadComplete
return { userId: user.id, email: user.email };
})
.onUploadComplete(async ({ metadata, file }) => {
console.log("Upload complete for user:", metadata.userId);
console.log("File URL:", file.url);
}),
};How It Works
- A user initiates an upload from the client.
- Clawdy calls your
.middleware()function with the incoming request. - If the middleware throws an
ClawdyError, the upload is rejected immediately. - If the middleware returns successfully, the returned object becomes the
metadataavailable inonUploadComplete.
Throwing Errors
When a user fails authentication, throw an ClawdyError to reject the upload with a meaningful message:
.middleware(async ({ req }) => {
const user = await auth(req);
if (!user) {
throw new ClawdyError("Unauthorized");
}
if (!user.canUpload) {
throw new ClawdyError("You do not have permission to upload files");
}
return { userId: user.id };
})The error message is forwarded to the client, so you can display it in your UI.
Passing Metadata
Whatever object you return from the middleware is passed as metadata to onUploadComplete. Use this to associate uploads with users, organizations, or any other context:
.middleware(async ({ req }) => {
const user = await auth(req);
if (!user) {
throw new ClawdyError("Unauthorized");
}
return {
userId: user.id,
email: user.email,
orgId: user.orgId,
plan: user.plan,
};
})
.onUploadComplete(async ({ metadata, file }) => {
// metadata.userId, metadata.email, etc. are all available here
await db.files.create({
url: file.url,
uploadedBy: metadata.userId,
organization: metadata.orgId,
});
})API Key Authentication
When communicating between your backend and the Clawdy server, use API key authentication. Set the CLAWDY_API_KEYS environment variable on your Clawdy server with one or more comma-separated keys:
CLAWDY_API_KEYS=sk_live_abc123,sk_live_def456Then pass the API key in your SDK configuration using a Bearer token:
import { createClawdy } from "@clawdyup/core";
const f = createClawdy({
apiKey: "sk_live_abc123",
});The SDK sends this as a Bearer token in the Authorization header when communicating with the Clawdy server.
Keep your API keys secret. Never expose them in client-side code or commit them to version control. Use environment variables to manage them safely.
Open Mode
If CLAWDY_API_KEYS is left empty on the server, the server runs in open mode -- no API key is required. This is convenient for local development but should never be used in production.