Authorization
The createAuthzInterceptor enforces access control after authentication. It supports declarative rules, proto-based options, and a programmatic fallback callback.
Declarative Rules
Define rules as an ordered list. The first matching rule wins:
import { createAuthzInterceptor } from '@connectum/auth';
const authz = createAuthzInterceptor({
defaultPolicy: 'deny',
rules: [
{ name: 'public', methods: ['public.v1.PublicService/*'], effect: 'allow' },
{ name: 'admin-only', methods: ['admin.v1.AdminService/*'], requires: { roles: ['admin'] }, effect: 'allow' },
{ name: 'write-scope', methods: ['data.v1.DataService/Write*'], requires: { scopes: ['write'] }, effect: 'allow' },
],
});2
3
4
5
6
7
8
9
10
Rule Fields
| Field | Type | Description |
|---|---|---|
name | string | Rule name for logging and debugging |
methods | string[] | Method patterns (same syntax as createMethodFilterInterceptor) |
requires | { roles?, scopes? } | Required roles and/or scopes |
effect | 'allow' | 'deny' | What to do when the rule matches |
Matching Semantics
- Roles use any-of semantics -- the user needs at least one of the listed roles.
- Scopes use all-of semantics -- the user needs all listed scopes.
- Rules without
requiresmatch all authenticated users (or all requests, if the method is public).
Method Patterns
| Pattern | Description |
|---|---|
'public.v1.PublicService/*' | All methods of the service |
'data.v1.DataService/Write*' | Methods starting with Write |
'admin.v1.AdminService/DeleteUser' | Exact method match |
Programmatic Callback
For complex logic that can not be expressed as rules, add an authorize callback. It is invoked only when no rule matches:
const authz = createAuthzInterceptor({
defaultPolicy: 'deny',
rules: [...],
authorize: (context, req) => context.roles.includes('superadmin'),
});2
3
4
5
If authorize returns true, the request is allowed. If it returns false, the defaultPolicy applies.
Proto-Based Authorization
For defining authorization rules directly in .proto files using custom options, see the dedicated Proto-Based Authorization page. Proto options are read at runtime by createProtoAuthzInterceptor() and take priority over programmatic rules.
Interceptor Chain Position
Auth and authz interceptors must be placed after errorHandler and before resilience interceptors:
errorHandler -> AUTH -> AUTHZ -> timeout -> bulkhead -> circuitBreaker -> retry -> ...This ensures:
- Authentication errors are properly formatted by
errorHandler - Unauthenticated requests are rejected before consuming resilience resources
- Auth context is available to all downstream interceptors
const server = createServer({
services: [routes],
interceptors: [
...createDefaultInterceptors(),
jwtAuth, // after errorHandler chain
authz, // after authentication
],
});2
3
4
5
6
7
8
Full Example
import { createServer } from '@connectum/core';
import { createDefaultInterceptors } from '@connectum/interceptors';
import { createJwtAuthInterceptor, createAuthzInterceptor } from '@connectum/auth';
const jwtAuth = createJwtAuthInterceptor({
jwksUri: 'https://auth.example.com/.well-known/jwks.json',
issuer: 'https://auth.example.com/',
});
const authz = createAuthzInterceptor({
defaultPolicy: 'deny',
rules: [
{ name: 'public', methods: ['public.v1.PublicService/*'], effect: 'allow' },
{ name: 'admin-only', methods: ['admin.v1.AdminService/*'], requires: { roles: ['admin'] }, effect: 'allow' },
{ name: 'write-scope', methods: ['data.v1.DataService/Write*'], requires: { scopes: ['write'] }, effect: 'allow' },
],
authorize: (context, req) => {
// Fallback: superadmins can do anything
return context.roles.includes('superadmin');
},
});
const server = createServer({
services: [routes],
interceptors: [...createDefaultInterceptors(), jwtAuth, authz],
});
await server.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Related
- Auth Overview -- all authentication strategies
- JWT Authentication -- token verification
- Proto-Based Authorization -- declarative authz via
.protooptions - Auth Context -- accessing identity in handlers
- Method Filtering -- per-method interceptor routing
- @connectum/auth -- Package Guide
- @connectum/auth API -- Full API Reference
- ADR-024: Auth/Authz Strategy -- design rationale
