{"id":28028391,"url":"https://github.com/permitio/permit-java-example","last_synced_at":"2025-09-13T08:50:50.706Z","repository":{"id":228344155,"uuid":"761921388","full_name":"permitio/permit-java-example","owner":"permitio","description":"A simple blog application that implements authorization using Permit.io.","archived":false,"fork":false,"pushed_at":"2024-03-18T08:34:44.000Z","size":87,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-09-05T22:02:27.796Z","etag":null,"topics":["example"],"latest_commit_sha":null,"homepage":"","language":"Java","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/permitio.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}},"created_at":"2024-02-22T18:30:30.000Z","updated_at":"2025-04-26T01:28:31.000Z","dependencies_parsed_at":"2024-03-18T11:01:17.543Z","dependency_job_id":"d8ba8e47-02c1-4374-9b42-e3f3504e539c","html_url":"https://github.com/permitio/permit-java-example","commit_stats":null,"previous_names":["permitio/permit-java-example"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/permitio/permit-java-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/permitio%2Fpermit-java-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/permitio%2Fpermit-java-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/permitio%2Fpermit-java-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/permitio%2Fpermit-java-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/permitio","download_url":"https://codeload.github.com/permitio/permit-java-example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/permitio%2Fpermit-java-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274942145,"owners_count":25378207,"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","status":"online","status_checked_at":"2025-09-13T02:00:10.085Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["example"],"created_at":"2025-05-11T07:13:01.444Z","updated_at":"2025-09-13T08:50:50.685Z","avatar_url":"https://github.com/permitio.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Blog Application with Permit.io Authorization\n\nThis example project showcases a simple blog application that implements authorization using permit.io.\n\n## Features\n\n- **User Authentication**: Users can log in to the application using their credentials.\n- **Blog Management**: Authenticated users can create new blog posts, read existing posts, update their posts, and\n  delete them, subject to their authorization level.\n- **Authorization with permit.io**: The application uses permit.io to manage user roles and permissions, ensuring that\n  access to certain actions (like updating or deleting a blog post) is appropriately restricted.\n- **Role-Based Access Control**: Defines different roles for users, such as viewer, editor, and admin, each with varying\n  levels of access and permissions.\n\n## Getting Started\n\nThese instructions will get you a copy of the project up and running on your local machine for development and testing\npurposes.\n\n### Prerequisites\n\nBefore you begin, ensure you have the following installed:\n\n- Java JDK 21\n- Gradle\n- Docker (optional, for running Permit.io PDP locally)\n- Terraform (optional, for setting up Permit.io resources)\n\n### 1. Setting Up Permit.io using Terraform\n\nLogin to your Permit.io account and create a new project in your workspace and copy your API key.\nSet the `PERMIT_API_KEY` environment variable to your API key:\n\n```shell\nexport PERMIT_API_KEY=\u003cYOUR_API_KEY\u003e\n```\nThen run the following commands to create the resources in your Permit.io project:\n```shell\nterraform init\nterraform plan\nterraform apply\n```\n\nYou should see under the Policy Editor a \"Blog\" and \"Owned Blog\" resources, and the roles `viewer`, `editor`, and `admin`.\n![image](https://github.com/permitio/permit-java-example/assets/12188774/d1fd9a57-aae0-42c1-a3e5-81e9af912b91)\n\n### 2. Starting your local PDP container\n\nThe PDP (Policy Decision Point) is the component of permit.io that evaluates access control decisions.\nYou can run a local PDP container using Docker:\n\n```shell\ndocker run -it -p 7766:7000 --env PDP_DEBUG=True --env PDP_API_KEY=\u003cYOUR_API_KEY\u003e permitio/pdp-v2:latest\n```\n\n\u003e You may use the Cloud PDP by modifying the `src/resources/application.yaml` config, setting the `permit.pdpUrl` property to https://cloudpdp.api.permit.io. \n\u003e It is not recommended as it does not support ABAC policies used in this project.\n\n### 3. Running the Application\n\nYou can run the application using the following Gradle command:\n\n```shell\n./gradlew bootRun\n```\n\nThen access the application Swagger at http://localhost:8080/swagger-ui/index.html.\n\n## Usage\n\nThe application contains a makeshift user authentication. Create a new user using the `/api/users/signup` endpoint:\n```shell\ncurl -X POST \"http://localhost:8080/api/users/signup\" -H \"Content-Type: application/json\" -d 'myuser'\n```\nYou should be able to view the user in your Permit.io project, under Directory \u003e All Tenants.\n\nInitially the user has no roles, therefor it cannot do much. For example, trying to list the blogs will result in a 403 Forbidden response:\n```shell\ncurl -X GET \"http://localhost:8080/api/blogs\" -H \"Authorization: Bearer myuser\"\n# 403 Forbidden\n```\nAssign the user with a `viewer` role using:\n```shell\ncurl -X POST \"http://localhost:8080/api/users/assign-role\" -H \"Authorization: Bearer myuser\" -d \"viewer\"\n```\n\nAlternatively, you can use the Swagger UI authorize with the username.\n\n### Example Usage\n\nThe application contains simple APIs for creating, reading, updating, and deleting blog and comment resources.\nHere is an example of how to use the application:\n\n#### 1. Reading Blogs\nWith your 'viewer' role, you can read the blogs. List all blogs using:\n```shell\ncurl -X GET \"http://localhost:8080/api/blogs\" -H \"Authorization: Bearer my-user\"\n```\nInitially, there are no blogs, so lets try to create one using:\n```shell\ncurl -X POST \"http://localhost:8080/api/blogs\" -H \"Authorization: Bearer my-user\" -H \"Content-Type: application/json\" -d 'This is my blog'\n# 403 Forbidden\n```\nTurns out viewers cannot create blogs. You can assign your user with an `editor` role using:\n```shell\ncurl -X POST \"http://localhost:8080/api/users/assign-role\" -H \"Authorization: Bearer my-user\" -d \"editor\"\n```\nThen you can create a blog using:\n```shell\ncurl -X POST \"http://localhost:8080/api/blogs\" -H \"Authorization: Bearer my-user\" -H \"Content-Type: application/json\" -d 'This is my blog'\n```\nNow you can read the blog using (assuming the blog ID is 1):\n```shell\ncurl -X GET \"http://localhost:8080/api/blogs/1\" -H \"Authorization: Bearer my-user\"\n```\n\n#### 2. Commenting on blogs\nLet's create another user and assign it with a `viewer` role:\n```shell\ncurl -X POST \"http://localhost:8080/api/users/signup\" -H \"Content-Type: application/json\" -d 'other-user'\ncurl -X POST \"http://localhost:8080/api/users/assign-role\" -H \"Authorization: Bearer myviewer\" -d \"viewer\"\n```\nNow, the user can comment our the blog using:\n```shell\ncurl -X POST \"http://localhost:8080/api/blogs/1/comments\" -H \"Authorization: Bearer other-user\" -H \"Content-Type: application/json\" -d 'This blog is not good!'\n```\nBut it wasn't enough, so it wanted to update the comment:\n```shell\ncurl -X POST \"http://localhost:8080/api/blogs/1/comments\" -H \"Authorization: Bearer other-user\" -H \"Content-Type: application/json\" -d 'This blog is awful!'\n```\nThe negative comment by `other-user` was not well received by `my-user`, so it wanted to change it:\n```shell\ncurl -X PUT \"http://localhost:8080/api/blogs/1/comments/1\" -H \"Authorization: Bearer my-user\" -H \"Content-Type: application/json\" -d 'This blog is great!'\n# 403 Forbidden\n```\nAlthough being the author of the blog, `my-user` cannot update other user's comments, but it can delete it:\n```shell\ncurl -X DELETE \"http://localhost:8080/api/blogs/1/comments/1\" -H \"Authorization: Bearer my-user\"\n```\nFeeling sorry, `other-user` left another comment:\n```shell\ncurl -X POST \"http://localhost:8080/api/blogs/1/comments\" -H \"Authorization: Bearer other-user\" -H \"Content-Type: application/json\" -d 'This blog is great!'\n```\nBut regretted it immediately and wanted to delete it:\n```shell\ncurl -X DELETE \"http://localhost:8080/api/blogs/1/comments/2\" -H \"Authorization: Bearer other-user\"\n```\n\n#### 3. Modifying Blogs\nWith the negative comments on it's blog, `my-user` wanted to update the blog:\n```shell\ncurl -X PUT \"http://localhost:8080/api/blogs/1\" -H \"Authorization: Bearer my-user\" -H \"Content-Type: application/json\" -d 'This is my updated blog'\n```\nBut it wasn't enough, eventually it decided to delete the blog:\n```shell\ncurl -X DELETE \"http://localhost:8080/api/blogs/1\" -H \"Authorization: Bearer my-user\"\n```\nThen, it created a new blog:\n```shell\ncurl -X POST \"http://localhost:8080/api/blogs\" -H \"Authorization: Bearer my-user\" -H \"Content-Type: application/json\" -d 'I dont like @other-user comments...'\n```\n\n#### 4. Admin Access\nPersonal blogs are not allowed in the application, so an admin user is needed to delete them.\nCreate an admin user and assign it with an `admin` role:\n```shell\ncurl -X POST \"http://localhost:8080/api/users/signup\" -H \"Content-Type: application/json\" -d 'admin-user'\ncurl -X POST \"http://localhost:8080/api/users/assign-role\" -H \"Authorization: Bearer admin-user\" -d \"admin\"\n```\nNow the admin can delete the blog using (assuming the blog ID is 2):\n```shell\ncurl -X DELETE \"http://localhost:8080/api/blogs/2\" -H \"Authorization: Bearer admin-user\"\n```\n\n## Testing\n\nThis example project contains integration tests that demonstrate the authorization flow using permit.io. \n\nYou can run all tests using the following Gradle command:\n```shell\n./gradlew test\n```\n\nFirst, the test suite create a viewer, editor and admin users, and assign them with the respective roles.\nThen, it asserts:\n* Unauthenticated users or unknown users cannot access the API.\n* Viewer can read blogs, but cannot create, update, or delete them. (RBAC)\n* Editor can read and create blogs, and can update or delete their own blogs. (ABAC)\n* Editor cannot update or delete other user's blogs. \n* Viewer can comment on blogs, and can update or delete their own comments. (ABAC)\n* Blog author (derives to be comment moderator) can delete comments on their own blogs. (ReBAC)\n* Admin can delete other user's blogs and comments.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpermitio%2Fpermit-java-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpermitio%2Fpermit-java-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpermitio%2Fpermit-java-example/lists"}