2025-12-11 21:50:42 +00:00
|
|
|
# Cedar Policies Production Guide
|
|
|
|
|
|
|
|
|
|
**Version**: 1.0.0
|
|
|
|
|
**Date**: 2025-10-08
|
|
|
|
|
**Audience**: Platform Administrators, Security Teams
|
|
|
|
|
**Prerequisites**: Understanding of Cedar policy language, Provisioning platform architecture
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Table of Contents
|
|
|
|
|
|
|
|
|
|
1. [Introduction](#introduction)
|
|
|
|
|
2. [Cedar Policy Basics](#cedar-policy-basics)
|
|
|
|
|
3. [Production Policy Strategy](#production-policy-strategy)
|
|
|
|
|
4. [Policy Templates](#policy-templates)
|
|
|
|
|
5. [Policy Development Workflow](#policy-development-workflow)
|
|
|
|
|
6. [Testing Policies](#testing-policies)
|
|
|
|
|
7. [Deployment](#deployment)
|
|
|
|
|
8. [Monitoring & Auditing](#monitoring--auditing)
|
|
|
|
|
9. [Troubleshooting](#troubleshooting)
|
|
|
|
|
10. [Best Practices](#best-practices)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Introduction
|
|
|
|
|
|
2026-01-12 04:42:18 +00:00
|
|
|
Cedar policies control **who can do what** in the Provisioning platform. This guide helps you create, test, and deploy production-ready Cedar policies
|
|
|
|
|
that balance security with operational efficiency.
|
2025-12-11 21:50:42 +00:00
|
|
|
|
2026-01-08 09:55:37 +00:00
|
|
|
### Why Cedar
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
- **Fine-grained**: Control access at resource + action level
|
|
|
|
|
- **Context-aware**: Decisions based on MFA, IP, time, approvals
|
|
|
|
|
- **Auditable**: Every decision is logged with policy ID
|
|
|
|
|
- **Hot-reload**: Update policies without restarting services
|
|
|
|
|
- **Type-safe**: Schema validation prevents errors
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Cedar Policy Basics
|
|
|
|
|
|
|
|
|
|
### Core Concepts
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
permit (
|
|
|
|
|
principal, # Who (user, team, role)
|
|
|
|
|
action, # What (create, delete, deploy)
|
|
|
|
|
resource # Where (server, cluster, environment)
|
|
|
|
|
) when {
|
|
|
|
|
condition # Context (MFA, IP, time)
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Entities
|
|
|
|
|
|
|
|
|
|
| Type | Examples | Description |
|
2026-01-12 04:42:18 +00:00
|
|
|
| ------ | ---------- | ------------- |
|
2025-12-11 21:50:42 +00:00
|
|
|
| **User** | `User::"alice"` | Individual users |
|
|
|
|
|
| **Team** | `Team::"platform-admin"` | User groups |
|
|
|
|
|
| **Role** | `Role::"Admin"` | Permission levels |
|
|
|
|
|
| **Resource** | `Server::"web-01"` | Infrastructure resources |
|
|
|
|
|
| **Environment** | `Environment::"production"` | Deployment targets |
|
|
|
|
|
|
|
|
|
|
### Actions
|
|
|
|
|
|
|
|
|
|
| Category | Actions |
|
2026-01-12 04:42:18 +00:00
|
|
|
| ---------- | --------- |
|
2025-12-11 21:50:42 +00:00
|
|
|
| **Read** | `read`, `list` |
|
|
|
|
|
| **Write** | `create`, `update`, `delete` |
|
|
|
|
|
| **Deploy** | `deploy`, `rollback` |
|
|
|
|
|
| **Admin** | `ssh`, `execute`, `admin` |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Production Policy Strategy
|
|
|
|
|
|
|
|
|
|
### Security Levels
|
|
|
|
|
|
|
|
|
|
#### Level 1: Development (Permissive)
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// Developers have full access to dev environment
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"developers",
|
|
|
|
|
action,
|
|
|
|
|
resource in Environment::"development"
|
|
|
|
|
);
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
#### Level 2: Staging (MFA Required)
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// All operations require MFA
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"developers",
|
|
|
|
|
action,
|
|
|
|
|
resource in Environment::"staging"
|
|
|
|
|
) when {
|
|
|
|
|
context.mfa_verified == true
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
#### Level 3: Production (MFA + Approval)
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// Deployments require MFA + approval
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"platform-admin",
|
|
|
|
|
action in [Action::"deploy", Action::"delete"],
|
|
|
|
|
resource in Environment::"production"
|
|
|
|
|
) when {
|
|
|
|
|
context.mfa_verified == true &&
|
|
|
|
|
context has approval_id &&
|
|
|
|
|
context.approval_id.startsWith("APPROVAL-")
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
#### Level 4: Critical (Break-Glass Only)
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// Only emergency access
|
|
|
|
|
permit (
|
|
|
|
|
principal,
|
|
|
|
|
action,
|
|
|
|
|
resource in Resource::"production-database"
|
|
|
|
|
) when {
|
|
|
|
|
context.emergency_access == true &&
|
|
|
|
|
context.session_approved == true
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Policy Templates
|
|
|
|
|
|
|
|
|
|
### 1. Role-Based Access Control (RBAC)
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// Admin: Full access
|
|
|
|
|
permit (
|
|
|
|
|
principal in Role::"Admin",
|
|
|
|
|
action,
|
|
|
|
|
resource
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Operator: Server management + read clusters
|
|
|
|
|
permit (
|
|
|
|
|
principal in Role::"Operator",
|
|
|
|
|
action in [
|
|
|
|
|
Action::"create",
|
|
|
|
|
Action::"update",
|
|
|
|
|
Action::"delete"
|
|
|
|
|
],
|
|
|
|
|
resource is Server
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
permit (
|
|
|
|
|
principal in Role::"Operator",
|
|
|
|
|
action in [Action::"read", Action::"list"],
|
|
|
|
|
resource is Cluster
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Viewer: Read-only everywhere
|
|
|
|
|
permit (
|
|
|
|
|
principal in Role::"Viewer",
|
|
|
|
|
action in [Action::"read", Action::"list"],
|
|
|
|
|
resource
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Auditor: Read audit logs only
|
|
|
|
|
permit (
|
|
|
|
|
principal in Role::"Auditor",
|
|
|
|
|
action in [Action::"read", Action::"list"],
|
|
|
|
|
resource is AuditLog
|
|
|
|
|
);
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 2. Team-Based Policies
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// Platform team: Infrastructure management
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"platform",
|
|
|
|
|
action in [
|
|
|
|
|
Action::"create",
|
|
|
|
|
Action::"update",
|
|
|
|
|
Action::"delete",
|
|
|
|
|
Action::"deploy"
|
|
|
|
|
],
|
|
|
|
|
resource in [Server, Cluster, Taskserv]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Security team: Access control + audit
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"security",
|
|
|
|
|
action,
|
|
|
|
|
resource in [User, Role, AuditLog, BreakGlass]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// DevOps team: Application deployments
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"devops",
|
|
|
|
|
action == Action::"deploy",
|
|
|
|
|
resource in Environment::"production"
|
|
|
|
|
) when {
|
|
|
|
|
context.mfa_verified == true &&
|
|
|
|
|
context.has_approval == true
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 3. Time-Based Restrictions
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// Deployments only during business hours
|
|
|
|
|
permit (
|
|
|
|
|
principal,
|
|
|
|
|
action == Action::"deploy",
|
|
|
|
|
resource in Environment::"production"
|
|
|
|
|
) when {
|
|
|
|
|
context.time.hour >= 9 &&
|
|
|
|
|
context.time.hour <= 17 &&
|
|
|
|
|
context.time.weekday in ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Maintenance window
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"platform",
|
|
|
|
|
action,
|
|
|
|
|
resource
|
|
|
|
|
) when {
|
|
|
|
|
context.maintenance_window == true
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 4. IP-Based Restrictions
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// Production access only from office network
|
|
|
|
|
permit (
|
|
|
|
|
principal,
|
|
|
|
|
action,
|
|
|
|
|
resource in Environment::"production"
|
|
|
|
|
) when {
|
|
|
|
|
context.ip_address.isInRange("10.0.0.0/8") ||
|
|
|
|
|
context.ip_address.isInRange("192.168.1.0/24")
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// VPN access for remote work
|
|
|
|
|
permit (
|
|
|
|
|
principal,
|
|
|
|
|
action,
|
|
|
|
|
resource in Environment::"production"
|
|
|
|
|
) when {
|
|
|
|
|
context.vpn_connected == true &&
|
|
|
|
|
context.mfa_verified == true
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 5. Resource-Specific Policies
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// Database servers: Extra protection
|
|
|
|
|
forbid (
|
|
|
|
|
principal,
|
|
|
|
|
action == Action::"delete",
|
|
|
|
|
resource in Resource::"database-*"
|
|
|
|
|
) unless {
|
|
|
|
|
context.emergency_access == true
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Critical clusters: Require multiple approvals
|
|
|
|
|
permit (
|
|
|
|
|
principal,
|
|
|
|
|
action in [Action::"update", Action::"delete"],
|
|
|
|
|
resource in Resource::"k8s-production-*"
|
|
|
|
|
) when {
|
|
|
|
|
context.approval_count >= 2 &&
|
|
|
|
|
context.mfa_verified == true
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 6. Self-Service Policies
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// Users can manage their own MFA devices
|
|
|
|
|
permit (
|
|
|
|
|
principal,
|
|
|
|
|
action in [Action::"create", Action::"delete"],
|
|
|
|
|
resource is MfaDevice
|
|
|
|
|
) when {
|
|
|
|
|
resource.owner == principal
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Users can view their own audit logs
|
|
|
|
|
permit (
|
|
|
|
|
principal,
|
|
|
|
|
action == Action::"read",
|
|
|
|
|
resource is AuditLog
|
|
|
|
|
) when {
|
|
|
|
|
resource.user_id == principal.id
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Policy Development Workflow
|
|
|
|
|
|
|
|
|
|
### Step 1: Define Requirements
|
|
|
|
|
|
|
|
|
|
**Document**:
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2025-12-11 21:50:42 +00:00
|
|
|
- Who needs access? (roles, teams, individuals)
|
|
|
|
|
- To what resources? (servers, clusters, environments)
|
|
|
|
|
- What actions? (read, write, deploy, delete)
|
|
|
|
|
- Under what conditions? (MFA, IP, time, approvals)
|
|
|
|
|
|
|
|
|
|
**Example Requirements Document**:
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Requirement: Production Deployment
|
|
|
|
|
|
|
|
|
|
**Who**: DevOps team members
|
|
|
|
|
**What**: Deploy applications to production
|
|
|
|
|
**When**: Business hours (9am-5pm Mon-Fri)
|
|
|
|
|
**Conditions**:
|
|
|
|
|
- MFA verified
|
|
|
|
|
- Change request approved
|
|
|
|
|
- From office network or VPN
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Step 2: Write Policy
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
@id("prod-deploy-devops")
|
|
|
|
|
@description("DevOps can deploy to production during business hours with approval")
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"devops",
|
|
|
|
|
action == Action::"deploy",
|
|
|
|
|
resource in Environment::"production"
|
|
|
|
|
) when {
|
|
|
|
|
context.mfa_verified == true &&
|
|
|
|
|
context has approval_id &&
|
|
|
|
|
context.time.hour >= 9 &&
|
|
|
|
|
context.time.hour <= 17 &&
|
|
|
|
|
context.time.weekday in ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] &&
|
|
|
|
|
(context.ip_address.isInRange("10.0.0.0/8") || context.vpn_connected == true)
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Step 3: Validate Syntax
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Use Cedar CLI to validate
|
|
|
|
|
cedar validate \
|
|
|
|
|
--policies provisioning/config/cedar-policies/production.cedar \
|
|
|
|
|
--schema provisioning/config/cedar-policies/schema.cedar
|
|
|
|
|
|
|
|
|
|
# Expected output: ✓ Policy is valid
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Step 4: Test in Development
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Deploy to development environment first
|
|
|
|
|
cp production.cedar provisioning/config/cedar-policies/development.cedar
|
|
|
|
|
|
|
|
|
|
# Restart orchestrator to load new policies
|
|
|
|
|
systemctl restart provisioning-orchestrator
|
|
|
|
|
|
|
|
|
|
# Test with real requests
|
|
|
|
|
provisioning server create test-server --check
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Step 5: Review & Approve
|
|
|
|
|
|
|
|
|
|
**Review Checklist**:
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2025-12-11 21:50:42 +00:00
|
|
|
- [ ] Policy syntax valid
|
|
|
|
|
- [ ] Policy ID unique
|
|
|
|
|
- [ ] Description clear
|
|
|
|
|
- [ ] Conditions appropriate for security level
|
|
|
|
|
- [ ] Tested in development
|
|
|
|
|
- [ ] Reviewed by security team
|
|
|
|
|
- [ ] Documented in change log
|
|
|
|
|
|
|
|
|
|
### Step 6: Deploy to Production
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Backup current policies
|
|
|
|
|
cp provisioning/config/cedar-policies/production.cedar \
|
|
|
|
|
provisioning/config/cedar-policies/production.cedar.backup.$(date +%Y%m%d)
|
|
|
|
|
|
|
|
|
|
# Deploy new policy
|
|
|
|
|
cp new-production.cedar provisioning/config/cedar-policies/production.cedar
|
|
|
|
|
|
|
|
|
|
# Hot reload (no restart needed)
|
|
|
|
|
provisioning cedar reload
|
|
|
|
|
|
|
|
|
|
# Verify loaded
|
|
|
|
|
provisioning cedar list
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Testing Policies
|
|
|
|
|
|
|
|
|
|
### Unit Testing
|
|
|
|
|
|
|
|
|
|
Create test cases for each policy:
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# tests/cedar/prod-deploy-devops.yaml
|
|
|
|
|
policy_id: prod-deploy-devops
|
|
|
|
|
|
|
|
|
|
test_cases:
|
|
|
|
|
- name: "DevOps can deploy with approval and MFA"
|
|
|
|
|
principal: { type: "Team", id: "devops" }
|
|
|
|
|
action: "deploy"
|
|
|
|
|
resource: { type: "Environment", id: "production" }
|
|
|
|
|
context:
|
|
|
|
|
mfa_verified: true
|
|
|
|
|
approval_id: "APPROVAL-123"
|
|
|
|
|
time: { hour: 10, weekday: "Monday" }
|
|
|
|
|
ip_address: "10.0.1.5"
|
|
|
|
|
expected: Allow
|
|
|
|
|
|
|
|
|
|
- name: "DevOps cannot deploy without MFA"
|
|
|
|
|
principal: { type: "Team", id: "devops" }
|
|
|
|
|
action: "deploy"
|
|
|
|
|
resource: { type: "Environment", id: "production" }
|
|
|
|
|
context:
|
|
|
|
|
mfa_verified: false
|
|
|
|
|
approval_id: "APPROVAL-123"
|
|
|
|
|
time: { hour: 10, weekday: "Monday" }
|
|
|
|
|
expected: Deny
|
|
|
|
|
|
|
|
|
|
- name: "DevOps cannot deploy outside business hours"
|
|
|
|
|
principal: { type: "Team", id: "devops" }
|
|
|
|
|
action: "deploy"
|
|
|
|
|
resource: { type: "Environment", id: "production" }
|
|
|
|
|
context:
|
|
|
|
|
mfa_verified: true
|
|
|
|
|
approval_id: "APPROVAL-123"
|
|
|
|
|
time: { hour: 22, weekday: "Monday" }
|
|
|
|
|
expected: Deny
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
Run tests:
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
provisioning cedar test tests/cedar/
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Integration Testing
|
|
|
|
|
|
|
|
|
|
Test with real API calls:
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Setup test user
|
|
|
|
|
export TEST_USER="alice"
|
|
|
|
|
export TEST_TOKEN=$(provisioning login --user $TEST_USER --output token)
|
|
|
|
|
|
|
|
|
|
# Test allowed action
|
|
|
|
|
curl -H "Authorization: Bearer $TEST_TOKEN" \
|
|
|
|
|
http://localhost:9090/api/v1/servers \
|
|
|
|
|
-X POST -d '{"name": "test-server"}'
|
|
|
|
|
|
|
|
|
|
# Expected: 200 OK
|
|
|
|
|
|
|
|
|
|
# Test denied action (without MFA)
|
|
|
|
|
curl -H "Authorization: Bearer $TEST_TOKEN" \
|
|
|
|
|
http://localhost:9090/api/v1/servers/prod-server-01 \
|
|
|
|
|
-X DELETE
|
|
|
|
|
|
|
|
|
|
# Expected: 403 Forbidden (MFA required)
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Load Testing
|
|
|
|
|
|
|
|
|
|
Verify policy evaluation performance:
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Generate load
|
|
|
|
|
provisioning cedar bench \
|
|
|
|
|
--policies production.cedar \
|
|
|
|
|
--requests 10000 \
|
|
|
|
|
--concurrency 100
|
|
|
|
|
|
2026-01-08 09:55:37 +00:00
|
|
|
# Expected: <10 ms per evaluation
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Deployment
|
|
|
|
|
|
|
|
|
|
### Development → Staging → Production
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
# deploy-policies.sh
|
|
|
|
|
|
|
|
|
|
ENVIRONMENT=$1 # dev, staging, prod
|
|
|
|
|
|
|
|
|
|
# Validate policies
|
|
|
|
|
cedar validate \
|
|
|
|
|
--policies provisioning/config/cedar-policies/$ENVIRONMENT.cedar \
|
|
|
|
|
--schema provisioning/config/cedar-policies/schema.cedar
|
|
|
|
|
|
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
|
echo "❌ Policy validation failed"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Backup current policies
|
|
|
|
|
BACKUP_DIR="provisioning/config/cedar-policies/backups/$ENVIRONMENT"
|
|
|
|
|
mkdir -p $BACKUP_DIR
|
|
|
|
|
cp provisioning/config/cedar-policies/$ENVIRONMENT.cedar \
|
|
|
|
|
$BACKUP_DIR/$ENVIRONMENT.cedar.$(date +%Y%m%d-%H%M%S)
|
|
|
|
|
|
|
|
|
|
# Deploy new policies
|
|
|
|
|
scp provisioning/config/cedar-policies/$ENVIRONMENT.cedar \
|
|
|
|
|
$ENVIRONMENT-orchestrator:/etc/provisioning/cedar-policies/production.cedar
|
|
|
|
|
|
|
|
|
|
# Hot reload on remote
|
|
|
|
|
ssh $ENVIRONMENT-orchestrator "provisioning cedar reload"
|
|
|
|
|
|
|
|
|
|
echo "✅ Policies deployed to $ENVIRONMENT"
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Rollback Procedure
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# List backups
|
|
|
|
|
ls -ltr provisioning/config/cedar-policies/backups/production/
|
|
|
|
|
|
|
|
|
|
# Restore previous version
|
|
|
|
|
cp provisioning/config/cedar-policies/backups/production/production.cedar.20251008-143000 \
|
|
|
|
|
provisioning/config/cedar-policies/production.cedar
|
|
|
|
|
|
|
|
|
|
# Reload
|
|
|
|
|
provisioning cedar reload
|
|
|
|
|
|
|
|
|
|
# Verify
|
|
|
|
|
provisioning cedar list
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Monitoring & Auditing
|
|
|
|
|
|
|
|
|
|
### Monitor Authorization Decisions
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Query denied requests (last 24 hours)
|
|
|
|
|
provisioning audit query \
|
|
|
|
|
--action authorization_denied \
|
|
|
|
|
--from "24h" \
|
|
|
|
|
--out table
|
|
|
|
|
|
|
|
|
|
# Expected output:
|
|
|
|
|
# ┌─────────┬────────┬──────────┬────────┬────────────────┐
|
|
|
|
|
# │ Time │ User │ Action │ Resour │ Reason │
|
|
|
|
|
# ├─────────┼────────┼──────────┼────────┼────────────────┤
|
|
|
|
|
# │ 10:15am │ bob │ deploy │ prod │ MFA not verif │
|
|
|
|
|
# │ 11:30am │ alice │ delete │ db-01 │ No approval │
|
|
|
|
|
# └─────────┴────────┴──────────┴────────┴────────────────┘
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Alert on Suspicious Activity
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# alerts/cedar-policies.yaml
|
|
|
|
|
alerts:
|
|
|
|
|
- name: "High Denial Rate"
|
|
|
|
|
query: "authorization_denied"
|
|
|
|
|
threshold: 10
|
|
|
|
|
window: "5m"
|
|
|
|
|
action: "notify:security-team"
|
|
|
|
|
|
|
|
|
|
- name: "Policy Bypass Attempt"
|
|
|
|
|
query: "action:deploy AND result:denied"
|
|
|
|
|
user: "critical-users"
|
|
|
|
|
action: "page:oncall"
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Policy Usage Statistics
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Which policies are most used?
|
|
|
|
|
provisioning cedar stats --top 10
|
|
|
|
|
|
|
|
|
|
# Example output:
|
|
|
|
|
# Policy ID | Uses | Allows | Denies
|
2026-01-12 04:42:18 +00:00
|
|
|
# ---------------------- | ------- | -------- | -------
|
2025-12-11 21:50:42 +00:00
|
|
|
# prod-deploy-devops | 1,234 | 1,100 | 134
|
|
|
|
|
# admin-full-access | 892 | 892 | 0
|
|
|
|
|
# viewer-read-only | 5,421 | 5,421 | 0
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Troubleshooting
|
|
|
|
|
|
|
|
|
|
### Policy Not Applying
|
|
|
|
|
|
|
|
|
|
**Symptom**: Policy changes not taking effect
|
|
|
|
|
|
|
|
|
|
**Solutions**:
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2025-12-11 21:50:42 +00:00
|
|
|
1. Verify hot reload:
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2025-12-11 21:50:42 +00:00
|
|
|
```bash
|
|
|
|
|
provisioning cedar reload
|
|
|
|
|
provisioning cedar list # Should show updated timestamp
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-08 09:55:37 +00:00
|
|
|
1. Check orchestrator logs:
|
|
|
|
|
|
2025-12-11 21:50:42 +00:00
|
|
|
```bash
|
|
|
|
|
journalctl -u provisioning-orchestrator -f | grep cedar
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-08 09:55:37 +00:00
|
|
|
2. Restart orchestrator:
|
|
|
|
|
|
2025-12-11 21:50:42 +00:00
|
|
|
```bash
|
|
|
|
|
systemctl restart provisioning-orchestrator
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Unexpected Denials
|
|
|
|
|
|
|
|
|
|
**Symptom**: User denied access when policy should allow
|
|
|
|
|
|
|
|
|
|
**Debug**:
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Enable debug mode
|
|
|
|
|
export PROVISIONING_DEBUG=1
|
|
|
|
|
|
|
|
|
|
# View authorization decision
|
|
|
|
|
provisioning audit query \
|
|
|
|
|
--user alice \
|
|
|
|
|
--action deploy \
|
|
|
|
|
--from "1h" \
|
|
|
|
|
--out json | jq '.authorization'
|
|
|
|
|
|
|
|
|
|
# Shows which policy evaluated, context used, reason for denial
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Policy Conflicts
|
|
|
|
|
|
|
|
|
|
**Symptom**: Multiple policies match, unclear which applies
|
|
|
|
|
|
|
|
|
|
**Resolution**:
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2025-12-11 21:50:42 +00:00
|
|
|
- Cedar uses **deny-override**: If any `forbid` matches, request denied
|
|
|
|
|
- Use `@priority` annotations (higher number = higher priority)
|
|
|
|
|
- Make policies more specific to avoid conflicts
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
@priority(100)
|
|
|
|
|
permit (
|
|
|
|
|
principal in Role::"Admin",
|
|
|
|
|
action,
|
|
|
|
|
resource
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
@priority(50)
|
|
|
|
|
forbid (
|
|
|
|
|
principal,
|
|
|
|
|
action == Action::"delete",
|
|
|
|
|
resource is Database
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Admin can do anything EXCEPT delete databases
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Best Practices
|
|
|
|
|
|
|
|
|
|
### 1. Start Restrictive, Loosen Gradually
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// ❌ BAD: Too permissive initially
|
|
|
|
|
permit (principal, action, resource);
|
|
|
|
|
|
|
|
|
|
// ✅ GOOD: Explicit allow, expand as needed
|
|
|
|
|
permit (
|
|
|
|
|
principal in Role::"Admin",
|
|
|
|
|
action in [Action::"read", Action::"list"],
|
|
|
|
|
resource
|
|
|
|
|
);
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 2. Use Annotations
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
@id("prod-deploy-mfa")
|
|
|
|
|
@description("Production deployments require MFA verification")
|
|
|
|
|
@owner("platform-team")
|
|
|
|
|
@reviewed("2025-10-08")
|
|
|
|
|
@expires("2026-10-08")
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"platform-admin",
|
|
|
|
|
action == Action::"deploy",
|
|
|
|
|
resource in Environment::"production"
|
|
|
|
|
) when {
|
|
|
|
|
context.mfa_verified == true
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 3. Principle of Least Privilege
|
|
|
|
|
|
|
|
|
|
Give users **minimum permissions** needed:
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// ❌ BAD: Overly broad
|
|
|
|
|
permit (principal in Team::"developers", action, resource);
|
|
|
|
|
|
|
|
|
|
// ✅ GOOD: Specific permissions
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"developers",
|
|
|
|
|
action in [Action::"read", Action::"create", Action::"update"],
|
|
|
|
|
resource in Environment::"development"
|
|
|
|
|
);
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 4. Document Context Requirements
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
// Context required for this policy:
|
|
|
|
|
// - mfa_verified: boolean (from JWT claims)
|
|
|
|
|
// - approval_id: string (from request header)
|
|
|
|
|
// - ip_address: IpAddr (from connection)
|
|
|
|
|
permit (
|
|
|
|
|
principal in Role::"Operator",
|
|
|
|
|
action == Action::"deploy",
|
|
|
|
|
resource in Environment::"production"
|
|
|
|
|
) when {
|
|
|
|
|
context.mfa_verified == true &&
|
|
|
|
|
context has approval_id &&
|
|
|
|
|
context.ip_address.isInRange("10.0.0.0/8")
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 5. Separate Policies by Concern
|
|
|
|
|
|
|
|
|
|
**File organization**:
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
cedar-policies/
|
|
|
|
|
├── schema.cedar # Entity/action definitions
|
|
|
|
|
├── rbac.cedar # Role-based policies
|
|
|
|
|
├── teams.cedar # Team-based policies
|
|
|
|
|
├── time-restrictions.cedar # Time-based policies
|
|
|
|
|
├── ip-restrictions.cedar # Network-based policies
|
|
|
|
|
├── production.cedar # Production-specific
|
|
|
|
|
└── development.cedar # Development-specific
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 6. Version Control
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Git commit each policy change
|
|
|
|
|
git add provisioning/config/cedar-policies/production.cedar
|
|
|
|
|
git commit -m "feat(cedar): Add MFA requirement for prod deployments
|
|
|
|
|
|
|
|
|
|
- Require MFA for all production deployments
|
|
|
|
|
- Applies to devops and platform-admin teams
|
|
|
|
|
- Effective 2025-10-08
|
|
|
|
|
|
|
|
|
|
Policy ID: prod-deploy-mfa
|
|
|
|
|
Reviewed by: security-team
|
|
|
|
|
Ticket: SEC-1234"
|
|
|
|
|
|
|
|
|
|
git push
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### 7. Regular Policy Audits
|
|
|
|
|
|
|
|
|
|
**Quarterly review**:
|
2026-01-08 09:55:37 +00:00
|
|
|
|
2025-12-11 21:50:42 +00:00
|
|
|
- [ ] Remove unused policies
|
|
|
|
|
- [ ] Tighten overly permissive policies
|
|
|
|
|
- [ ] Update for new resources/actions
|
|
|
|
|
- [ ] Verify team memberships current
|
|
|
|
|
- [ ] Test break-glass procedures
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Quick Reference
|
|
|
|
|
|
|
|
|
|
### Common Policy Patterns
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Allow all
|
|
|
|
|
permit (principal, action, resource);
|
|
|
|
|
|
|
|
|
|
# Deny all
|
|
|
|
|
forbid (principal, action, resource);
|
|
|
|
|
|
|
|
|
|
# Role-based
|
|
|
|
|
permit (principal in Role::"Admin", action, resource);
|
|
|
|
|
|
|
|
|
|
# Team-based
|
|
|
|
|
permit (principal in Team::"platform", action, resource);
|
|
|
|
|
|
|
|
|
|
# Resource-based
|
|
|
|
|
permit (principal, action, resource in Environment::"production");
|
|
|
|
|
|
|
|
|
|
# Action-based
|
|
|
|
|
permit (principal, action in [Action::"read", Action::"list"], resource);
|
|
|
|
|
|
|
|
|
|
# Condition-based
|
|
|
|
|
permit (principal, action, resource) when { context.mfa_verified == true };
|
|
|
|
|
|
|
|
|
|
# Complex
|
|
|
|
|
permit (
|
|
|
|
|
principal in Team::"devops",
|
|
|
|
|
action == Action::"deploy",
|
|
|
|
|
resource in Environment::"production"
|
|
|
|
|
) when {
|
|
|
|
|
context.mfa_verified == true &&
|
|
|
|
|
context has approval_id &&
|
|
|
|
|
context.time.hour >= 9 &&
|
|
|
|
|
context.time.hour <= 17
|
|
|
|
|
};
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
### Useful Commands
|
|
|
|
|
|
2026-01-14 01:56:30 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
# Validate policies
|
|
|
|
|
provisioning cedar validate
|
|
|
|
|
|
|
|
|
|
# Reload policies (hot reload)
|
|
|
|
|
provisioning cedar reload
|
|
|
|
|
|
|
|
|
|
# List active policies
|
|
|
|
|
provisioning cedar list
|
|
|
|
|
|
|
|
|
|
# Test policies
|
|
|
|
|
provisioning cedar test tests/
|
|
|
|
|
|
|
|
|
|
# Query denials
|
|
|
|
|
provisioning audit query --action authorization_denied
|
|
|
|
|
|
|
|
|
|
# Policy statistics
|
|
|
|
|
provisioning cedar stats
|
2026-01-12 04:42:18 +00:00
|
|
|
```
|
2025-12-11 21:50:42 +00:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Support
|
|
|
|
|
|
|
|
|
|
- **Documentation**: `docs/architecture/CEDAR_AUTHORIZATION_IMPLEMENTATION.md`
|
|
|
|
|
- **Policy Examples**: `provisioning/config/cedar-policies/`
|
|
|
|
|
- **Issues**: Report to platform-team
|
|
|
|
|
- **Emergency**: Use break-glass procedure
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
**Version**: 1.0.0
|
|
|
|
|
**Maintained By**: Platform Team
|
|
|
|
|
**Last Updated**: 2025-10-08
|