Feathers UCAN Authentication

0.1.45 · active · verified Wed Apr 22

feathers-ucan is an extension for FeathersJS that integrates User Controlled Authorization Networks (UCAN) tokens into the existing JWT authentication system. Currently at version 0.1.45, the library is in an early, active development stage, with the README indicating that UCAN concepts are still emerging and the implementation is tailored to specific project needs, suggesting an iterative release cadence. Its key differentiators include the ability to register a `UcanStrategy` with the Feathers authentication service, utilities for generating UCAN capabilities (`genCapability`), and a `CoreCall` class designed to manage and propagate 'core' authentication parameters across internal service calls, aiming to optimize performance by avoiding redundant authentication checks. The package strives to remain unopinionated while providing a structured way to leverage UCAN's decentralized authorization model within a Feathers application.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart initializes a basic FeathersJS application with an authentication service, registers the `UcanStrategy` alongside a `LocalStrategy`, and sets up minimal configuration required for `feathers-ucan` to function. It demonstrates how to integrate UCAN into the standard Feathers authentication flow, enabling the application to process and verify UCAN tokens.

import { feathers } from '@feathersjs/feathers';
import express from '@feathersjs/express';
import { UcanStrategy } from 'feathers-ucan';
import { AuthenticationService, LocalStrategy, expressOauth } from '@feathersjs/authentication';
import { NotAuthenticated } from '@feathersjs/errors';

interface AppConfig {
  authentication: {
    secret: string;
    entity: string;
    service: string;
    authStrategies: string[];
    jwtOptions: {
      header: { typ: string };
      audience: string;
      issuer: string;
      algorithm: string;
      expiresIn: string;
    };
    client_ucan?: string;
    ucan_aud?: string;
  };
}

const app = express(feathers());

// Minimal configuration for authentication service
app.set('authentication', {
  secret: process.env.AUTH_SECRET ?? 'super-secret-secret-key-insecure-for-production',
  entity: 'user',
  service: 'users',
  authStrategies: ['ucan', 'local'],
  jwtOptions: {
    header: { typ: 'access' },
    audience: 'https://your-app.com',
    issuer: 'feathers',
    algorithm: 'HS256',
    expiresIn: '1d'
  },
  // feathers-ucan specific config (defaults for example)
  client_ucan: 'did:key:example-client',
  ucan_aud: 'did:key:example-app-server'
} as AppConfig['authentication']);

// Register the standard Feathers authentication service
app.use('/authentication', new AuthenticationService(app));

// Register UCAN and Local strategies
const authService = app.service('authentication') as AuthenticationService; // Cast for types
authService.register('ucan', new UcanStrategy());
authService.register('local', new LocalStrategy());

// Enable Feathers Express middleware
app.configure(express.rest());
app.configure(expressOauth());

// Basic user service for local strategy (not strictly needed for UCAN but completes the example)
app.use('/users', {
  async create(data: any) { return { id: 1, email: data.email, password: data.password }; },
  async get(id: string) {
    if (id === '1') return { id: 1, email: 'test@example.com' };
    throw new NotAuthenticated('User not found');
  }
});

// Add authentication hooks
app.service('authentication').hooks({
  before: {
    create: [
      AuthenticationService.hooks.authenticate(['ucan', 'local'])
    ]
  }
});

app.listen(3030).on('listening', () => {
  console.log('Feathers application listening on http://localhost:3030');
  console.log('Try authenticating with a UCAN token or local strategy.');
  console.log('Example: POST to http://localhost:3030/authentication with { strategy: "local", email: "test@example.com", password: "password" }');
});

view raw JSON →