Entitlement System
Azotte's entitlement system provides fine-grained access control, ensuring customers receive exactly what they've purchased while enabling complex business rules.
System Architecture
┌────────────────────┐ ┌─────────────────────────┐ ┌────────────────────┐
│ Application │────▶│ Entitlement API │────▶│ Policy Engine │
│ │ │ │ │ │
│• Feature Checks │ │• Access Validation │ │• Rule Evaluation │
│• Usage Tracking │ │• Usage Monitoring │ │• Permission Logic │
│• Resource Access │ │• Quota Management │ │• Inheritance Rules │
└──────────┬─────────┘ └───────────┬─────────────┘ └──────────┬─────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Data Layer │
│ │
│ • Subscription entitlements and bundle associations │
│ • Usage quotas, limits, and consumption tracking │
│ • Entitlement grants, temporary access, and overrides │
└─────────────────────────────────────────────────────────────────────────┘
Entitlement Types
Boolean Entitlements
- Feature Flags: Simple on/off access control
- Service Tiers: Basic, Premium, Enterprise access levels
- Regional Access: Geographic content restrictions
- Time-Based Access: Temporary or scheduled access
Quantitative Entitlements
- Usage Quotas: API calls, storage, bandwidth limits
- Seat Licenses: User count limitations
- Transaction Limits: Monthly/daily transaction caps
- Resource Allocations: CPU, memory, or compute quotas
Hierarchical Entitlements
- Role-Based Access: Admin, editor, viewer permissions
- Organizational Units: Department or team-based access
- Cascading Permissions: Inherited access rights
- Override Capabilities: Escalated temporary access
Entitlement Definition Schema
{
"entitlement_id": "premium_analytics",
"name": "Premium Analytics Access",
"type": "feature",
"data_type": "boolean",
"default_value": false,
"inheritance_rules": {
"inherits_from": ["basic_analytics"],
"override_policy": "always_allow"
},
"usage_tracking": {
"enabled": true,
"reset_period": "monthly",
"soft_limit": 1000,
"hard_limit": 1200
},
"constraints": {
"geographic_restrictions": ["EU", "US"],
"time_restrictions": {
"start_date": "2024-01-01T00:00:00Z",
"end_date": "2024-12-31T23:59:59Z"
}
}
}
Access Evaluation Engine
Real-Time Access Checks
interface EntitlementChecker {
hasAccess(
customerId: string,
entitlement: string,
context?: AccessContext
): Promise<AccessResult>;
checkUsageQuota(
customerId: string,
entitlement: string,
requestedAmount: number
): Promise<QuotaResult>;
getRemainingQuota(
customerId: string,
entitlement: string
): Promise<number>;
}
Access Context
interface AccessContext {
requestId: string;
timestamp: Date;
clientInfo: {
ipAddress: string;
userAgent: string;
location?: GeoLocation;
};
resourceInfo: {
resourceType: string;
resourceId?: string;
action: string;
};
metadata?: Record<string, any>;
}
Policy Engine
Rule-Based Evaluation
interface EntitlementPolicy {
conditions: PolicyCondition[];
effect: 'ALLOW' | 'DENY';
priority: number;
temporal_constraints?: TemporalConstraint;
}
interface PolicyCondition {
field: string; // e.g., 'subscription.tier', 'customer.region'
operator: 'equals' | 'contains' | 'greater_than' | 'in_set';
value: any;
}
Policy Evaluation Flow
- Context Collection: Gather customer, subscription, and request context
- Policy Matching: Find applicable policies for the requested entitlement
- Condition Evaluation: Evaluate all conditions in matched policies
- Conflict Resolution: Apply priority-based conflict resolution
- Final Decision: Return ALLOW/DENY with reasoning
Usage Tracking and Quotas
Real-Time Usage Monitoring
class UsageTracker {
async recordUsage(
customerId: string,
entitlement: string,
amount: number,
metadata?: UsageMetadata
): Promise<UsageRecord> {
// Atomic usage increment with quota checking
const currentUsage = await this.getCurrentUsage(customerId, entitlement);
const quota = await this.getQuota(customerId, entitlement);
if (currentUsage + amount > quota.hard_limit) {
throw new QuotaExceededException();
}
return this.incrementUsage(customerId, entitlement, amount);
}
}
Quota Management
- Soft Limits: Warning thresholds with notifications
- Hard Limits: Absolute caps with access denial
- Overage Handling: Defined behavior for quota exceeded
- Reset Cycles: Hourly, daily, monthly, or custom cycles
Usage Analytics
Usage Dashboard
┌──────────────────────────────────────────────────┐
│ Entitlement Current Quota Status │
├──────────────────────────────────────────────────┤
│ API Calls 8,420 10,000 ✓ OK │
│ Storage GB 145.2 200 ✓ OK │
│ Premium Features ✓ ✓ ✓ ACTIVE │
│ Monthly Reports 28 30 ⚠ WARNING │
└──────────────────────────────────────────────────┘
Inheritance and Stacking
Bundle Inheritance
interface BundleEntitlements {
bundleId: string;
baseEntitlements: Entitlement[];
inheritanceRules: {
inheritsFrom: string[]; // Parent bundle IDs
overridePolicy: 'merge' | 'replace' | 'additive';
conflicts: ConflictResolution[];
};
}
Entitlement Stacking
- Additive Stacking: Numeric values sum across subscriptions
- Maximum Selection: Take highest value across subscriptions
- Boolean OR Logic: Any active subscription grants access
- Override Hierarchy: Premium subscriptions override basic
Integration Patterns
SDK Integration
// JavaScript/Node.js SDK
import { AzotteClient } from '@azotte/sdk';
const azotte = new AzotteClient({ apiKey: 'your-api-key' });
// Check feature access
const hasAccess = await azotte.entitlements.hasAccess(
customerId,
'premium_analytics'
);
// Track usage
if (hasAccess) {
await azotte.entitlements.recordUsage(
customerId,
'api_calls',
1
);
// Proceed with premium analytics
}
Middleware Integration
// Express.js middleware
function requireEntitlement(entitlement: string) {
return async (req: Request, res: Response, next: NextFunction) => {
const customerId = req.user.customerId;
const hasAccess = await azotte.entitlements.hasAccess(
customerId,
entitlement
);
if (!hasAccess.allowed) {
return res.status(403).json({
error: 'Insufficient permissions',
required_entitlement: entitlement,
upgrade_url: '/upgrade'
});
}
next();
};
}
// Usage
app.get('/api/premium-data',
requireEntitlement('premium_analytics'),
premiumAnalyticsController
);
Caching and Performance
Multi-Level Caching
- Application Cache: In-memory caching with TTL
- Redis Cache: Shared cache for entitlement decisions
- CDN Edge Cache: Geographic distribution for low latency
- Database Read Replicas: Optimized for entitlement queries
Cache Invalidation
interface CacheInvalidation {
onSubscriptionChange: (customerId: string) => void;
onBundleUpdate: (bundleId: string) => void;
onEntitlementGrant: (customerId: string, entitlement: string) => void;
onUsageReset: (customerId: string) => void;
}
Audit and Compliance
Access Logging
{
"timestamp": "2024-03-14T10:30:00Z",
"request_id": "req_12345",
"customer_id": "cus_67890",
"entitlement": "premium_analytics",
"action": "access_check",
"result": "ALLOWED",
"reason": "Active premium subscription",
"context": {
"ip_address": "192.168.1.100",
"user_agent": "MyApp/1.0",
"resource": "analytics/dashboard"
}
}
Compliance Reports
- Data access audit trails
- Entitlement usage reports
- Permission change history
- Regulatory compliance documentation
Event-Driven Updates
Real-Time Notifications
// Webhook events for entitlement changes
interface EntitlementEvent {
type: 'entitlement.granted' | 'entitlement.revoked' | 'quota.exceeded';
customerId: string;
entitlement: string;
oldValue?: any;
newValue?: any;
effectiveDate: Date;
}
Event Handlers
- Subscription lifecycle events
- Bundle modification events
- Campaign activation/deactivation
- Administrative overrides
Next Steps
- Learn about Developer Integration
- Understand API Reference
- Explore Portal Management