Nungwi is a ReBAC style PoC authorization service inspired by Google Zanzibar, written in Ichiban Prolog. Nungwi is also is a village located at the northern end of the island of Zanzibar.
This is a PoC WIP. Don't use in production 😝
# Run the server
$ make run
# Write a schema
$ curl -XPOST 'http://localhost:8080/nungwi.v1alpha.NungwiService/WriteSchema' \
--header 'Content-Type: application/json' \
--data-raw '{
"configs": [
{
"namespace": "folder",
"relation": "viewer",
"rewrite": "self"
},
{
"namespace": "document",
"relation": "parent",
"rewrite": "self"
},
{
"namespace": "document",
"relation": "viewer",
"rewrite": "union(self, tupleToUserset(parent, viewer))"
}
]
}'
{}
# Write some tuples
$ curl -XPOST 'http://localhost:8080/nungwi.v1alpha.NungwiService/WriteTuples' \
--header 'Content-Type: application/json' \
--data-raw '{
"tuples": [
{
"namespace": "folder",
"id": "x",
"relation": "viewer",
"user": "abigail"
},
{
"namespace": "document",
"id": "a1",
"relation": "parent",
"user": "object(folder, x)"
},
{
"namespace": "document",
"id": "a2",
"relation": "parent",
"user": "object(folder, x)"
},
{
"namespace": "document",
"id": "a1",
"relation": "viewer",
"user": "beatrix"
}
]
}'
{}
# Check
$ curl -XPOST 'http://localhost:8080/nungwi.v1alpha.NungwiService/Check' \
--header 'Content-Type: application/json' \
--data-raw '{
"namespace": "document",
"id": "a1",
"relation": "viewer",
"user": "abigail"
}'
{"allowed": true}
# List objects
$ curl -XPOST 'http://localhost:8080/nungwi.v1alpha.NungwiService/ListObjects' \
--header 'Content-Type: application/json' \
--data-raw '{
"namespace": "document",
"relation": "viewer",
"user": "abigail"
}'
{"ids": [a1, a2]}
A rewrite can be any of the following:
self
.computedUserset(relation: str)
tupleToUserset(tupleset: str, computedUserset: str)
union(p1: rewrite, p2: rewrite)
intersection(p1: rewrite, p2: rewrite)
exclusion(minuend: rewrite, subtrahend: rewrite)
The str
type indicates that the argument must be a string, and the rewrite
type indicates that the argument is a rewrite itself.
A relation config consists of a namespace, relation, and rewrite. These are written as:
config(namespace, relation, rewrite)
A schema consists of one or more relation configs.
A user can be any of the following:
userId: str
object(namespace: str, id: str)
userset(namespace: str, id: str, relation: str)
A tuple consists of a namespace, id, relation, and user. These are written as:
tuple(namespace, id, relation, user)
You can run nungwi using Docker with:
docker compose up
Not so well. You can try to run the load tests in the k6 directory.
We ❤️ contributions.
- Thank you to @ichiban for helping me with Ichiban Prolog.