{"id":20611942,"url":"https://github.com/craigpastro/pgfga","last_synced_at":"2025-05-10T01:31:43.799Z","repository":{"id":195139061,"uuid":"691365140","full_name":"craigpastro/pgfga","owner":"craigpastro","description":"An experimental Postgres extension for doing fine-grained authorization","archived":true,"fork":false,"pushed_at":"2025-02-03T02:10:53.000Z","size":130,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-01T06:34:29.294Z","etag":null,"topics":["postgres","postgres-extension","postgresql","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","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":"2023-09-14T03:14:11.000Z","updated_at":"2025-02-03T02:11:37.000Z","dependencies_parsed_at":"2024-01-01T10:33:40.204Z","dependency_job_id":"1511ee66-7c7a-400b-aae4-a5cd4f6b5105","html_url":"https://github.com/craigpastro/pgfga","commit_stats":null,"previous_names":["craigpastro/pgfga"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigpastro%2Fpgfga","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigpastro%2Fpgfga/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigpastro%2Fpgfga/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigpastro%2Fpgfga/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/craigpastro","download_url":"https://codeload.github.com/craigpastro/pgfga/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253350024,"owners_count":21894818,"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":["postgres","postgres-extension","postgresql","rust"],"created_at":"2024-11-16T10:22:41.796Z","updated_at":"2025-05-10T01:31:43.793Z","avatar_url":"https://github.com/craigpastro.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Postgres Fine-Grained Authorization (pgfga)\n\n## What is this?\n\nThis is an experimental Postgres extension for doing fine-grained authorization\n(fga), written with [pgrx](https://github.com/pgcentralfoundation/pgrx).\n\nFGA here means Relationship Based Access Control (ReBAC) based off the\n[Zanzibar paper](https://research.google/pubs/pub48190/), and is similar to what\n[Nungwi](https://github.com/craigpastro/nungwi),\n[OpenFGA](https://github.com/openfga/openfga),\n[Permify](https://github.com/Permify/permify),\n[SpiceDB](https://github.com/authzed/spicedb),\n[Warrent](https://github.com/warrant-dev/warrant), and others have done.\n\nThis is a WIP. There is no documentation and there are no validations. There are\nplans to add these things, and a bunch more. See the \"roadmap\" below. Please\nhelp out if you are interested!\n\n## Usage\n\n```bash\npgfga=# CREATE EXTENSION pgfga;\n\npgfga=# SELECT * FROM pgfga.create_schema('{\"namespaces\":{\"document\":{\"relations\":{\"viewer\":[{\"namespace\":\"user\"}]},\"permissions\":{\"can_view\":{\"union\":[{\"computedUserset\":\"viewer\"},{\"tupleToUserset\":[\"parent\",\"can_view\"]}]}}},\"user\":{\"relations\":{},\"permissions\":{}}}}');\n         create_schema          \n--------------------------------------\n 31c1cf4f-f1de-42fb-8e24-9f407805dadf\n\n\npgfga=# SELECT * FROM pgfga.create_tuple('31c1cf4f-f1de-42fb-8e24-9f407805dadf', 'document', '1', 'viewer', 'user', 'anya', '');\n create_tuple \n--------------\n            1\n(1 row)\n\npgfga=# SELECT * FROM pgfga.check('31c1cf4f-f1de-42fb-8e24-9f407805dadf', 'document', '1', 'viewer', 'user', 'anya', '');\n check \n-------\n t\n(1 row)\n```\n\n## Docker\n\nYou can spin up a Postgres container with the `pgfga` extension installed with\n`docker compose up -d`. (This doesn't seem to work on silicon Macs though. I'm\ninvestigating and would love any help.) Once Postgres is up, you can connect to\nit using the following connection string:\n\n```\npostgres://postgres:password@localhost:28801/postgres\n```\n\n## Installation\n\nRequires [pgrx](https://github.com/pgcentralfoundation/pgrx). If you have pgrx\ninstalled and `init`ed then\n\n```\ncargo pgrx run pg16\n```\n\nshould drop you into a psql prompt:\n\n```\npsql (16.0)\nType \"help\" for help.\n\npgfga=# CREATE EXTENSION pgfga;\nCREATE EXTENSION\n```\n\n## Extension functions\n\nThe `pgfga` extension is comprised of the following functions:\n\n- `pgfga.create_schema`\n- `pgfga.read_schema`\n- `pgfga.read_schemas`\n- `pgfga.create_tuple`\n- `pgfga.read_tuples`\n- `pgfga.delete_tuple`\n- `pgfga.check`\n\nSee below for descriptions and examples.\n\n### `pgfga.create_schema`\n\n```sql\npgfga=# SELECT * FROM pgfga.create_schema(schema::json);\n            create_schema             \n--------------------------------------\n e8f8971e-12d7-40a6-b45c-b39d621fd34f\n(1 row)\n```\n\nSchemas in `pgfga` are closely related to the schemas of\n[SpiceDB](https://github.com/authzed/spicedb), except for the fact that they\nneed to be written in JSON (sorry!). The JSON notation for schemas is based\non the `Schema` struct found in [./src/schema.rs](./src/schema.rs). You can\nsee some examples in the check tests found near the bottom of\n[./src/lib.rc](./src/lib.rs).\n\nIn the future it would be nice to write a DSL for schemas and a parser so\nthat we don't have to specify the schema using JSON. It would also be very\nnice if all the people who have written ReBAC implementations decided on a\nsingle DSL.\n\n### `pgfga.read_schema`\n\n```sql\npgfga=# SELECT * FROM pgfga.read_schema(id::uuid);\n rowid |                  id                  |       schema                       |          created_at           \n-------+--------------------------------------+------------------------------------+-------------------------------\n     1 | 35777d4d-3b66-47e5-907b-191b682b92c4 | {\"namespaces\":{\"document\":{...}}}\" | 2023-09-17 09:40:00.897494-07\n(1 row)\n```\n\nRead the schema corresponding to the given id.\n\n### `pgfga.read_schemas`\n\n```sql\npgfga=# SELECT * FROM pgfga.read_schemas();\n rowid |                  id                  |       schema                       |          created_at           \n-------+--------------------------------------+------------------------------------+-------------------------------\n     1 | 35777d4d-3b66-47e5-907b-191b682b92c4 | {\"namespaces\":{\"document\":{...}}}\" | 2023-09-17 09:40:00.897494-07\n     2 | 3fd56696-29c5-47d7-8d6d-5b95405b9169 | {\"namespaces\":{\"folder\":{...}}}\"   | 2023-09-17 09:45:11.504819-07\n(1 row)\n```\n\nRead all the schemas.\n\n### `pgfga.create_tuple`\n\n```sql\npgfga=# SELECT * FROM pgfga.create_tuple(\n    schema_id::uuid,\n    resource_namespace::varchar(128),\n    resource_id::varchar(128),\n    relation::varchar(128),\n    subject_namespace::varchar(128),\n    subject_id::varchar(128),\n    subject_action::varchar(128) default '',\n);\n create_tuple \n--------------\n            1\n(1 row)\n```\n\nCreate a tuple. It returns the number of tuples created.\n\n### `pgfga.read_tuples`\n\n```sql\npgfga=# SELECT * FROM pgfga.read_tuples(\n    schema_id::uuid,\n    resource_namespace::varchar(128),\n    resource_id::varchar(128),\n    relation::varchar(128),\n    subject_namespace::varchar(128),\n    subject_id::varchar(128),\n    subject_action::varchar(128) default '',\n);\n rowid | schema_id | resource_namespace | resource_id | relation | subject_namespace | subject_id | subject_action \n-------+-----------+--------------------+-------------+----------+-------------------+------------+----------------\n...\n(n rows)\n```\n\n`pgfga.read_tuples` acts a filter. Empty strings will match everything. This\nfunction will return all tuples that match the filter.\n\n#### Examples\n\n1. Read all tuples within a given `schema_id`:\n\n   ```sql\n   SELECT * FROM pgfga.read_tuples(schema_id, '', '', '', '', '');\n   ```\n\n### `pgfga.delete_tuple`\n\n```sql\npgfga=# SELECT * FROM pgfga.delete_tuple(\n    schema_id::uuid,\n    resource_namespace::varchar(128),\n    resource_id::varchar(128),\n    relation::varchar(128),\n    subject_namespace::varchar(128),\n    subject_id::varchar(128),\n    subject_action::varchar(128) default '',\n);\n delete_tuple \n--------------\n            1\n(1 row)\n```\n\nDelete the given tuple. It returns the number of tuples deleted.\n\n### `pgfga.check`\n\n```sql\npgfga=# SELECT * FROM pgfga.check(\n    schema_id::uuid,\n    resource_namespace::varchar(128),\n    resource_id::varchar(128),\n    relation::varchar(128),\n    subject_namespace::varchar(128),\n    subject_id::varchar(128),\n    subject_action::varchar(128) default ''\n);\n check \n-------\n t\n(1 row)\n```\n\nCheck if the `subject` has the `relation` with the `resource`.\n\n## Roadmap\n\n- Check tests\n- Schema documentation\n- Add the proper indices\n- Client library to make this easier to use\n- Return iterators (and not vectors) in the storage module\n- Validate those tuples against the schema before persisting\n- Create many tuples function\n- Delete many tuples function\n- Function signatures are out of control. Do I need more structs or type\n  aliases?\n- ?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcraigpastro%2Fpgfga","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcraigpastro%2Fpgfga","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcraigpastro%2Fpgfga/lists"}