How actions, users, and resources are automatically mapped to policy data
You do not need to write any policy verification engine or custom gateway. For every request, we extract the relevant details and map them onto policy entities and actions. All Cedar policies have a Principal (who is it), Action (what are they doing), and Resource (what resource is their action targeting).
Principal
The principal is always the user making the request. If they are authenticated with Jupiter Auth and the request includes their access token in the Authorization header, it will be parsed and verified, and the claims will be mapped onto the principal entity. The standard default claims from the access token will be included under the principal object, while the custom configurable claims (user_attributes, system_attributes, custom_claims) will be passed dynamically to the context.
Standard claims included under the principal
permit ( principal, action == JupiterStorage::Action::"GetObject", resource)when { principal.is_anonymous == false};Optional dynamic claims under the context
permit ( principal, action == JupiterStorage::Action::"GetObject", resource)when { context.user_attributes has age && context.user_attributes.age >= 18};Action
Actions are the specific operations that the user tries to perform. For Storage requests, actions are mapped directly from the API request to Storage actions.
| Action | Cedar Action Name |
|---|---|
| GetObject | JupiterStorage::Action::"GetObject" |
| ListObjects | JupiterStorage::Action::"ListObjects" |
| DeleteObject | JupiterStorage::Action::"DeleteObject" |
| UploadObject | JupiterStorage::Action::"UploadObject" |
| DownloadObject | JupiterStorage::Action::"DownloadObject" |
| StartMultipartUpload | JupiterStorage::Action::"StartMultipartUpload" |
| GetMultipartUpload | JupiterStorage::Action::"GetMultipartUpload" |
| UploadMultipartPart | JupiterStorage::Action::"UploadMultipartPart" |
| ListMultipartUploadParts | JupiterStorage::Action::"ListMultipartUploadParts" |
| GetMultipartUploadPart | JupiterStorage::Action::"GetMultipartUploadPart" |
| CompleteMultipartUpload | JupiterStorage::Action::"CompleteMultipartUpload" |
| AbortMultipartUpload | JupiterStorage::Action::"AbortMultipartUpload" |
| DeleteObjects | JupiterStorage::Action::"DeleteObjects" |
| CopyObject | JupiterStorage::Action::"CopyObject" |
| UpdateObject | JupiterStorage::Action::"UpdateObjectMetadata" |
| ListMultipartUploads | JupiterStorage::Action::"ListMultipartUploads" |
| UploadPartCopy | JupiterStorage::Action::"UploadPartCopy" |
For example, if you have an app that allows users to upload content, such as photos, and users on the free tier can only access uploaded data without posting, you could use the following policy.
forbid ( principal, action == JupiterStorage::Action::"UploadObject", resource)when { context.user_attributes.user.plan == "free"};Resource
The resource is the bucket or object to which the action applies. Depending on the particular action, additional data will be included in the context and parent entities.
| Action | Resource | Included context |
|---|---|---|
| GetObject | JupiterObject | { bucket: JupiterBucket } |
| ListObjects | JupiterBucket | — |
| DeleteObject | JupiterObject | { bucket: JupiterBucket } |
| UploadObject | JupiterObject | { bucket: JupiterBucket } |
| DownloadObject | JupiterObject | { bucket: JupiterBucket } |
| StartMultipartUpload | JupiterObject | { bucket: JupiterBucket } |
| GetMultipartUpload | JupiterObject | { bucket: JupiterBucket } |
| UploadMultipartPart | JupiterObject | { bucket: JupiterBucket } |
| ListMultipartUploadParts | JupiterObject | { bucket: JupiterBucket } |
| GetMultipartUploadPart | JupiterObject | { bucket: JupiterBucket } |
| CompleteMultipartUpload | JupiterObject | { bucket: JupiterBucket } |
| AbortMultipartUpload | JupiterObject | { bucket: JupiterBucket } |
| DeleteObjects | JupiterBucket | { objects: [JupiterObject] } |
| CopyObject | JupiterObject | { bucket: JupiterBucket, source: JupiterObject, source_bucket: JupiterBucket } |
| UpdateObject | JupiterObject | { bucket: JupiterBucket } |
| ListMultipartUploads | JupiterBucket | — |
| UploadPartCopy | JupiterObject | { bucket: JupiterBucket, source: JupiterObject } |
Protect a bucket
Storage requests carry the authenticated user context supplied by Jupiter Auth. A policy can compare that context with the requested Storage resource before the operation reaches the service.
permit ( principal, action in [ JupiterStorage::Action::"UploadObject", JupiterStorage::Action::"GetObject" ], resource)when { context.auth.user.id == resource.owner_id};Restrict large uploads by plan
This policy denies uploads larger than 5 GB unless the authenticated user has a pro subscription plan in custom claims.
forbid ( principal, action == JupiterStorage::Action::"UploadObject", resource)when { resource.object.size > 5368709120 && context.auth.user.custom_claims.subscription_plan != "pro"};