{"id":37027876,"url":"https://github.com/encryptorcode/spring-permissions","last_synced_at":"2026-01-14T03:19:10.894Z","repository":{"id":48666404,"uuid":"277316022","full_name":"encryptorcode/spring-permissions","owner":"encryptorcode","description":"Move all your validations out of your business logic.","archived":false,"fork":false,"pushed_at":"2021-07-15T06:04:44.000Z","size":45,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-17T18:47:21.360Z","etag":null,"topics":["permissions","spring","validation"],"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/encryptorcode.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}},"created_at":"2020-07-05T14:15:47.000Z","updated_at":"2021-05-29T16:53:15.000Z","dependencies_parsed_at":"2022-09-26T22:11:17.429Z","dependency_job_id":null,"html_url":"https://github.com/encryptorcode/spring-permissions","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/encryptorcode/spring-permissions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/encryptorcode%2Fspring-permissions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/encryptorcode%2Fspring-permissions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/encryptorcode%2Fspring-permissions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/encryptorcode%2Fspring-permissions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/encryptorcode","download_url":"https://codeload.github.com/encryptorcode/spring-permissions/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/encryptorcode%2Fspring-permissions/sbom","scorecard":{"id":376721,"data":{"date":"2025-08-11","repo":{"name":"github.com/encryptorcode/spring-permissions","commit":"248ae6d3055300e60f48624f8c0c72a2aa07da43"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/4 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 10 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"22 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-4jrv-ppp4-jm57","Warn: Project is vulnerable to: GHSA-78wr-2p64-hpwj","Warn: Project is vulnerable to: GHSA-3vqj-43w4-2q58","Warn: Project is vulnerable to: GHSA-4jq9-2xhw-jpx7","Warn: Project is vulnerable to: GHSA-36p3-wjmg-h94x","Warn: Project is vulnerable to: GHSA-hh26-6xwr-ggv7","Warn: Project is vulnerable to: GHSA-4gc7-5j7h-4qph","Warn: Project is vulnerable to: GHSA-4wp7-92pw-q264","Warn: Project is vulnerable to: GHSA-g5mm-vmx4-3rg7","Warn: Project is vulnerable to: GHSA-6gf2-pvqw-37ph","Warn: Project is vulnerable to: GHSA-rfmp-97jj-h8m6","Warn: Project is vulnerable to: GHSA-558x-2xjg-6232","Warn: Project is vulnerable to: GHSA-564r-hj7v-mcr5","Warn: Project is vulnerable to: GHSA-9cmq-m9j5-mvww","Warn: Project is vulnerable to: GHSA-wxqc-pxw9-g2p8","Warn: Project is vulnerable to: GHSA-2rmj-mq67-h97g","Warn: Project is vulnerable to: GHSA-2wrp-6fg6-hmc5","Warn: Project is vulnerable to: GHSA-4wrc-f8pq-fpqp","Warn: Project is vulnerable to: GHSA-ccgv-vj62-xf9h","Warn: Project is vulnerable to: GHSA-gfwj-fwqj-fp3v","Warn: Project is vulnerable to: GHSA-hgjh-9rj2-g67j","Warn: Project is vulnerable to: GHSA-g5vr-rgqm-vf78"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T14:25:53.947Z","repository_id":48666404,"created_at":"2025-08-18T14:25:53.947Z","updated_at":"2025-08-18T14:25:53.947Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408824,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"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":["permissions","spring","validation"],"created_at":"2026-01-14T03:19:10.229Z","updated_at":"2026-01-14T03:19:10.889Z","avatar_url":"https://github.com/encryptorcode.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spring permissions\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.encryptorcode/spring-permissions.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.github.encryptorcode%22%20AND%20a:%22spring-permissions%22)\n[![License](https://img.shields.io/github/license/encryptorcode/spring-permissions)](https://github.com/encryptorcode/spring-permissions/blob/master/LICENSE)\n[![Maintainability](https://api.codeclimate.com/v1/badges/f9cc1dc193117fd7f834/maintainability)](https://codeclimate.com/github/encryptorcode/spring-permissions/maintainability)\n[![Dependabot](https://badgen.net/dependabot/encryptorcode/spring-permissions/277316022?icon=dependabot)](https://github.com/encryptorcode/spring-permissions)\n[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.encryptorcode/spring-permissions?server=https%3A%2F%2Foss.sonatype.org)](https://oss.sonatype.org/content/repositories/snapshots/io/github/encryptorcode/spring-permissions/)\n\n\u003e Move all your validations out of your business logic.\n\n## Installation\n#### Maven\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.encryptorcode\u003c/groupId\u003e\n    \u003cartifactId\u003espring-permissions\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n#### Groovy\n```groovy\nimplementation 'io.github.encryptorcode:spring-permissions:1.0.0'\n```\n\n#### Kotlin DSL\n```groovy\nimplementation(\"io.github.encryptorcode:spring-permissions:1.0.0\")\n```\n\n## Why?\nHave you ever wanted a way to separate huge piles of permission checks and validations out of your business layer ?\nHave you ever felt your method sizes are way too big, but you weren't able to do anything about it ?\nFor the answer both the above, Spring Permissions is a layer that will help you split your services into validation and actual logic by using simple annotations.\n\n## Usage\n### Adding permission checks to controller methods\n```java\n@Controller\nclass MyController{\n\n    @RequestMapping(path = \"/myapi\")\n    @Permission(id = \"my.permission.id\")\n    @ResponseBody\n    public String myApi(){\n        return \"You are valid user.\";\n    }\n}\n```\n\nAdding permissions to a controller is as easy adding an annotation to the controller method. \nJust add the @Permission annotation with the right permission id and permission handler method will be automatically invoked. \n\n### To register a permission handler\n```java\nimport io.github.encryptorcode.permissions.abstracts.PermissionHandler;\nimport io.github.encryptorcode.permissions.annotations.Handler;\n\nclass MyPermissionHandler extends PermissionHandler {\n    public MyPermissionHandler(Variables variables){\n        super(variables);\n    }\n    \n    @Handler(id = \"my.permission.id\")\n    public void myPermissionValidator() throws Exception {\n        if(some condition){\n            throw new Exception(\"Seems like you don't have permission to perform this operation\");\n        }\n    }\n}\n```\n\nYou need to follow certain rules when writing a permission handler\n1. You can define any number of classes and methods.\n2. All the classes should extend `PermissionHandler` class\n3. All the classes should have a constructor with just `Variables` param\n4. All the methods should be annotated with `@Handler` and permission id should be specified\n5. All the methods should be of public visibility and should return void\n\n### Setting up permission manager\n#### 1. Initialising Permission Manager.\n```java\nPermissionManager.init(\"your.app.package.name\");\n```\nMake sure you make this call immediately after your server starts. \n\u003e In case of tomcat you will want to register a listener and invoke this once the server is started.\n\n#### 2. Adding Interceptors and Resolvers.\n```java\nimport io.github.encryptorcode.permissions.service.PermissionInterceptor;\nimport io.github.encryptorcode.permissions.service.VariablesResolver;\n\n@EnableWebMvc\n@ComponentScan(basePackages = {\"your.app.package.name\"})\npublic class WebMvcConfig implements WebMvcConfigurer {\n\n    @Override\n    public void addInterceptors(InterceptorRegistry registry) {\n        registry.addInterceptor(getPermissionInterceptor());\n    }\n\n    @Override\n    public void addArgumentResolvers(List\u003cHandlerMethodArgumentResolver\u003e resolvers) {\n        resolvers.add(getPermissionVariableResolver());\n    }\n\n    @Bean\n    public PermissionInterceptor getPermissionInterceptor() {\n        return new PermissionInterceptor();\n    }\n\n    @Bean\n    public VariablesResolver getPermissionVariableResolver() {\n        return new VariablesResolver();\n    }\n}\n```\n\nWe need to register both `PermissionInterceptor` and `VariablesResolver` to spring. \nIf you are using springs with annotation based configurations you add those in your WebMvcConfigurer class as given in the above snippet.\n\n### [EXTRA] Passing data from permission handler to controller\nIn permission handler you can use the variables object provided from the constructor. \nSay for example you need to store the result of a db operation `dao.get(\"data\")` and pass the result of this to the controller, you can do the same as below. \n```java\ndata = variables.pipe(\"name\", () -\u003e dao.get(\"data\"));\n```\n\nThen in the controller method you can define an argument as below. This will automatically get the data you set using `variables.pipe()` in the permissions layer. \n```java\n    @HandlerVariable(\"name\") String data\n```\n\n#### `pipe(key, lambda)` method\nYou need to pass the key name and a lambda expression that returns the retrieved data.\nlambda expression will be automatically invoked and the result will be stored in the specified key and returned.\n**If this method is invoked with the same key again lambda expression WILL NOT be evaluated, so the existing data will be returned.**\nIf you need to forcefully execute the lambda function you may also invoke `pipeNew(key, lambda)` for the same.\n\n### [EXTRA] Passing data from controller to permission handler\nYou may define arguments for your permission handler methods and you have to set argument values in args param of @Permission annotation.\nSay for example, you need to pass 2 arguments the word `id` and request param value for `id` to permissions handler. You can do as follows.\n\n**In controller**\n```java\n@Permission(id = \"my.permission\", args = {\"id\", \"${param.id}\"})\n```\n\n**In permission handler**\n```java\n@Handler(id = \"my.permission\")\npublic void myPermission(String id, String idParam) throw Exception{\n    // your logic\n}\n```\n\n#### Supported templates\n* `${path.name}` → Path value taken from the url\n* `${query.name}` or `${param.name}` → Request param value\n* `${header.name}` → Header value\n* `${cookie.name}` → Cookie value\n\n## Example\nWe have made an example application for demo purposes, Feel free to clone this repository and run `mvn clean package cargo:run` inside the example folder.\nA few interesting files you might like to refer from the example folder:\n* [com.example.myshop.controllers.ProductsController](./example/src/main/java/com/example/myshop/controllers/ProductsController.java)\n* [com.example.myshop.permissions.ProductPermissions](./example/src/main/java/com/example/myshop/permissions/ProductPermissions.java)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fencryptorcode%2Fspring-permissions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fencryptorcode%2Fspring-permissions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fencryptorcode%2Fspring-permissions/lists"}