Documentation Index Fetch the complete documentation index at: https://mintlify.com/KTS-o7/permission-mongo/llms.txt
Use this file to discover all available pages before exploring further.
Architecture
Permission Mongo is designed as a high-performance middleware layer between your application and MongoDB, providing REST API, RBAC, versioning, and audit logging.
System overview
┌─────────────────────────────────────────────────────────────────────┐
│ Clients │
│ (Web App, Mobile App, FastAPI, External Services) │
└───────────────────────────────┬─────────────────────────────────────┘
│ HTTPS + JWT
▼
┌─────────────────────────────────────────────────────────────────────┐
│ Permission Mongo Service │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Configuration │ │
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────────┐ │ │
│ │ │schema.yml │ │policy.yml │ │ hooks.yml │ │ server.yml │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │• Types │ │• Roles │ │• pre/post │ │• Storage │ │ │
│ │ │• Computed │ │• Policies │ │• Webhooks │ │• Audit config │ │ │
│ │ │• Indexes │ │• Hierarchy│ │• Validate │ │• Cache TTLs │ │ │
│ │ │• Version │ │• Actions │ │ │ │• Auth config │ │ │
│ │ └───────────┘ └───────────┘ └───────────┘ └───────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ REST API Layer │ │
│ │ │ │
│ │ Single Document Batch Operations Queries │ │
│ │ ┌────────────────┐ ┌────────────────┐ ┌────────────┐ │ │
│ │ │POST /:coll │ │POST /:coll/batch│ │GET /:coll │ │ │
│ │ │GET /:coll/:id │ │PUT /:coll/batch│ │POST /:coll/│ │ │
│ │ │PUT /:coll/:id │ │DEL /:coll/batch│ │ aggregate │ │ │
│ │ │DEL /:coll/:id │ └────────────────┘ │POST /:coll/│ │ │
│ │ └────────────────┘ │ count │ │ │
│ │ └────────────┘ │ │
│ │ Versioning │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ GET /:coll/:id/versions │ │ │
│ │ │ GET /:coll/:id/versions/:v │ │ │
│ │ │ GET /:coll/:id/diff/:v1/:v2 │ │ │
│ │ │ POST /:coll/:id/restore/:v │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Core Engine │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │
│ │ │ JWT Auth │ │ RBAC Engine │ │ Schema Validator │ │ │
│ │ │ • Validate │ │ • Policies │ │ • Type checking │ │ │
│ │ │ • Extract │ │ • Hierarchy │ │ • Constraints │ │ │
│ │ │ user ctx │ │ • $subord. │ │ • References │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │
│ │ │ Query Builder│ │ Computed │ │ Hook Executor │ │ │
│ │ │ • Filters │ │ Fields │ │ • Sync/Async │ │ │
│ │ │ • Projection │ │ • Virtual │ │ • HTTP calls │ │ │
│ │ │ • Pagination │ │ • Stored │ │ • Conditions │ │ │
│ │ │ • Aggregation│ │ • Recompute │ │ │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │
│ │ │ Version │ │ Audit Logger │ │ Field Mask │ │ │
│ │ │ Manager │ │ • MongoDB │ │ • Email │ │ │
│ │ │ • Snapshot │ │ • Webhook │ │ • Phone │ │ │
│ │ │ • Diff │ │ • Stdout │ │ • Partial │ │ │
│ │ │ • Restore │ │ │ │ │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────┬──────────────────────────────────┘
│
┌───────────────┴───────────────┐
▼ ▼
┌───────────────┐ ┌───────────────┐
│ Redis │ │ MongoDB │
│ │ │ │
│ • Policies │ │ • App Data │
│ • Hierarchy │ │ • _pm_versions│
│ • Rate limits │ │ • _pm_audit │
└───────────────┘ │ • _pm_hier │
└───────────────┘
From SPECIFICATION.md:88-170.
Core components
HTTP server
Permission Mongo uses fasthttp for high-performance HTTP handling.
Key characteristics:
10x faster than net/http for high-throughput scenarios
Optimized for 256K concurrent connections
Zero-allocation routing with atomic operations
Implementation: pkg/api/server.go
// Server initialization from cmd/server/main.go:176-182
server := api . NewServer ( cfg . Server , serverOpts ... )
server . RegisterHandlers ( & api . Handlers {
Store : mongoStore ,
RBAC : rbacEngine ,
})
MongoDB store
The MongoDB store layer (pkg/store/mongo.go) provides:
Connection pooling (default: 100 connections)
CRUD operations with RBAC filter injection
Aggregation pipeline execution
Index management
Connection: See cmd/server/main.go:62-77
mongoStore := store . NewMongoStore ( mongoURI , mongoDatabase )
if err := mongoStore . Connect ( ctx ); err != nil {
return fmt . Errorf ( "failed to connect to MongoDB: %w " , err )
}
Redis cache
Redis is used for caching frequently accessed data:
Cache keys:
pm:policy:{tenant}:compiled - Compiled RBAC policies (TTL: 60s)
pm:hier:{tenant}:{user}:subs - User subordinates (TTL: 300s)
pm:schema:compiled - Schema definitions (TTL: 60s)
Connection: See cmd/server/main.go:80-91
redisCache := cache . NewRedisCache ( redisURL , cfg . Server . Redis . Password , cfg . Server . Redis . DB )
if err := redisCache . Connect ( ctx ); err != nil {
return fmt . Errorf ( "failed to connect to Redis: %w " , err )
}
From SPECIFICATION.md:1436-1451.
Schema validator
Validates documents against schema definitions before write operations.
Features:
Type checking (string, number, boolean, date, objectId, array, object)
Constraints (required, min/max, pattern, enum)
Nested object and array validation
Computed field evaluation
Implementation: pkg/schema/validator.go
Initialization: cmd/server/main.go:94-95
schemaValidator := schema . NewValidator ( cfg . Schema )
Field types from examples/config/schema.yml:18-415.
RBAC engine
The Role-Based Access Control engine enforces permissions at multiple levels:
Permission checks:
Collection-level: Can user perform action on collection?
Document-level: Does document match when clause?
Field-level: Which fields can user read/write?
Expression evaluation:
when : |
doc.company_id == user.tenant_id &&
(doc.created_by == user.id || doc.created_by in user.$subordinates)
The expression is compiled to a MongoDB query filter and cached.
Special variables:
user.id - Current user ID
user.tenant_id - User’s tenant
user.roles - User’s roles array
user.$subordinates - All subordinate user IDs (from hierarchy)
Implementation: pkg/rbac/engine.go
Initialization: cmd/server/main.go:104-105
rbacEngine := rbac . NewEngine ( cfg . Policy )
From examples/config/policy.yml:1-178.
Hierarchy resolver
Resolves organizational hierarchy for manager-subordinate relationships.
How it works:
Hierarchy defined in schema: users.manager_id references users._id
Transitive closure stored in _pm_hierarchy collection
Cached in Redis for fast lookups
Data structure:
// _pm_hierarchy collection
{
tenant_id : "acme-corp" ,
user_id : "dave" ,
ancestor_id : "alice" , // Dave reports to Alice (directly or indirectly)
depth : 2 // 2 levels up
}
Implementation: pkg/hierarchy/resolver.go
Initialization: cmd/server/main.go:98-101
hierTTL := time . Duration ( cfg . Server . Cache . HierarchyTTLSeconds ) * time . Second
hierResolver := hierarchy . NewResolver ( mongoStore , redisCache , hierTTL )
From SPECIFICATION.md:771-808.
Version manager
Tracks document change history in the _pm_versions collection.
Version storage:
// _pm_versions collection
{
_id : ObjectId ( "..." ),
collection : "orders" ,
doc_id : "order-123" ,
version : 3 ,
mode : "full" , // "full" snapshot or "diff" changes
data : { /* complete document snapshot */ },
tenant_id : "acme-corp" ,
updated_by : "user-alice" ,
updated_at : ISODate ( "2026-03-04T12:00:00Z" )
}
API endpoints:
GET /{collection}/{id}/versions - List versions
GET /{collection}/{id}/versions/{v} - Get specific version
GET /{collection}/{id}/diff/{v1}/{v2} - Compare versions
POST /{collection}/{id}/restore/{v} - Restore to version
Implementation: pkg/version/manager.go, pkg/api/handlers_version.go
Initialization: cmd/server/main.go:108-109
versionMgr := version . NewManager ( mongoStore )
From SPECIFICATION.md:810-1017.
Audit logger
Records all operations for compliance and debugging.
Audit log entry:
// _pm_audit collection
{
_id : ObjectId ( "..." ),
tenant_id : "acme-corp" ,
user_id : "user-alice" ,
action : "update" , // create, read, update, delete
collection : "orders" ,
doc_id : "order-123" ,
changes : [
{ field: "status" , from: "pending" , to: "shipped" }
],
timestamp : ISODate ( "2026-03-04T14:00:00Z" ),
success : true
}
Storage options:
MongoDB collection with TTL
Webhook (batch HTTP POST)
Stdout (for development)
Implementation: pkg/audit/logger.go
Initialization: cmd/server/main.go:112-113
auditLogger := audit . NewLogger ( & cfg . Server . Audit , mongoStore )
From SPECIFICATION.md:1072-1243.
Hooks manager
Executes pre/post operation hooks for validation, transformation, and notifications.
Hook types:
pre_create, post_create
pre_update, post_update
pre_delete, post_delete
Built-in actions:
set_field - Set field to value or expression
validate - Check condition or fail
validate_ref - Verify reference exists
http - Call external webhook
Implementation: pkg/hooks/executor.go
Initialization: cmd/server/main.go:116-120
var hooksMgr * hooks . Manager
if cfg . Hooks != nil {
hooksMgr = hooks . NewManager ()
}
Request flow
Typical request lifecycle for an update operation:
┌─────────────────────────────────────────────────────────────────────┐
│ 1. Client sends request │
│ PUT /orders/order-123 { "status": "shipped" } │
│ Authorization: Bearer <jwt> │
│ │ │
│ ▼ │
│ 2. JWT Authentication │
│ • Validate signature │
│ • Extract: user_id, tenant_id, roles │
│ • Build AuthContext │
│ │ │
│ ▼ │
│ 3. RBAC Check │
│ • Load policy (from cache) │
│ • Check: can user.roles do "update" on "orders"? │
│ • If denied → 403 Forbidden │
│ │ │
│ ▼ │
│ 4. Load Existing Document │
│ • Fetch current state for versioning │
│ • Check document-level permission (when clause) │
│ │ │
│ ▼ │
│ 5. Schema Validation │
│ • Type checking │
│ • Constraints (min, max, enum) │
│ • Immutable field check │
│ │ │
│ ▼ │
│ 6. Pre-Update Hooks │
│ • Validation rules │
│ • Field transformations │
│ • HTTP calls (sync) │
│ │ │
│ ▼ │
│ 7. Save Version Snapshot │
│ • Store previous state in _pm_versions │
│ • Increment _version field │
│ │ │
│ ▼ │
│ 8. Compute Stored Fields │
│ • Recalculate affected computed fields │
│ • Update updated_at timestamp │
│ │ │
│ ▼ │
│ 9. MongoDB Update │
│ • Execute update │
│ │ │
│ ▼ │
│ 10. Post-Update Hooks (async) │
│ • Webhook notifications │
│ │ │
│ ▼ │
│ 11. Audit Log │
│ • Record: user, action, collection, doc_id, changes │
│ • Ship to configured destinations │
│ │ │
│ ▼ │
│ 12. Compute Virtual Fields │
│ • Calculate non-stored computed fields │
│ │ │
│ ▼ │
│ 13. Apply Field Projection │
│ • Remove denied fields │
│ • Apply masks │
│ │ │
│ ▼ │
│ 14. Return Response │
│ { "_id": "order-123", "status": "shipped", "_version": 4 } │
└─────────────────────────────────────────────────────────────────────┘
From SPECIFICATION.md:256-333.
See handler implementation in pkg/api/handlers_crud.go.
Data storage
MongoDB collections
MongoDB Database
│
├── orders ← Your application data
├── customers ← Your application data
├── products ← Your application data
├── users ← Your application data
│
├── _pm_versions ← All version history (single collection)
│ Indexes:
│ - { tenant_id: 1, collection: 1, doc_id: 1, version: -1 }
│ - { updated_at: 1 } with TTL (optional)
│
├── _pm_audit ← Audit logs (optional)
│ Indexes:
│ - { tenant_id: 1, timestamp: -1 }
│ - { tenant_id: 1, user_id: 1, timestamp: -1 }
│ - { timestamp: 1 } with TTL
│
├── _pm_hierarchy ← Org chart closure table
│ Indexes:
│ - { tenant_id: 1, ancestor_id: 1 }
│ - { tenant_id: 1, user_id: 1 }
│
└── _pm_policies ← Compiled policies cache
Indexes:
- { tenant_id: 1 } unique
From SPECIFICATION.md:1245-1277.
Redis keys
Redis
│
├── pm:policy:{tenant_id}:compiled ← Compiled policy (TTL: 60s)
├── pm:policy:{tenant_id}:version ← Policy version for invalidation
│
├── pm:hier:{tenant_id}:{user_id}:subs ← Subordinates list (TTL: 300s)
├── pm:hier:{tenant_id}:{user_id}:direct ← Direct reports (TTL: 300s)
├── pm:hier:{tenant_id}:{user_id}:anc ← Ancestors (TTL: 300s)
│
└── pm:schema:compiled ← Schema cache (TTL: 60s)
From SPECIFICATION.md:1279-1291.
Project structure
permission-mongo/
├── cmd/
│ ├── server/main.go # Main server entry point
│ └── pmctl/main.go # CLI tool
├── pkg/
│ ├── api/
│ │ ├── server.go # fasthttp server
│ │ ├── handlers_crud.go # CRUD handlers
│ │ ├── handlers_batch.go # Batch handlers
│ │ ├── handlers_query.go # List/aggregate handlers
│ │ ├── handlers_version.go # Version history handlers
│ │ └── middleware.go # Auth, logging, recovery
│ ├── auth/
│ │ ├── jwt.go # JWT validation
│ │ └── context.go # User context extraction
│ ├── config/
│ │ ├── schema.go # Schema parsing
│ │ ├── policy.go # Policy parsing
│ │ └── loader.go # Config file loader
│ ├── schema/
│ │ ├── validator.go # Document validation
│ │ └── computed.go # Computed field evaluation
│ ├── rbac/
│ │ ├── engine.go # Permission engine
│ │ ├── evaluator.go # Condition evaluation
│ │ ├── compiler.go # Expression → MongoDB
│ │ └── fields.go # Field projection/masking
│ ├── hierarchy/
│ │ ├── resolver.go # Subordinate lookups
│ │ └── closure.go # Transitive closure
│ ├── version/
│ │ ├── manager.go # Version management
│ │ ├── diff.go # Diff calculation
│ │ └── restore.go # Restore logic
│ ├── audit/
│ │ ├── logger.go # Audit log interface
│ │ └── mongodb.go # MongoDB storage
│ ├── hooks/
│ │ ├── executor.go # Hook execution
│ │ └── http.go # HTTP call handling
│ ├── store/
│ │ └── mongo.go # MongoDB operations
│ └── cache/
│ └── redis.go # Redis client
├── config/
│ ├── schema.yml # Example schema
│ ├── policy.yml # Example policy
│ └── config.example.yaml # Server configuration
├── docker/
│ ├── Dockerfile
│ └── docker-compose.yaml
└── Makefile
From README.md:181-205 and SPECIFICATION.md:172-254.
Throughput targets
Operation Target Latency Throughput GET (cached) Less than 10ms 50K+ QPS POST (create) Less than 25ms 25K+ QPS PUT (update with versioning) Less than 30ms 20K+ QPS Batch (100 docs) Less than 100ms 5K+ QPS
Optimizations
Lock-free router (pkg/api/router.go):
Atomic operations for route registration
Zero allocations in hot path
Connection pooling:
MongoDB: 100 connections (configurable)
Redis: 500 connections (configurable)
Async audit logging:
Batched inserts to MongoDB
No latency impact on user requests
AST caching:
RBAC expressions compiled once and cached
Reduces CPU usage by 80% vs. parsing on every request
From README.md:207-214.
Scalability
Permission Mongo scales to:
50-100M documents per collection (single instance)
500M total documents across all collections
1M users in hierarchy
25K QPS sustained on standard hardware
For larger scale, use MongoDB sharding and horizontal scaling of Permission Mongo instances (stateless).
From SPECIFICATION.md:1515-1531.
Security
Authentication
JWT-based authentication with configurable algorithms:
RS256 (asymmetric, recommended for production)
HS256 (symmetric, simpler setup)
JWT claims:
{
"sub" : "user-456" , // User ID
"tenant_id" : "acme-corp" , // Tenant ID
"roles" : [ "manager" ], // User roles
"iat" : 1707220800 ,
"exp" : 1707224400
}
Authorization
Multi-level RBAC enforcement:
Collection-level - Can user access this collection?
Action-level - Can user perform this action (create/read/update/delete)?
Document-level - Does document match when clause?
Field-level - Which fields are allowed/denied/masked?
Data protection
Field masking:
fields :
mask :
email : email # j***@example.com
phone : phone # +1-***-***-1234
ssn : partial # ***-**-1234
Immutable fields:
fields :
created_at :
type : date
immutable : true # Cannot be changed after creation
Next steps
Configuration Learn how to configure schema, policies, and hooks
API Reference Complete REST API documentation
RBAC Guide Master role-based access control
Performance Tuning Optimize for high throughput