{"id":20120510,"url":"https://github.com/osohq/gitcloud","last_synced_at":"2025-05-06T14:33:01.415Z","repository":{"id":37837729,"uuid":"496807694","full_name":"osohq/gitcloud","owner":"osohq","description":"Example application using Oso Cloud","archived":false,"fork":false,"pushed_at":"2025-03-11T14:32:42.000Z","size":3799,"stargazers_count":14,"open_issues_count":0,"forks_count":5,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-09T14:04:11.859Z","etag":null,"topics":["authorization","authorization-service","nodejs","permissions","python","rbac","roles","roles-management","zanzibar"],"latest_commit_sha":null,"homepage":"https://www.osohq.com/docs","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/osohq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-05-27T00:03:26.000Z","updated_at":"2025-01-22T20:42:48.000Z","dependencies_parsed_at":"2024-01-13T01:50:37.863Z","dependency_job_id":"6a9656d6-b7ec-4ed7-b788-ae58ee6e16f5","html_url":"https://github.com/osohq/gitcloud","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/osohq%2Fgitcloud","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osohq%2Fgitcloud/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osohq%2Fgitcloud/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osohq%2Fgitcloud/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/osohq","download_url":"https://codeload.github.com/osohq/gitcloud/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252703467,"owners_count":21790891,"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":["authorization","authorization-service","nodejs","permissions","python","rbac","roles","roles-management","zanzibar"],"created_at":"2024-11-13T19:20:50.087Z","updated_at":"2025-05-06T14:33:00.944Z","avatar_url":"https://github.com/osohq.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GitCloud\n\nThis is an example application based on GitHub that's meant to model GitHub's\npermissions system. The app is implemented as multiple backend services (in the\n`services/` directory) that use Oso Cloud as a shared central authorization\nsystem and a React frontend (in the `frontend/` directory).\n\nThis application is built as an example for [Oso Cloud](https://osohq.com/docs/).\n\n## Backend services\n\n### GitClub (Python - SQLAlchemy - Flask)\n\nThis is an example application based on GitHub that's meant to model GitHub's\npermissions system. The app uses the [`oso-cloud`][pypi-oso-cloud] Python\nlibrary to model, manage, and enforce authorization.\n\n[pypi-oso-cloud]: https://pypi.org/project/oso-cloud/\n\nThe [Oso Cloud documentation][docs] is a good reference for more information on\nOso's [Python][docs-python] library.\n\n[docs]: https://osohq.com/docs/\n[docs-python]: https://osohq.com/docs/reference/client-apis/python\n\n### Jobs Service (Node.js - TypeORM - Express.js)\n\nThis is an example application based on GitHub Actions that's meant to model\nGitHub Actions's permissions system. The app uses the\n[`oso-cloud`][npm-oso-cloud] Node.js library to model, manage, and enforce\nauthorization.\n\n[npm-oso-cloud]: https://www.npmjs.com/package/oso-cloud\n\nThe [Oso Cloud documentation][docs] is a good reference for more information on\nOso's [Node.js][docs-node] library.\n\n[docs-node]: https://osohq.com/docs/reference/client-apis/node\n\n### Configuring your local environment\n\nInstall the `oso-cloud` CLI by following the instructions in the \n[Oso Cloud Quickstart](https://www.osohq.com/docs/tutorials/quickstart#adding-oso-cloud-to-your-application)\n\nYou can optionally set up your environment for local testing by running `make setup`\nfrom the root directory of the repository. This will do the following:\n\n* Install the appropriate version of the Oso Cloud [local development binary](https://www.osohq.com/docs/guides/develop/local-development) for your system.\n* Copy the pre-commit hook from the `scripts` directory to `.git/pre-commit` if one doesn't already exist there.\n    * This will automatically validate the syntax of `policy/authorization.polar` before committing it.\n\n### Running local policy tests\n\nIf you configured your environment for local testing above,\nthen you can run the policy tests locally by running the following command\nfrom the root directory of the repository:\n\n```\nOSO_AUTH=e_0123456789_12345_osotesttoken01xiIn make test-policy\n```\n\nThe `OSO_AUTH` variable is set to the local development API key as documented in the \n[Setup section](https://www.osohq.com/docs/guides/develop/local-development#setup) of the Local Development Guide.\nIt will only work against the local development binary.\n\nThis will:\n* start the local development binary\n* Run the policy tests in `policy/authorization.polar` against the local development binary\n### Running tests\n\nNOTE: ***running the test suite against an Oso Cloud instance will reset all\ndata in that instance.*** This ensures each test starts from a clean slate.\n\nTo run the test suite, which, again, *will reset data and perform many\nauthorization requests against the target Oso Cloud instance*, grab your API\nkey from https://ui.osohq.com/dashboard and export it as the `OSO_AUTH`\nenvironment variable.\n\n```console\n$ export OSO_AUTH=\"0123456789\"\n$ make test\n```\n\n### Running the services\n\nThe first time you run these services, you'll need to upload your policy:\n```console\nmake update-policy\n```\nYou only need to do this once. (If you make changes to the policy, you'll need to run it again.)\n\nRun GitClub in one terminal:\n\n```console\nmake -C services/gitclub\n```\n\nRun the Jobs Service in another terminal:\n\n```console\nmake -C services/jobs\n```\n\n### Running with Docker\n\nYou can run all the services at once, along with a Oso Cloud local development binary and Postgres instance, using Docker Compose:\n\n```\ndocker-compose up\n```\n\nThis repo's `docker-compose.yml` file starts the following services:\n\n1. GitClub on port 5000\n2. Jobs Service on port 5001\n3. Oso Cloud local development binary on port 8081\n4. Postgres on port 5432\n5. Next.js frontend on port 8000\n\nIf `docker-compose up` ran successfully, you should see the following output.\n\n```\nfrontend-1  | yarn run v1.22.19\nfrontend-1  | $ next start\nfrontend-1  | ready - started server on 0.0.0.0:8000, url: http://localhost:8000\n```\n\nIf this is your first time running `docker-compose up`, you will also need to seed your local Postgres database by running `make seed`.\n\n#### Docker Troubleshooting\n\nIf you run into the following error when running `docker-compose up`, run `ALTER TABLE users DROP CONSTRAINT IF EXISTS pg_type_typname_nsp_index;` to clean up the dangling unique constraint.\n\n```\npsycopg2.errors.UniqueViolation: duplicate key value violates unique constraint \"pg_type_typname_nsp_index\"\n```\n\nYou can run this code from Python using the following:\n\n```python\nwith engine.connect() as conn:\n    conn.execute('ALTER TABLE users DROP CONSTRAINT IF EXISTS pg_type_typname_nsp_index')\n```\n\n## Frontend\n\n### Running the frontend\n\n```console\n$ cd frontend\n$ yarn\n$ yarn start\n```\n\n### Architecture\n\n- TypeScript / React / Reach Router\n\n## Development\n\nThe GitClub service runs on port 5000; the Jobs service runs on port 5001.\nThe frontend knows to make requests to 5001 for Jobs and 5000 for everything\nelse. In a real production scenario, these disparate backend APIs would\nprobably be abstracted behind an API gateway or similar.\n\nThe GitClub service uses cookies to manage sessions. The Jobs service looks\nfor a special `x-user-id` header that contains the logged-in user's super secret\ntoken... which is also their ID... which is also their email. In a production\nscenario, the authentication system should be a lot more secure. It doesn't\nreally matter for our purposes, where we really only care about showing off\nauthorization might.\n\nIf you want to be able to debug/test the backend without running the frontend\nand logging in, you can use the following to save a session locally:\n\n### Save the cookies\n\n```bash\ncurl -c gitclub.cookies -H \"Content-Type: application/json\" -X POST -d '{\"username\": \"john@beatles.com\"}' localhost:5000/session\n```\n\n### Use the cookies\n\n```bash\ncurl -b gitclub.cookies localhost:5000/orgs/1\n```\n\n## FAQ\n\n### I'm getting \"Failed to fetch\" CORS errors on Mac\n\nTry [disabling Airplay](https://developer.apple.com/forums/thread/693768), Airplay can intercept requests to `localhost:5000`.\nIn the Chrome console, check the \"server\" response header on a failed request: if the \"server\" response header includes \"Airplay\", then Airplay is the culprit.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosohq%2Fgitcloud","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fosohq%2Fgitcloud","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosohq%2Fgitcloud/lists"}