Policy Engine & Rule Evaluation
The Olympus Cloud Policy Engine provides dynamic rule evaluation for feature gating, access control, and business logic enforcement.
Overview
The Policy Engine consists of three integrated components:
| Component | Purpose | Use Case |
|---|---|---|
| Gating Service | Feature flag evaluation | Gradual rollouts, A/B testing |
| Rule Evaluator | Dynamic condition evaluation | Access control, targeting |
| Scheduling Policies | Labor law compliance | Workforce scheduling |
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ POLICY ENGINE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Policy │───▶│ Rule │───▶│ Result │ │
│ │ Lookup │ │ Evaluator │ │ Cache │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ▲ │ │ │
│ │ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Spanner │ │ Override │ │ Redis │ │
│ │ Database │ │ Matching │ │ Cache │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Policy Model
Policy Structure
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"key": "new_checkout_flow",
"name": "New Checkout Flow",
"description": "Redesigned checkout experience",
"policy_type": "feature_flag",
"enabled": true,
"rules": {
"allOf": [
{
"condition": {
"field": "tenant.tier",
"operator": "in",
"value": ["enterprise", "professional"]
}
},
{
"condition": {
"field": "user.role",
"operator": "not_equals",
"value": "guest"
}
}
]
},
"default_value": { "variant": "control" },
"metadata": {
"category": "checkout",
"owner": "product-team"
}
}
Policy Types
| Type | Description | Example |
|---|---|---|
feature_flag | Boolean on/off toggle | Enable new UI |
gradual_rollout | Percentage-based activation | 25% of users |
experiment | A/B testing with variants | Checkout A vs B |
access_control | Permission gating | Admin-only features |
business_rule | Dynamic configuration | Pricing rules |
Rule Evaluation
Evaluation Context
Every policy evaluation requires a context object:
{
"user_id": "user-abc123",
"user_role": "manager",
"user_roles": ["manager", "staff"],
"user_groups": ["premium-beta"],
"tenant_id": "tenant-xyz789",
"tenant_tier": "enterprise",
"app_version": "2.5.0",
"environment": "production",
"attributes": {
"location_id": "loc-001",
"device_type": "mobile",
"custom_field": "value"
}
}
Rule Operators
| Operator | Description | Example |
|---|---|---|
equals | Exact match | role == "admin" |
not_equals | Not equal | status != "disabled" |
greater_than | Numeric greater | count > 10 |
less_than | Numeric less | price < 100 |
greater_than_or_equal | >= comparison | version >= 2.0 |
less_than_or_equal | <= comparison | age <= 65 |
contains | String contains | email contains "@company" |
not_contains | String doesn't contain | name not contains "test" |
in | Value in array | tier in ["pro", "enterprise"] |
not_in | Value not in array | role not in ["guest"] |
matches_regex | Regex pattern match | email matches ".*@corp.com" |
Logical Combinators
Combine conditions with logical operators:
{
"allOf": [
{ "condition": { "field": "user.role", "operator": "equals", "value": "admin" } },
{ "condition": { "field": "tenant.tier", "operator": "in", "value": ["enterprise"] } }
]
}
| Combinator | Description | Behavior |
|---|---|---|
allOf | Logical AND | All conditions must pass |
anyOf | Logical OR | At least one must pass |
not | Logical NOT | Negates the condition |
Nested Rules
Rules can be nested for complex logic:
{
"anyOf": [
{
"allOf": [
{ "condition": { "field": "user.role", "operator": "equals", "value": "admin" } }
]
},
{
"allOf": [
{ "condition": { "field": "tenant.tier", "operator": "equals", "value": "enterprise" } },
{ "condition": { "field": "user.groups", "operator": "contains", "value": "beta-testers" } }
]
}
]
}
Policy Overrides
Target specific segments with overrides:
Override Structure
{
"id": "override-001",
"policy_id": "policy-xyz",
"tenant_id": "tenant-specific",
"tenant_group_id": null,
"role_id": "manager",
"user_id": null,
"app_version": ">=2.5.0",
"environment": "production",
"enabled": true,
"value": { "variant": "experimental" },
"rules": null,
"rollout_percentage": 100,
"priority": 10
}
Override Matching Priority
Overrides are matched in priority order:
- User-specific (highest) -
user_idmatches - Role-specific -
role_idmatches - Tenant-specific -
tenant_idmatches - Group-specific -
tenant_group_idmatches - Version-specific -
app_versionmatches - Environment-specific -
environmentmatches - Default policy (lowest) - No override matches
API Reference
Evaluate Policy
POST /api/v1/platform/evaluate-policy
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"policy_key": "new_checkout_flow",
"context": {
"user_id": "user-123",
"user_role": "manager",
"tenant_id": "tenant-456",
"tenant_tier": "professional",
"app_version": "2.5.0",
"environment": "production"
}
}
Response:
{
"policy_key": "new_checkout_flow",
"enabled": true,
"value": { "variant": "variant_a" },
"matched_override": "override-001",
"evaluation_time_ms": 2
}
Batch Evaluate Policies
POST /api/v1/platform/batch-evaluate-policies
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"policy_keys": ["feature_a", "feature_b", "feature_c"],
"context": {
"user_id": "user-123",
"tenant_id": "tenant-456"
}
}
Response:
{
"results": {
"feature_a": { "enabled": true, "value": null },
"feature_b": { "enabled": false, "value": null },
"feature_c": { "enabled": true, "value": { "limit": 100 } }
},
"total_time_ms": 15
}
Create Policy
POST /api/v1/platform/policies
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"key": "new_feature",
"name": "New Feature",
"description": "A new feature being rolled out",
"policy_type": "feature_flag",
"enabled": true,
"rules": {
"condition": {
"field": "tenant.tier",
"operator": "equals",
"value": "enterprise"
}
},
"default_value": null
}
List Policies
GET /api/v1/platform/policies?status=active&category=checkout
Authorization: Bearer {access_token}
Create Override
POST /api/v1/platform/policies/{policy_key}/overrides
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"tenant_id": "tenant-beta",
"enabled": true,
"value": { "variant": "experimental" },
"rollout_percentage": 50,
"priority": 10
}
Canary Releases
Create Canary Release
POST /api/v1/platform/policies/{policy_key}/canary
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"target_percentage": 10,
"increment_percentage": 10,
"increment_interval_hours": 24,
"success_criteria": {
"error_rate_threshold": 0.01,
"latency_p99_threshold_ms": 500
}
}
Promote Canary
POST /api/v1/platform/policies/{policy_key}/canary/promote
Authorization: Bearer {access_token}
Rollback Canary
POST /api/v1/platform/policies/{policy_key}/canary/rollback
Authorization: Bearer {access_token}
Scheduling Policies
The Policy Engine includes specialized scheduling policies for labor law compliance.
Rule Categories
| Category | Description | Example |
|---|---|---|
labor_law | State/federal labor laws | Overtime rules |
minor_restrictions | Minor worker protections | Curfew hours |
overtime_rules | Overtime calculations | CA overtime |
break_requirements | Mandatory breaks | Meal periods |
company_policy | Custom business rules | Max shifts/week |
operational | Operational constraints | Min staffing |
Constraint Types
// Maximum consecutive days worked
MaxConsecutiveDays { max_days: 6 }
// Minimum rest between shifts (clopening prevention)
MinRestBetweenShifts { min_hours: 8 }
// Weekly hour limits
MaxHoursPerWeek { max_hours: 40 }
// Daily hour limits
MaxHoursPerDay { max_hours: 10 }
// Minor curfew restrictions
MinorCurfew { start_hour: 22, end_hour: 6 }
// California overtime rules
CaliforniaOvertime { daily_threshold: 8, weekly_threshold: 40 }
// Required break periods
RequiredBreak { hours_worked: 6, break_duration_minutes: 30 }
// Predictive scheduling notice
PredictiveScheduling { notice_days: 14 }
State-Specific Configurations
| State | Meal Break | Predictive Scheduling | Rest Period |
|---|---|---|---|
| California | 30 min after 5 hours | 14 days notice | 10 hours |
| New York | 30 min after 6 hours | 72 hours notice | 11 hours |
| Oregon | 30 min after 6 hours | 14 days notice | 10 hours |
| Federal | No requirement | No requirement | No requirement |
Performance
SLA Targets
| Operation | Target | Actual |
|---|---|---|
| Cache hit | < 10ms | < 1ms |
| Cache miss | < 100ms | ~47ms |
| Batch (10 policies) | < 200ms | ~150ms |
| Rule evaluation | < 10ms | ~5ms P99 |
Caching Strategy
- Redis cache with 300-second TTL
- Cache hit ratio: ~85% after warmup
- Pub/Sub invalidation on policy updates
- Deterministic cache keys based on policy + context hash
Security
The matches_regex operator is protected against ReDoS attacks with a 200-character pattern limit. Prefer simpler operators like contains or in whenever possible, as regex evaluation is significantly slower and more error-prone than exact match operators.
- ReDoS protection: Pattern length limits (200 chars max)
- Regex size limits: 1MB compiled, 1MB DFA
- Execution timing: Monitored for anomalies
- Access control: Requires
platform_adminorpolicy_adminrole
Best Practices
Policy Design
- Use descriptive keys:
checkout_redesign_v2notfeature_1 - Add metadata: Include owner, category, and description
- Start disabled: Enable after configuration is complete
- Use overrides: Target specific segments before broad rollout
Rule Writing
- Keep rules simple: Prefer multiple policies over complex rules
- Use dot notation:
user.role,tenant.tier,attributes.custom - Test thoroughly: Verify rule logic with different contexts
- Avoid regex when possible: Use
containsorininstead
Rollout Strategy
- Start small: Begin with 5-10% rollout
- Monitor metrics: Track error rates and latency
- Use canary releases: Automated gradual rollout
- Have a rollback plan: Quick disable if issues arise
Troubleshooting
Policy Not Evaluating
- Check policy is
enabled: true - Verify context fields match rule conditions
- Check for overrides that might disable the policy
- Review Redis cache (may have stale data)
Unexpected Results
- Enable evaluation logging
- Check override priority order
- Verify rule operator usage
- Test with simplified rules
Performance Issues
- Check Redis connectivity
- Review rule complexity
- Consider batch evaluation for multiple policies
- Monitor database query times
Related Documentation
- Feature Gating API - API reference
- RBAC & Permissions - Role-based access
- Multi-Tenancy - Tenant isolation