Secure API keys for users and organisations
auth.createApiKey returns the raw key once and stores only its protected hash. auth.verifyApiKey rejects expired or revoked keys, requires the scopes passed by the route, and returns the owning user or organisation.
Create and display once
const { rawKey, apiKey } = await auth.createApiKey({
actorUserId: currentUser.id,
name: "Production",
scopes: ["reports:read"],
});
return { rawKey, id: apiKey.id };Verify and authorize
const value = request.headers.get("authorization") ?? "";
const rawKey = value.replace(/^Bearer\s+/i, "");
const verified = await auth.verifyApiKey(rawKey, ["reports:read"]);
return {
apiKeyId: verified.apiKey.id,
userId: verified.apiKey.userId,
organisationId: verified.apiKey.organisationId,
};- Give each integration its own key and required scopes.
- Display the raw key once and show only its prefix later.
- Set an expiry for temporary integrations.
- Revoke a key without changing any other credential.
- Keep raw keys out of URLs, logs, and analytics.