Any complex system is only useful if it can be configured and maintained in a reasonable manner by those using it. At Authzed, we are building the permission system as a service for the world, modeled on the Zanzibar service as originally described by Google in the Zanzibar paper. While Zanzibar and Authzed are simple to use, the complexity of configuring the object type definitions (called "namespaces" in Zanzibar) associated with a permissions system has left something to be desired. This is primarily due to the configuration being based on Protocol Buffers, with the configuration "language" merely being the text form of the underlying proto messages. Recognizing that this experience for developers has shown room for improvement, we are happy today to announce the release of the new Authzed configuration language.
Reducing complexity
The primary goal of the new Authzed configuration language is to reduce complexity of configuration.
As an example, imagine a simple permissions system consisting of document
s, which have roles reader
and writer
, permissions read
and write
, and a type of user
.
In the new configuration language, this can be represented concisely and clearly:
In contrast, in the previous Zanzibar-inspired configuration, this would consist of two configuration "files":
name: "user"
name: "document"
relation {
name: "reader"
}
relation {
name: "writer"
}
relation {
name: "write"
userset_rewrite {
union {
child {
computed_userset {
relation: "writer"
}
}
}
}
}
relation {
name: "read"
userset_rewrite {
union {
child {
computed_userset {
relation: "writer"
}
}
child {
computed_userset {
relation: "reader"
}
}
}
}
}
As we can see, the above configuration is verbose, confusing (what even is a computed_userset
?), and broken into two distinct blocks, despite them being related and, despite being far more concise, the config language has exactly reproduced the above configuration (in fact, it is translated directly into it!).
The new language allows for easy and readable configuration, without any loss of power or expression.
Permitting a relationship
Two interesting items to note in the config language are the separation of concerns between relation
and permission
and the addition of allowed subject types.
We've had a lot of developer feedback that issuing Check calls on a relation to represent a permission can be... somewhat confusing.
To rectify this issue, the configuration now has a distinction between relation
's, which relate one Object to another (or a Subject), and permission
s, which are computed from one or more relations (or permissions), and represent distinct authorization decisions.
To reinforce this distinction, we recommend using verbs for permissions (read
, write
) and nouns for relations (reader
, writer
), to indicate that relations define a relationship (such as a role in RBAC), while permissions represent, well, a permission!
The addition of allowed subject types, on the other hand, provides two major benefits: developer safety and data for driving new APIs.
Developer safety is enhanced by the API verifying that subjects written to a relation
match those specified in the schema: If a subject does not match, the write call to the Authzed API will now fail at runtime, ensuring that relationships only exist between objects and subjects that are expected.
This data is also used by the Lookup API to assist in its walk of the permissions graph, ensuring that Authzed can provide performant ACL filtering without having to infer the kinds of relationships that might exist between objects.
Try it now
The configuration language is now fully supported in the Authzed Playground, as well as the Authzed API. Try it today, read the documentation, or discuss in Discord. We hope it proves a far better configuration experience!
Additional Reading
If you’re interested in learning more about Authorization and Google Zanzibar, we recommend reading the following posts: