npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@authfn/core

v0.0.1

Published

Authentication self deployed

Readme

authfn

API key authentication library using Superfunctions abstractions.

Overview

authfn is a reference implementation of the @superfunctions/auth abstraction that provides API key-based authentication. It includes:

  • Auth Provider: Conforms to @superfunctions/auth interface
  • Database Storage: Uses @superfunctions/db adapters for storing API keys
  • Management API: Optional HTTP API for managing keys (uses @superfunctions/http)
  • Key Generation: Secure API key generation and validation

Installation

npm install authfn @superfunctions/db @superfunctions/http

Quick Start

1. Generate Schema

First, generate the database schema for your ORM:

npx @superfunctions/cli generate-schema \
  --config ./node_modules/authfn \
  --adapter drizzle \
  --output ./src/db

2. Setup Database

import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import * as authSchema from './db/authfn-schema';

const client = postgres(process.env.DATABASE_URL);
const db = drizzle(client, { schema: authSchema });

3. Create authfn Instance

import { createAuthFn } from 'authfn';
import { drizzleAdapter } from '@superfunctions/db/adapters';

const adapter = drizzleAdapter({ db, dialect: 'postgres' });

const auth = createAuthFn({
  database: adapter,
  namespace: 'authfn',
  enableApi: true,
  apiConfig: {
    adminKey: process.env.ADMIN_KEY, // Optional: protect management API
  },
});

4. Use with Libraries

Use the auth provider with any library accepting @superfunctions/auth:

import { createConductBackend } from 'conduct-backend';

const conduct = createConductBackend({
  database: adapter,
  auth: auth.provider,
});

5. Mount API

Mount both the auth management API and your library's API:

import express from 'express';
import { toExpress } from '@superfunctions/http-express';

const app = express();

// Mount auth management API
app.use('/api/auth', toExpress(auth.router));

// Mount your library's API
app.use('/api/conduct', toExpress(conduct.router));

app.listen(3000);

API Reference

createAuthFn(config)

Creates an authfn instance.

Config Options:

{
  database: Adapter;           // Database adapter
  namespace?: string;          // Table prefix (default: 'authfn')
  enableApi?: boolean;         // Enable management API (default: false)
  apiConfig?: {
    basePath?: string;         // API base path (default: '/auth')
    adminKey?: string;         // Admin key for managing keys
  };
}

Returns:

{
  provider: AuthProvider;      // Auth provider for use with libraries
  router?: Router;             // Management API router (if enabled)
  createKey: Function;         // Create API key programmatically
  revokeKey: Function;         // Revoke API key
  getKey: Function;            // Get API key by ID
  listKeys: Function;          // List API keys
}

Management API Endpoints

When enableApi is true, the following endpoints are available:

POST /keys

Create a new API key.

Request:

{
  "name": "My API Key",
  "resourceIds": ["project_abc", "project_def"],
  "scopes": ["read", "write"],
  "metadata": { "team": "engineering" },
  "expiresAt": "2025-12-31T23:59:59Z"
}

Response:

{
  "id": "key_abc123",
  "key": "ak_64characterhexstring..."
}

Note: The actual key value is only returned once during creation. Store it securely.

GET /keys

List all API keys (without key values).

Query Parameters:

  • resourceId - Filter by resource ID

Response:

{
  "keys": [
    {
      "id": "key_abc123",
      "name": "My API Key",
      "resourceIds": ["project_abc"],
      "scopes": ["read", "write"],
      "metadata": { "team": "engineering" },
      "expiresAt": "2025-12-31T23:59:59Z",
      "lastUsedAt": "2025-01-15T10:30:00Z",
      "createdAt": "2025-01-01T00:00:00Z"
    }
  ]
}

GET /keys/:id

Get a specific API key by ID (without key value).

DELETE /keys/:id

Revoke an API key.

Response:

{
  "success": true
}

Programmatic Usage

You can also create and manage keys programmatically:

// Create a key
const { id, key } = await auth.createKey({
  name: 'My API Key',
  resourceIds: ['project_abc'],
  scopes: ['read', 'write'],
  expiresAt: new Date('2025-12-31'),
});

// List keys
const keys = await auth.listKeys();

// Get a key
const apiKey = await auth.getKey('key_abc123');

// Revoke a key
await auth.revokeKey('key_abc123');

Database Schema

authfn creates a single table:

{namespace}_api_keys

  • id - Unique identifier
  • key - API key value (unique, indexed)
  • name - Descriptive name
  • resource_ids - JSON array of resource IDs
  • scopes - JSON array of scopes/permissions
  • metadata - JSON object for additional data
  • expires_at - Expiration timestamp
  • last_used_at - Last usage timestamp
  • revoked_at - Revocation timestamp
  • created_at - Creation timestamp

Security

  • API keys are 64-character hex strings with a prefix
  • Keys are validated against database on each request
  • Expired and revoked keys are rejected
  • Management API requires admin key authentication
  • Key values are never returned in list/get operations

Integration Examples

With Conduct Backend

const auth = createAuthFn({
  database: adapter,
  enableApi: true,
});

const conduct = createConductBackend({
  database: adapter,
  auth: {
    ...auth.provider,
    // Map resourceIds to projectIds
    authenticate: async (request) => {
      const session = await auth.provider.authenticate(request);
      if (!session) return null;
      return {
        ...session,
        projectIds: session.resourceIds,
      };
    },
  },
});

Custom Implementation

Implement your own auth provider using the same abstraction:

import type { AuthProvider, AuthSession } from '@superfunctions/auth';

const customAuth: AuthProvider = {
  async authenticate(request: Request): Promise<AuthSession | null> {
    // Your custom auth logic
    return {
      id: 'user_123',
      type: 'custom',
      resourceIds: ['resource_1'],
    };
  },
};

License

MIT