Last Updated: 2026-06-28 Status: Active
Authoritative map of every permission check in newsletter-service. Source of truth: apps/newsletter-service/src/middleware/auth.middleware.ts + route files.
1. Permission Strings
| Permission | Grants |
|---|---|
newsletter:subscribers.read |
List, stats, view individual subscribers, view segments |
newsletter:subscribers.create |
Create/import subscribers, create/update segments |
newsletter:subscribers.delete |
Delete subscribers, delete segments |
newsletter:templates.read |
List, view templates and template sections |
newsletter:templates.create |
Create/update/duplicate templates and template sections |
newsletter:templates.delete |
Delete templates and template sections |
newsletter:campaigns.read |
List, view campaigns and send records, view blog binding |
newsletter:campaigns.create |
Create/update campaigns, manage blog binding |
newsletter:campaigns.send |
Fire campaigns, cancel campaigns, test-send templates |
system:owner |
Bypasses all permission checks |
2. system:owner Bypass
Same pattern as blog-service: permissions.includes(permission) || permissions.includes("system:owner") → passes unconditionally.
3. Permission → Route Map
Subscribers (/subscribers)
| Method | Path | Permission |
|---|---|---|
POST |
/subscribers |
newsletter:subscribers.create |
GET |
/subscribers |
newsletter:subscribers.read |
GET |
/subscribers/stats |
newsletter:subscribers.read |
POST |
/subscribers/import |
newsletter:subscribers.create |
POST |
/subscribers/:id/unsubscribe |
newsletter:subscribers.create |
DELETE |
/subscribers/:id |
newsletter:subscribers.delete |
Templates (/templates)
| Method | Path | Permission |
|---|---|---|
POST |
/templates |
newsletter:templates.create |
GET |
/templates |
newsletter:templates.read |
GET |
/templates/:id |
newsletter:templates.read |
PUT |
/templates/:id |
newsletter:templates.create |
POST |
/templates/:id/duplicate |
newsletter:templates.create |
DELETE |
/templates/:id |
newsletter:templates.delete |
POST |
/templates/:id/test-send |
newsletter:campaigns.send |
Campaigns (/campaigns)
| Method | Path | Permission |
|---|---|---|
POST |
/campaigns |
newsletter:campaigns.create |
GET |
/campaigns |
newsletter:campaigns.read |
GET |
/campaigns/:id |
newsletter:campaigns.read |
PUT |
/campaigns/:id |
newsletter:campaigns.create |
POST |
/campaigns/:id/send |
newsletter:campaigns.send |
POST |
/campaigns/:id/cancel |
newsletter:campaigns.create |
GET |
/campaigns/:id/sends |
newsletter:campaigns.read |
Segments (/segments)
| Method | Path | Permission |
|---|---|---|
POST |
/segments |
newsletter:subscribers.create |
GET |
/segments |
newsletter:subscribers.read |
GET |
/segments/:id |
newsletter:subscribers.read |
PUT |
/segments/:id |
newsletter:subscribers.create |
DELETE |
/segments/:id |
newsletter:subscribers.delete |
POST |
/segments/:id/preview |
newsletter:subscribers.read |
GET |
/segments/sendable-count |
newsletter:subscribers.read |
Sections (/sections)
| Method | Path | Permission |
|---|---|---|
POST |
/sections |
newsletter:templates.create |
GET |
/sections |
newsletter:templates.read |
GET |
/sections/:id |
newsletter:templates.read |
PUT |
/sections/:id |
newsletter:templates.create |
DELETE |
/sections/:id |
newsletter:templates.delete |
Blog Binding (/blog-binding)
| Method | Path | Permission |
|---|---|---|
GET |
/blog-binding |
newsletter:campaigns.read |
PUT |
/blog-binding |
newsletter:campaigns.create |
DELETE |
/blog-binding |
newsletter:campaigns.create |
GET |
/blog-binding/context |
newsletter:campaigns.read |
No Permission Required
| Surface | Auth |
|---|---|
POST /public/subscribe |
Rate-limited; x-tenant-id from gateway |
POST /public/confirm |
HMAC token in query params |
POST /public/unsubscribe |
HMAC token in query params |
POST /internal/bounce |
x-internal-key header |
POST /internal/event |
x-internal-key header |
POST /internal/blog/post-published |
x-internal-key header |
POST /internal/blog/post-unpublished |
x-internal-key header |
4. Recommended Role Bundles
| Role | Permissions | Use case |
|---|---|---|
| Owner | system:owner |
Full access |
| Marketer | subscribers.*, templates.*, campaigns.* |
Full newsletter management |
| Campaign sender | campaigns.read, campaigns.create, campaigns.send, templates.read, subscribers.read |
Create and fire campaigns; can't manage subscribers |
| Subscriber manager | subscribers.read, subscribers.create, subscribers.delete |
Import/manage list only |
| Read only | *.read (all three namespaces) |
Reporting/analytics access |