Created
November 7, 2025 02:20
-
-
Save dengjonathan/ecc2c050b904fa2a7127412ac94cd997 to your computer and use it in GitHub Desktop.
Cedar Policies for Automotive Case
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ========== AUTOMOTIVE R&D PROJECT ACCESS CONTROL ========== | |
| // | |
| // Scenario: Automotive R&D project with 6 assets (engine, transmission, chassis, | |
| // drive_assistance, interior, vehicle_sensors). The project focuses on redesigning | |
| // the engine. Access control is needed to limit access to 4 relevant assets | |
| // (engine, transmission, chassis, vehicle_sensors) to specific groups. | |
| // | |
| // Groups: | |
| // - engineGroup: Internal engine design team | |
| // - transmissionReviewers: Internal transmission review group | |
| // - TestVendorExternal: External testing facility vendors | |
| // | |
| // Access Requirements: | |
| // - Engine Group: All data (all assets and associated channels) | |
| // - Transmission Reviewers: Assets (engine, transmission) and associated channels | |
| // - Test Vendor (External): EngineChannel_1 and EngineChannel_2 only under the Engine asset | |
| // - Any new user not in either group: Nothing (default deny) | |
| // ========== ENGINE GROUP ACCESS (Full Access) ========== | |
| // Policy 1: Engine Group can view all assets | |
| permit ( | |
| // This SiftApp::UserGroup is defined in our ABAC system as an attribute NOT within the existing RBAC system. | |
| principal in SiftApp::UserGroup::"engineGroup", | |
| action == SiftApp::Action::"view", | |
| resource is SiftApp::Asset | |
| ); | |
| // Policy 2: Engine Group can view all channels (across all assets) | |
| permit ( | |
| principal in SiftApp::UserGroup::"engineGroup", | |
| action == SiftApp::Action::"view", | |
| resource is SiftApp::Channel | |
| ); | |
| // Policy 3: Engine Group can perform all actions on all assets | |
| permit ( | |
| principal in SiftApp::UserGroup::"engineGroup", | |
| action in [SiftApp::Action::"create", SiftApp::Action::"edit", SiftApp::Action::"delete", SiftApp::Action::"update", SiftApp::Action::"ingest"], | |
| resource is SiftApp::Asset | |
| ); | |
| // Policy 4: Engine Group can perform all actions on all channels | |
| permit ( | |
| principal in SiftApp::UserGroup::"engineGroup", | |
| action in [SiftApp::Action::"create", SiftApp::Action::"edit", SiftApp::Action::"delete", SiftApp::Action::"update", SiftApp::Action::"ingest"], | |
| resource is SiftApp::Channel | |
| ); | |
| // ========== TRANSMISSION REVIEWERS ACCESS (Limited to Engine and Transmission) ========== | |
| // Policy 5: Transmission Reviewers can view engine and transmission assets | |
| permit ( | |
| principal in SiftApp::UserGroup::"transmissionReviewers", | |
| action == SiftApp::Action::"view", | |
| resource is SiftApp::Asset | |
| ) | |
| when | |
| { | |
| resource has owning_team && | |
| (resource.owning_team == "engine" || resource.owning_team == "transmission") | |
| }; | |
| // Policy 6: Transmission Reviewers can perform read-only actions on engine and transmission assets | |
| permit ( | |
| principal in SiftApp::UserGroup::"transmissionReviewers", | |
| action in [SiftApp::Action::"view", SiftApp::Action::"update-metadata"], | |
| resource is SiftApp::Asset | |
| ) | |
| when | |
| { | |
| resource has owning_team && | |
| (resource.owning_team == "engine" || resource.owning_team == "transmission") | |
| }; | |
| // Note: CONSISTENT RULE - Access to all channels requires parent Asset access with the same action. | |
| // - Channels with empty attributes: Skip Cedar evaluation via pre-filter, use parent asset result directly | |
| // - Channels with attributes: Evaluate Cedar policies on channel, AND still require parent asset access | |
| // This ensures channels can be more restrictive (via attributes) but never bypass parent requirements. | |
| // Channels under engine and transmission assets automatically inherit access through this mechanism. | |
| // ========== TEST VENDOR EXTERNAL ACCESS (Very Limited - Specific Channels Only) ========== | |
| // Policy 7: Test Vendor External can view only EngineChannel_1 and EngineChannel_2 under the Engine asset | |
| // Note: EngineChannel_1 and EngineChannel_2 must have an "allow_external_vendor" attribute set to true. | |
| // CONSISTENT RULE: All channels require parent asset access. This policy allows specific channels, | |
| // but they still require engine asset access (Policy 9) and parent check in application logic. | |
| permit ( | |
| principal in SiftApp::UserGroup::"TestVendorExternal", | |
| action == SiftApp::Action::"view", | |
| resource is SiftApp::Channel | |
| ) | |
| when | |
| { | |
| resource has name && | |
| resource has allow_external_vendor && | |
| resource.allow_external_vendor == true | |
| }; | |
| // Policy 8: Test Vendor External is read-only (no write operations) | |
| forbid ( | |
| principal in SiftApp::UserGroup::"TestVendorExternal", | |
| action in [SiftApp::Action::"create", SiftApp::Action::"edit", SiftApp::Action::"delete", SiftApp::Action::"update", SiftApp::Action::"ingest"], | |
| resource | |
| ); | |
| // Policy 9: Test Vendor External can view the engine asset (required to access channels under it) | |
| // Note: Consistent rule - channels require parent asset access. External vendors need engine asset | |
| // access to view the two specific channels (Policy 7), but cannot view other assets. | |
| permit ( | |
| principal in SiftApp::UserGroup::"TestVendorExternal", | |
| action == SiftApp::Action::"view", | |
| resource is SiftApp::Asset | |
| ) | |
| when | |
| { | |
| resource has owning_team && | |
| resource.owning_team == "engine" | |
| }; | |
| // Policy 10: Test Vendor External cannot view any assets other than engine | |
| forbid ( | |
| principal in SiftApp::UserGroup::"TestVendorExternal", | |
| action == SiftApp::Action::"view", | |
| resource is SiftApp::Asset | |
| ) | |
| when | |
| { | |
| !(resource has owning_team) || | |
| resource.owning_team != "engine" | |
| }; | |
| // Policy 11: Test Vendor External cannot view any channels other than EngineChannel_1 and EngineChannel_2 | |
| // This explicitly forbids all other channels, including those under the engine asset that don't have | |
| // the allow_external_vendor attribute. This ensures only the two specific channels are accessible. | |
| forbid ( | |
| principal in SiftApp::UserGroup::"TestVendorExternal", | |
| action == SiftApp::Action::"view", | |
| resource is SiftApp::Channel | |
| ) | |
| when | |
| { | |
| !(resource has name) || | |
| (resource.name != "EngineChannel_1" && resource.name != "EngineChannel_2") || | |
| !(resource has allow_external_vendor) || | |
| resource.allow_external_vendor != true | |
| }; | |
| // ========== DEFAULT DENY (Explicit Denial for Unauthorized Users) ========== | |
| // Policy 11: Explicitly deny access to restricted assets (chassis, vehicle_sensors) for non-engine-group users | |
| // Note: This is redundant with default deny, but makes the policy explicit | |
| forbid ( | |
| principal, | |
| action == SiftApp::Action::"view", | |
| resource is SiftApp::Asset | |
| ) | |
| when | |
| { | |
| resource has owning_team && | |
| (resource.owning_team == "chassis" || resource.owning_team == "vehicle_sensors") && | |
| !(principal in SiftApp::UserGroup::"engineGroup") | |
| }; | |
| // Note: Channels under restricted assets are automatically denied through application-level logic | |
| // (applyChannelPolicyLogic) that requires VIEW permission on the parent asset. Since parent asset | |
| // access is denied in Policy 11, channels are automatically denied. No channel-specific policy needed. | |
| // Policy 12: Deny access to drive_assistance and interior assets for non-engine-group users | |
| forbid ( | |
| principal, | |
| action == SiftApp::Action::"view", | |
| resource is SiftApp::Asset | |
| ) | |
| when | |
| { | |
| resource has owning_team && | |
| (resource.owning_team == "drive_assistance" || resource.owning_team == "interior") && | |
| !(principal in SiftApp::UserGroup::"engineGroup") | |
| }; | |
| // Note: Channels under drive_assistance and interior assets are automatically denied through | |
| // application-level logic. No channel-specific policy needed. | |
| // ========== NOTES ========== | |
| // | |
| // Entity Structure Expected: | |
| // - Assets: SiftApp::Asset with "owning_team" attribute ("engine", "transmission", "chassis", "drive_assistance", "interior", "vehicle_sensors") | |
| // - Channels: SiftApp::Channel with parent relationship to Asset | |
| // * Most channels: EMPTY attributes (no attributes at all) | |
| // * Special channels: Attributes like "allow_external_vendor" for override cases | |
| // - User Groups: SiftApp::UserGroup::"engineGroup", SiftApp::UserGroup::"transmissionReviewers", SiftApp::UserGroup::"TestVendorExternal" | |
| // | |
| // Important Considerations: | |
| // 1. Cedar is deny-by-default, so users not matching any permit policy will be denied access | |
| // 2. Sparse Attribute Model (Optimized for High Cardinality): | |
| // - Assets have attributes (e.g., "owning_team") - low cardinality, manageable storage | |
| // - Most channels have NO attributes - they rely on parent asset checks via application-level logic | |
| // - Only special channels that need different permissions than parent get attributes | |
| // - This avoids ballooning storage costs for 10k+ channels where most data would be sparse/duplicated | |
| // 3. Channel Access Control Pattern (CONSISTENT RULE): | |
| // - ALL channels require parent asset access (enforced via application-level logic) | |
| // - Channels with empty attributes: Skip Cedar evaluation via pre-filter, use parent asset result | |
| // (pre-filter optimization - most channels fall into this category) | |
| // - Channels with attributes: Evaluate Cedar policies on channel, AND still require parent asset access | |
| // (attributes can make channels more restrictive, but never bypass parent requirements) | |
| // - This consistent rule applies to all cases: | |
| // * Transmission Reviewers: Empty channels → inherit from parent (parent allows via Policy 5) | |
| // * External Vendor: Special channels → require engine asset access (Policy 9), then channel policy (Policy 7) | |
| // * Future cases: Attributes can make channels more restrictive, but parent access always required | |
| // 4. The policies assume: | |
| // - Assets have an "owning_team" attribute ("engine", "transmission", "chassis", etc.) | |
| // - Most channels have EMPTY attributes (no attributes at all) | |
| // - Special channels (like EngineChannel_1, EngineChannel_2) have attributes like "allow_external_vendor" | |
| // to add additional restrictions/permissions on top of parent requirements - these are the exception, not the rule | |
| // 5. Test Vendor External has the most restrictive access (read-only, specific channels only) | |
| // - Policy 9 allows engine asset access (required for channel access) | |
| // - Policy 7 allows specific channels that have "allow_external_vendor" attribute | |
| // - Policy 11 explicitly forbids all other channels under engine asset | |
| // - Consistent rule: Channels require parent asset access, attributes can add restrictions but not bypass parent | |
| // 6. Transmission Reviewers have read-only access to engine and transmission assets/channels | |
| // - Policies 5 & 6 define access on assets only | |
| // - Channels inherit access through application-level logic (no channel attributes needed) | |
| // 7. Engine Group has full access to all assets and channels | |
| // 8. This approach scales efficiently: storage costs stay low since most channels have no attributes, | |
| // and performance is good since we're not duplicating sparse data across thousands of channels | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment