Skip to content

RFC: SDKs & Framework Middleware Libraries #524

@lakhansamani

Description

@lakhansamani

RFC: SDKs & Framework Middleware Libraries

Phase: 6 — Developer Experience & Polish
Priority: P2 — High
Estimated Effort: High


Problem Statement

Authorizer's current SDK ecosystem is limited. Downstream services need easy-to-use, typed clients for all Authorizer APIs and framework-specific middleware for permission checks. Without quality SDKs, developer adoption suffers. Clerk's developer experience is their primary differentiator — Authorizer needs to close this gap.


Proposed Solution

1. Go SDK — `authorizer-go`

Typed client for all Authorizer APIs:

import "github.com/authorizerdev/authorizer-go"

client := authorizer.NewClient(authorizer.Config{
    AuthorizerURL: "https://auth.example.com",
    ClientID:      "...",
    ClientSecret:  "...",  // optional, for admin/M2M operations
})

// User auth
resp, err := client.Login(ctx, authorizer.LoginInput{Email: "...", Password: "..."})

// Token validation
claims, err := client.ValidateToken(ctx, "eyJ...")

// Permission check
allowed, err := client.CheckPermission(ctx, "user_123", "documents:write", "doc_456")

// Admin operations
users, err := client.Admin.ListUsers(ctx, authorizer.PaginationInput{Page: 1, Limit: 10})
auditLogs, err := client.Admin.ListAuditLogs(ctx, authorizer.AuditLogFilter{Action: "user.login_success"})

Gin middleware:

import authzmw "github.com/authorizerdev/authorizer-go/middleware/gin"

router.Use(authzmw.Authenticate(client))                          // validate token
router.Use(authzmw.RequirePermission(client, "documents:read"))   // check permission
router.Use(authzmw.RequireRole("admin"))                          // check role

2. Node.js/TypeScript SDK — `@authorizer/authorizer-js` (enhance existing)

import { Authorizer } from '@authorizer/authorizer-js';

const client = new Authorizer({
    authorizerURL: 'https://auth.example.com',
    clientID: '...',
});

// Typed responses
const { data, errors } = await client.login({ email: '...', password: '...' });
const { data: user } = await client.getProfile();
const isAllowed = await client.checkPermission('documents:write', 'doc_456');

Express middleware:

import { authenticate, requirePermission } from '@authorizer/authorizer-js/express';

app.use(authenticate(client));
app.get('/docs/:id', requirePermission(client, 'documents:read'), handler);

Next.js integration:

import { withAuth } from '@authorizer/authorizer-js/next';
export default withAuth(handler, { permission: 'documents:read' });

3. Python SDK — `authorizer-python`

from authorizer import Authorizer

client = Authorizer(
    authorizer_url="https://auth.example.com",
    client_id="...",
)

# Auth
response = client.login(email="...", password="...")
claims = client.validate_token("eyJ...")
allowed = client.check_permission("user_123", "documents:write", "doc_456")

FastAPI middleware:

from authorizer.fastapi import AuthorizerDep, require_permission

@app.get("/docs/{doc_id}")
async def get_doc(user: AuthorizerDep, doc_id: str):
    ...

@app.get("/admin/users")
@require_permission("users:manage")
async def admin_users(user: AuthorizerDep):
    ...

4. React Component Library — `@authorizer/react`

Pre-built, themeable components:

import { AuthorizerProvider, LoginForm, SignupForm, OrgSwitcher, SessionManager, APIKeyManager } from '@authorizer/react';

function App() {
    return (
        <AuthorizerProvider config={{ authorizerURL: '...', clientID: '...' }}>
            <LoginForm 
                onLogin={(user) => console.log(user)}
                showSocialLogins={true}
                showPasskeys={true}
            />
            <OrgSwitcher />
            <SessionManager />       {/* View/revoke active sessions */}
            <APIKeyManager />        {/* Create/manage API keys */}
        </AuthorizerProvider>
    );
}

SDK Architecture Principles

  1. Generated from GraphQL schema — use code generation to keep SDKs in sync with the API
  2. Typed responses — full TypeScript/Go types for all responses
  3. Zero dependencies where possible (or minimal deps)
  4. Consistent patterns — same method names across languages
  5. Error handling — structured errors with codes, not just strings
  6. Retry logic — built-in retry with exponential backoff for transient failures

Repository Structure

Each SDK is a separate repository under the authorizerdev org:

  • authorizerdev/authorizer-go
  • authorizerdev/authorizer-js (existing, enhance)
  • authorizerdev/authorizer-python
  • authorizerdev/authorizer-react (existing, enhance)

Testing Plan

  • Each SDK has its own test suite running against a test Authorizer instance
  • CI/CD runs SDK tests on every Authorizer release
  • Type generation tests verify SDK types match GraphQL schema
  • Integration tests cover all major flows (login, token validation, permission check, admin ops)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions