# Cedar Authorization Policies This directory contains Cedar policy files for the Provisioning platform authorization system. ## Overview Cedar is a language for defining permissions as policies, which describe who should have access to what. It is purpose-built to be ergonomic, fast, and safe. ### Key Features - **Declarative Authorization**: Define permissions as policies, not code - **Type-Safe**: Schema-based validation prevents errors - **Fast**: High-performance authorization engine - **Auditable**: All policies are version-controlled - **Hot-Reload**: Policies reload automatically on changes ## Policy Files ### schema.cedar Defines entity types, actions, and their relationships: - **Entities**: User, Team, Environment, Workspace, Server, Taskserv, Cluster, Workflow - **Actions**: create, delete, update, read, list, deploy, rollback, ssh, execute, monitor, admin - **Context**: MFA verification, IP address, time windows, approval IDs ### production.cedar Production environment policies (strictest security): - ✅ MFA required for all deployments - ✅ Approval required for deployments and deletions - ✅ Business hours restriction (08:00-18:00 UTC) - ✅ IP address restrictions (corporate network only) - ✅ SSH access limited to platform-admin and SRE teams - ❌ Force deletion forbidden without emergency approval ### development.cedar Development environment policies (relaxed): - ✅ Developers have full access - ✅ No MFA required - ✅ No approval required - ✅ Force deletion allowed - ✅ Self-service workspace creation - ✅ Cluster size limited to 5 nodes ### admin.cedar Administrative policies: - ✅ Platform admins have unrestricted access - ✅ Emergency access with special approvals - ✅ Audit team has read-only access - ✅ SRE team has elevated permissions - ✅ Security team can perform lockdowns ## Policy Examples ### Basic Permission ```cedar // Allow developers to read resources permit( principal in Team::"developers", action == Action::"read", resource ); ``` ### Conditional Permission ```cedar // Production deployments require MFA permit( principal, action == Action::"deploy", resource in Environment::"production" ) when { context.mfa_verified == true }; ``` ### Deny Policy ```cedar // Forbid force deletion in production without emergency approval forbid( principal, action == Action::"delete", resource in Environment::"production" ) when { context.force == true } unless { context has approval_id && context.approval_id.startsWith("EMERGENCY-") }; ``` ### Time-Based Restriction ```cedar // Production deployments only during business hours forbid( principal, action == Action::"deploy", resource in Environment::"production" ) unless { context.time.split("T")[1].split(":")[0].decimal() >= 8 && context.time.split("T")[1].split(":")[0].decimal() <= 18 }; ``` ### IP Restriction ```cedar // Production access requires corporate network forbid( principal, action in [Action::"create", Action::"delete", Action::"deploy"], resource in Environment::"production" ) unless { context.ip_address.startsWith("10.") || context.ip_address.startsWith("172.16.") || context.ip_address.startsWith("192.168.") }; ``` ## Context Variables Authorization requests include context information: ```rust AuthorizationContext { mfa_verified: bool, // MFA verification status ip_address: String, // Client IP address time: String, // ISO 8601 timestamp approval_id: Option, // Approval ID (optional) reason: Option, // Reason for operation (optional) force: bool, // Force flag additional: HashMap, // Additional context } ``` ## Entity Hierarchy ``` Environment (production, staging, development) ├── Workspace │ ├── Server │ ├── Taskserv │ ├── Cluster │ └── Workflow └── User/Team (principals) ``` ## Testing Policies ### Using Cedar CLI ```bash # Validate schema cedar validate --schema schema.cedar --policies production.cedar # Test specific authorization cedar authorize \ --policies production.cedar \ --schema schema.cedar \ --principal 'User::"user123"' \ --action 'Action::"deploy"' \ --resource 'Server::"server123"' \ --context '{"mfa_verified": true}' ``` ### Using Rust Tests ```bash cd provisioning/platform/orchestrator cargo test security::tests ``` ## Policy Best Practices ### 1. Deny by Default Cedar defaults to deny. Only explicitly permitted actions are allowed. ### 2. Use Schemas Always define schemas for type safety and validation. ### 3. Explicit Context Include all necessary context in authorization requests. ### 4. Separate by Environment Different policies for production, staging, and development. ### 5. Version Control All policies are in git for auditability and rollback. ### 6. Test Policies Write tests for all policy scenarios. ### 7. Document Policies Use annotations to explain policy intent: ```cedar @id("prod-deploy-mfa") @description("All production deployments must have MFA verification") permit(principal, action, resource) when { ... }; ``` ## Hot Reload The orchestrator watches this directory for changes and automatically reloads policies: ```rust // Enable hot reload (default) let config = PolicyLoaderConfigBuilder::new() .policy_dir("provisioning/config/cedar-policies") .hot_reload(true) .build(); ``` Changes to policy files are picked up within seconds without restart. ## Security Considerations ### 1. Secrets in Policies Never hardcode secrets in policies. Use references: ```cedar // ❌ Bad when { context.api_key == "secret123" } // ✅ Good when { context.api_key_hash == resource.expected_hash } ``` ### 2. IP Restrictions Use IP restrictions for sensitive operations: ```cedar when { context.ip_address.startsWith("10.") } ``` ### 3. MFA Enforcement Require MFA for critical operations: ```cedar when { context.mfa_verified == true } ``` ### 4. Approval Workflows Require approvals for production changes: ```cedar when { context has approval_id && context.approval_id != "" } ``` ### 5. Rate Limiting Cedar doesn't enforce rate limits directly. Implement in middleware: ```rust // Hint: Implement rate limiting for critical operations @id("rate-limit-critical") permit(principal, action, resource) when { true }; ``` ## Troubleshooting ### Policy Validation Errors Check policy syntax: ```bash cedar validate --schema schema.cedar --policies production.cedar ``` ### Authorization Denied Check diagnostics in authorization result: ```rust let result = engine.authorize(&request).await?; println!("Decision: {:?}", result.decision); println!("Diagnostics: {:?}", result.diagnostics); println!("Policies: {:?}", result.policies); ``` ### Hot Reload Not Working Check file permissions and orchestrator logs: ```bash tail -f provisioning/platform/orchestrator/data/orchestrator.log | grep -i policy ``` ## Additional Resources - **Cedar Documentation**: https://docs.cedarpolicy.com/ - **Cedar Playground**: https://www.cedarpolicy.com/en/playground - **Implementation**: `provisioning/platform/orchestrator/src/security/` - **Tests**: `provisioning/platform/orchestrator/src/security/tests.rs` ## Contributing When adding new policies: 1. Update schema if adding new entities or actions 2. Add policy with annotations (`@id`, `@description`) 3. Write tests for new policy 4. Update this README 5. Validate with `cedar validate` 6. Create pull request with policy changes ## Version History | Version | Date | Changes | |---------|------|---------| | 1.0.0 | 2025-10-08 | Initial Cedar policy implementation |