Step 2: Create the Policy Engine
This is the big upgrade from Lab 1. Instead of hard-coding access logic in a Lambda function, we'll define policies in Amazon Verified Permissions using the Cedar policy language. Cedar lets us write human-readable rules that the service evaluates for us.
Create a Policy Store
- Go to Amazon Verified Permissions Console: https://console.aws.amazon.com/verifiedpermissions
- Click Create policy store
- Choose Create with an empty policy store
- Description:
DCS Level 2 - Coalition ABAC policies - Click Create policy store
- Note down the Policy Store ID (you'll need it later)
Define the Schema
The schema tells Verified Permissions what your entities (users, data objects) and actions look like.
- In your policy store, go to Schema
- Click Edit schema then choose the JSON mode editor
- Paste this schema:
{
"DCS": {
"entityTypes": {
"User": {
"shape": {
"type": "Record",
"attributes": {
"clearanceLevel": { "type": "Long", "required": true },
"nationality": { "type": "String", "required": true },
"saps": {
"type": "Set",
"element": { "type": "String" }
}
}
}
},
"DataObject": {
"shape": {
"type": "Record",
"attributes": {
"classificationLevel": { "type": "Long", "required": true },
"releasableTo": {
"type": "Set",
"element": { "type": "String" }
},
"requiredSap": { "type": "String", "required": true },
"originator": { "type": "String", "required": true }
}
}
}
},
"actions": {
"read": {
"appliesTo": {
"principalTypes": ["User"],
"resourceTypes": ["DataObject"]
}
},
"write": {
"appliesTo": {
"principalTypes": ["User"],
"resourceTypes": ["DataObject"]
}
}
}
}
}
- Click Save changes
This schema defines:
- Users have a clearance level (number), nationality (text), and a set of SAPs
- DataObjects have a classification level (number), a set of releasable-to countries, a required SAP, and an originator
- Users can read or write data objects
Add Cedar Policies
Policy 1: Standard access (clearance + nationality + SAP)
- Go to Policies > Create policy > Create static policy
- Description:
Standard access - clearance, nationality, and SAP check - Policy body:
permit(
principal is DCS::User,
action == DCS::Action::"read",
resource is DCS::DataObject
) when {
principal.clearanceLevel >= resource.classificationLevel &&
resource.releasableTo.contains(principal.nationality) &&
(resource.requiredSap == "" || principal.saps.contains(resource.requiredSap))
};
- Click Create policy
What this says in plain English: Allow a user to read a data object when:
- Their clearance level is at least as high as the data's classification level, AND
- Their nationality is in the data's releasable-to list, AND
- Either the data doesn't require a SAP, or the user has the required SAP
Policy 2: Originator access
- Create another static policy
- Description:
Originator access - data creators always have access - Policy body:
permit(
principal is DCS::User,
action == DCS::Action::"read",
resource is DCS::DataObject
) when {
principal.nationality == resource.originator
};
- Click Create policy
What this says: Users from the same country that created the data always have read access.
Policy 3: Block revoked clearances
- Create another static policy
- Description:
Block users with revoked clearance (level 0) - Policy body:
forbid(
principal is DCS::User,
action,
resource is DCS::DataObject
) when {
principal.clearanceLevel == 0
};
- Click Create policy
What this says: Users with clearance level 0 (revoked) are denied access to everything.
Test the policies
Verified Permissions has a built-in test feature:
- Go to Test bench in the left menu
- Fill in:
- Principal:
DCS::User::"uk-analyst-01" - Add attributes:
clearanceLevel: 2,nationality: "GBR",saps: {"WALL"} - Action:
DCS::Action::"read" - Resource:
DCS::DataObject::"intel-report-001" - Add attributes:
classificationLevel: 2,releasableTo: {"GBR", "USA", "POL"},requiredSap: "",originator: "POL"
- Principal:
- Click Run authorization request
- Result should be ALLOW
Try changing the principal's clearanceLevel to 0 and run again - you should get DENY.
Cedar is powerful
We wrote three short policies that handle all our access scenarios. Compare this to Lab 1 where we wrote a Python function with if/else logic. Cedar policies are declarative (you say what's allowed, not how to check), testable, and changeable without code deploys.