Converted JSON schemas use "EntityOrCommon"
Opened this issue · 3 comments
Describe the improvement you'd like to request
Due to recent changes introduced on main
(which are currently unreleased, but will be released as part of 4.0), converting a Cedar schema to JSON will now introduce "EntityOrCommon" types. These seems like an internal detail that is not useful to expose to users. Is there a way to hide this detail when returning JSON data from SchemaFragment::to_json_string
?
As an example, here's a snippet from the translation of the TinyTodo schema:
{
"": {
"commonTypes": {
"Task": {
"type": "Record",
"attributes": {
"id": {
"type": "EntityOrCommon",
"name": "Long"
},
"name": {
"type": "EntityOrCommon",
"name": "String"
},
"state": {
"type": "EntityOrCommon",
"name": "String"
}
}
},
"Tasks": {
"type": "Set",
"element": {
"type": "EntityOrCommon",
"name": "Task"
}
}
},
"entityTypes": {
"Team": {
"memberOfTypes": [
"Team",
"Application"
]
},
"User": {
"memberOfTypes": [
"Team",
"Application"
],
"shape": {
"type": "Record",
"attributes": {
"joblevel": {
"type": "EntityOrCommon",
"name": "Long"
},
"location": {
"type": "EntityOrCommon",
"name": "String"
}
}
}
},
...
The more natural way for a user to write this would be:
{
"": {
"commonTypes": {
"Task": {
"type": "Record",
"attributes": {
"id": {
"type": "Long"
},
"name": {
"type": "String"
},
"state": {
"type": "String"
}
}
},
"Tasks": {
"type": "Set",
"element": {
"type": "Task"
}
}
},
"entityTypes": {
"Team": {
"memberOfTypes": [
"Team",
"Application"
]
},
"User": {
"memberOfTypes": [
"Team",
"Application"
],
"shape": {
"type": "Record",
"attributes": {
"joblevel": {
"type": "Long"
},
"location": {
"type": "String"
}
}
}
},
...
Describe alternatives you've considered
No response
Additional context
Related: the Display
trait for the Cedar schema format is also not as pretty as it could be. See #682.
Is this something that you'd be interested in working on?
- 👋 I may be able to implement this internal improvement
-
⚠️ This feature might incur a breaking change
some context: in some ways, EntityOrCommon
is more correct than the previous status quo. The Cedar syntax Long
will actually refer to an entity type Long
if it exists, in preference to the builtin type Long
, as specified by RFC 24. (This is why RFC 24 introduced the __cedar::Long
notation in the first place.) This remains true after #1150, which only introduced restrictions on the names of common types, not entity types. So, translating Cedar syntax Long
to JSON EntityOrCommon
is an accurate reflection of the semantics of the Cedar syntax.
To resolve this issue, we would have to actually resolve the typenames in the Cedar syntax (e.g., to know that Long
does indeed refer to the builtin type Long
) in order to write a more accurate JSON-syntax typename.
I attempted to add a common type with type String = __cedar::String;
but cedar validate
returns an error:
error parsing schema: this uses a reserved schema keyword: `String`
2 │ type String = __cedar::String;
help: Keywords such as `entity`, `extension`, `set` and `record` cannot be used as common type names
On the other hand, I am able to create an Entity with the name String
—that just earns me a warning:
⚠ The name `String` shadows a builtin Cedar name. You'll have to refer to the builtin as `__cedar::String`.
My own personal issue with using EntityOrCommon
for built-in primitive types is that Amazon Verified Permissions does not work with JSON-formatted cedar schema like this. It doesn't seem to understand EntityOrCommon
at all, so I can't use cedar translate-schema
to convert my nice schema into JSON form to hand over to Amazon Verified Permissions without post-processing to remove all the EntityOrCommon
references. I guess that's technically an AWS problem, not a Cedar problem, but... it's extra friction in the ecosystem.
If you want to use your schema with AVP, it should work if you convert the schema with the latest 3.x CLI release. This release won't insert EntityOrCommon
, so it should work