{"id":13562948,"url":"https://github.com/craigpastro/nungwi","last_synced_at":"2025-04-03T19:31:55.030Z","repository":{"id":64654284,"uuid":"573245820","full_name":"craigpastro/nungwi","owner":"craigpastro","description":"Nungwi is a PoC authorization service inspired by Google Zanzibar, written in Ichiban Prolog.","archived":true,"fork":false,"pushed_at":"2024-04-01T19:06:11.000Z","size":179,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-04T15:52:03.438Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/craigpastro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-02T02:26:03.000Z","updated_at":"2024-04-01T19:06:27.000Z","dependencies_parsed_at":"2023-12-01T15:28:03.365Z","dependency_job_id":"dfb88e81-a035-49c6-a549-dc5330289bca","html_url":"https://github.com/craigpastro/nungwi","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigpastro%2Fnungwi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigpastro%2Fnungwi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigpastro%2Fnungwi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigpastro%2Fnungwi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/craigpastro","download_url":"https://codeload.github.com/craigpastro/nungwi/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247065314,"owners_count":20877756,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T13:01:13.710Z","updated_at":"2025-04-03T19:31:54.761Z","avatar_url":"https://github.com/craigpastro.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Nungwi\n\nNungwi is a ReBAC style PoC authorization service inspired by\n[Google Zanzibar](https://research.google/pubs/pub48190/), written in\n[Ichiban Prolog](https://github.com/ichiban/prolog). Nungwi is also is a village\nlocated at the northern end of the island of Zanzibar.\n\nThis is a PoC WIP. Don't use in production :stuck_out_tongue_closed_eyes:\n\n## Example Usage\n\n```console\n# Run the server\n$ make run\n\n# Write a schema\n$ curl -XPOST 'http://localhost:8080/nungwi.v1alpha.NungwiService/WriteSchema' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"configs\": [\n        {\n            \"namespace\": \"folder\",\n            \"relation\": \"viewer\",\n            \"rewrite\": \"self\"\n        },\n        {\n            \"namespace\": \"document\",\n            \"relation\": \"parent\",\n            \"rewrite\": \"self\"\n        },\n        {\n            \"namespace\": \"document\",\n            \"relation\": \"viewer\",\n            \"rewrite\": \"union(self, tupleToUserset(parent, viewer))\"\n        }\n    ]\n}'\n{}\n\n# Write some tuples\n$ curl -XPOST 'http://localhost:8080/nungwi.v1alpha.NungwiService/WriteTuples' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"tuples\": [\n        {\n            \"namespace\": \"folder\",\n            \"id\": \"x\",\n            \"relation\": \"viewer\",\n            \"user\": \"abigail\"\n        },\n        {\n            \"namespace\": \"document\",\n            \"id\": \"a1\",\n            \"relation\": \"parent\",\n            \"user\": \"object(folder, x)\"\n        },\n        {\n            \"namespace\": \"document\",\n            \"id\": \"a2\",\n            \"relation\": \"parent\",\n            \"user\": \"object(folder, x)\"\n        },\n        {\n            \"namespace\": \"document\",\n            \"id\": \"a1\",\n            \"relation\": \"viewer\",\n            \"user\": \"beatrix\"\n        }\n    ]\n}'\n{}\n\n# Check\n$ curl -XPOST 'http://localhost:8080/nungwi.v1alpha.NungwiService/Check' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"namespace\": \"document\",\n    \"id\": \"a1\",\n    \"relation\": \"viewer\",\n    \"user\": \"abigail\"\n}'\n{\"allowed\": true}\n\n# List objects\n$ curl -XPOST 'http://localhost:8080/nungwi.v1alpha.NungwiService/ListObjects' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"namespace\": \"document\",\n    \"relation\": \"viewer\",\n    \"user\": \"abigail\"\n}'\n{\"ids\": [a1, a2]}\n```\n\n## Modelling\n\n### Schema\n\nA rewrite can be any of the following:\n\n- `self`.\n- `computedUserset(relation: str)`\n- `tupleToUserset(tupleset: str, computedUserset: str)`\n- `union(p1: rewrite, p2: rewrite)`\n- `intersection(p1: rewrite, p2: rewrite)`\n- `exclusion(minuend: rewrite, subtrahend: rewrite)`\n\nThe `str` type indicates that the argument must be a string, and the `rewrite`\ntype indicates that the argument is a rewrite itself.\n\nA relation config consists of a namespace, relation, and rewrite. These are\nwritten as:\n\n```python\nconfig(namespace, relation, rewrite)\n```\n\nA schema consists of one or more relation configs.\n\n### Tuples\n\nA user can be any of the following:\n\n- `userId: str`\n- `object(namespace: str, id: str)`\n- `userset(namespace: str, id: str, relation: str)`\n\nA tuple consists of a namespace, id, relation, and user. These are written as:\n\n```python\ntuple(namespace, id, relation, user)\n```\n\n## Try it out\n\nYou can run nungwi using Docker with:\n\n```\ndocker compose up\n```\n\n## How does it perform?\n\nNot so well. You can try to run the load tests in the [k6](./k6) directory.\n\n## Contributions\n\nWe :heart: contributions.\n\n## Acknowledgements\n\n- Thank you to @ichiban for helping me with\n  [Ichiban Prolog](https://github.com/ichiban/prolog).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcraigpastro%2Fnungwi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcraigpastro%2Fnungwi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcraigpastro%2Fnungwi/lists"}