noesis-auth
v0.1.3
Published
TypeScript Auth SDK for AI tool integration with the Noesis AIToolCenter platform
Maintainers
Readme
noesis-auth (TypeScript)
TypeScript Auth SDK for AI tool integration with the Noesis AIToolCenter platform.
Installation
npm install noesis-authQuick Start
JWT Validation (Tool-side)
import { JWTValidator } from "noesis-auth";
const validator = new JWTValidator(
"https://your-platform.com/.well-known/jwks.json"
);
const payload = await validator.validate(token);
console.log(payload.sub); // user ID
console.log(payload.entitlements); // tool access listExpress Middleware
import { createAuthMiddleware } from "noesis-auth";
const auth = createAuthMiddleware({
jwksUrl: "https://your-platform.com/.well-known/jwks.json",
});
// Require valid token + specific tool access (toolId accepts string or number)
app.get("/api/generate", auth.requireToolAccess("your-tool-id"), (req, res) => {
const payload = (req as any).auth; // TokenPayload
res.json({ user: payload.sub });
});
// Require valid token only (no specific tool check)
app.get("/api/profile", auth.requireAuth(), (req, res) => {
const payload = (req as any).auth;
res.json({ userId: payload.sub });
});OAuth2 Client (PKCE)
import { AuthClient } from "noesis-auth";
const client = new AuthClient("https://your-platform.com");
// Or with custom timeout (default: 10000ms)
const client2 = new AuthClient("https://your-platform.com", 15000);
// Generate PKCE pair
const { codeVerifier, codeChallenge } = await AuthClient.generatePKCE();
// Build authorization URL
const url = client.buildAuthorizeUrl("your-client-id", "http://localhost:3000/callback", {
codeChallenge,
state: crypto.randomUUID(),
});
// Exchange code for tokens
const tokens = await client.exchangeCode(
authCode,
"http://localhost:3000/callback",
"your-client-id",
codeVerifier,
);Activation Code Redemption
const result = await client.redeemCode(userToken, "AXKF-M3PQ-7RBN-W2YT");
console.log(result.tool_id); // "uuid-xxx"
console.log(result.tool_name); // "AI Translator"
console.log(result.duration_days); // 30
console.log(result.expires_at); // "2026-06-23T10:00:00+00:00" (ISO datetime)
console.log(result.token_refresh_required); // true
console.log(result.new_access_token); // new JWT if refresh requiredToken Introspection
const info = await client.introspect(token, clientId, clientSecret);
if (info.active) {
console.log(info.sub, info.entitlements);
}Token Refresh
const newTokens = await client.refreshToken(refreshToken, clientId, clientSecret);
console.log(newTokens.access_token);HS256 (Symmetric) Validation
const auth = createAuthMiddleware({
jwksUrl: "https://your-platform.com/.well-known/jwks.json",
hs256Secret: process.env.JWT_SECRET, // enables HS256 when token header declares alg=HS256
});Note: HS256 is only used when the token's JWT header explicitly declares
alg: HS256. The SDK will NOT silently fall back to HS256 if JWKS is unavailable.
Features
- JWT Validation — RS256 (JWKS) and HS256 (shared secret) with auto-detection from token header
- Express Middleware — Drop-in authentication and tool access verification
- OAuth2 Client — Authorization URL builder, code exchange, token refresh
- PKCE Support — S256 code challenge generation for public clients
- Token Introspection — Remote token validation endpoint
- Activation Codes — Redeem activation codes with full response (tool_name, duration, new_access_token)
- JWKS Retry — Automatic retry with 1s delay on JWKS fetch failure
- Timeout Protection — Configurable request timeout via AbortController (default 10s)
- Zero dependencies — Only
josefor JWT operations
Error Handling
All HTTP methods throw AuthError with a specific error code:
import { AuthClient, AuthError } from "noesis-auth";
try {
const tokens = await client.exchangeCode(...);
} catch (e) {
if (e instanceof AuthError) {
console.log(e.code); // "TOKEN_INVALID" | "NETWORK_ERROR"
console.log(e.statusCode); // HTTP status code (0 for network/timeout)
console.log(e.message); // Human-readable message
}
}| Code | Meaning |
|------|---------|
| TOKEN_EXPIRED | JWT has expired |
| TOKEN_INVALID | Server rejected the request or JWT signature invalid |
| NO_ACCESS | User lacks tool entitlement |
| NETWORK_ERROR | Timeout or connection failure |
TokenPayload Interface
interface TokenPayload {
sub: string; // User ID
iat: number; // Issued at (unix timestamp)
exp: number; // Expires at (unix timestamp)
jti: string; // Unique token ID
entitlements: Entitlement[]; // Tool access list
role?: string; // "integrator", "distributor", or undefined
is_admin?: boolean; // true for admin users
}hasToolAccess(payload, toolId) and middleware methods accept toolId as string | number (auto-coerced to string for comparison).
Security Notes
- No silent algorithm fallback: If JWKS endpoint fails and token declares RS256, validation fails explicitly. The SDK never silently falls back to HS256.
- HS256 only when token declares it: Symmetric validation only when the token’s JWT header has
alg: HS256andhs256Secretis configured. - Timeout protection: All HTTP requests use AbortController with configurable timeout (default 10s).
Requirements
- Node.js >= 18.0.0
- ESM (type: "module")
License
MIT
