{"id":13600280,"url":"https://github.com/casbin/gorm-adapter","last_synced_at":"2026-01-20T18:44:02.181Z","repository":{"id":38190856,"uuid":"98703066","full_name":"casbin/gorm-adapter","owner":"casbin","description":"GORM adapter for Casbin, see extended version of GORM Adapter Ex at: https://github.com/casbin/gorm-adapter-ex","archived":false,"fork":false,"pushed_at":"2025-12-12T14:52:15.000Z","size":217,"stargazers_count":734,"open_issues_count":0,"forks_count":217,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-12-14T06:13:00.271Z","etag":null,"topics":["abac","access-control","acl","adapter","auth","authorization","authz","casbin","go","golang","gorm","orm","rbac","storage-driver"],"latest_commit_sha":null,"homepage":"https://github.com/casbin/casbin","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/casbin.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"casbin"}},"created_at":"2017-07-29T02:34:31.000Z","updated_at":"2025-12-12T14:50:32.000Z","dependencies_parsed_at":"2023-02-18T23:15:27.473Z","dependency_job_id":"d58421fe-ee83-4e71-bbc9-60cbc001d596","html_url":"https://github.com/casbin/gorm-adapter","commit_stats":{"total_commits":120,"total_committers":56,"mean_commits":2.142857142857143,"dds":0.8083333333333333,"last_synced_commit":"3d3a3c755df913a52c7077694c4b33f175a37894"},"previous_names":[],"tags_count":86,"template":false,"template_full_name":null,"purl":"pkg:github/casbin/gorm-adapter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casbin%2Fgorm-adapter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casbin%2Fgorm-adapter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casbin%2Fgorm-adapter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casbin%2Fgorm-adapter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/casbin","download_url":"https://codeload.github.com/casbin/gorm-adapter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casbin%2Fgorm-adapter/sbom","scorecard":{"id":267044,"data":{"date":"2025-08-11","repo":{"name":"github.com/casbin/gorm-adapter","commit":"0ebaa028637edce9f9b5a654795caa96800aba40"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.9,"checks":[{"name":"Maintained","score":6,"reason":"4 commit(s) and 4 issue activity found in the last 90 days -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","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":"Code-Review","score":8,"reason":"Found 26/30 approved changesets -- score normalized to 8","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":"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":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/casbin/gorm-adapter/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/casbin/gorm-adapter/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/casbin/gorm-adapter/ci.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/ci.yml:66","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 npmCommand dependencies pinned"],"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"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":"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":"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":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: 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":"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":"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":"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":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/ci.yml:56"],"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":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2024-3321 / GHSA-v778-237x-gjrc","Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 27 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"}}]},"last_synced_at":"2025-08-17T12:21:26.046Z","repository_id":38190856,"created_at":"2025-08-17T12:21:26.046Z","updated_at":"2025-08-17T12:21:26.046Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28609157,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T16:10:39.856Z","status":"ssl_error","status_checked_at":"2026-01-20T16:10:39.493Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["abac","access-control","acl","adapter","auth","authorization","authz","casbin","go","golang","gorm","orm","rbac","storage-driver"],"created_at":"2024-08-01T18:00:34.405Z","updated_at":"2026-01-20T18:43:57.156Z","avatar_url":"https://github.com/casbin.png","language":"Go","funding_links":["https://github.com/sponsors/casbin"],"categories":["Go"],"sub_categories":[],"readme":"Gorm Adapter\n====\n\n\u003e In v3.0.3, method `NewAdapterByDB` creates table named `casbin_rules`,  \n\u003e we fix it to `casbin_rule` after that.  \n\u003e If you used v3.0.3 and less, and you want to update it,  \n\u003e you might need to *migrate* data manually.\n\u003e Find out more at: https://github.com/casbin/gorm-adapter/issues/78\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/casbin/gorm-adapter)](https://goreportcard.com/report/github.com/casbin/gorm-adapter)\n[![Go](https://github.com/casbin/gorm-adapter/actions/workflows/ci.yml/badge.svg)](https://github.com/casbin/gorm-adapter/actions/workflows/ci.yml)\n[![Coverage Status](https://coveralls.io/repos/github/casbin/gorm-adapter/badge.svg?branch=master)](https://coveralls.io/github/casbin/gorm-adapter?branch=master)\n[![Godoc](https://godoc.org/github.com/casbin/gorm-adapter?status.svg)](https://godoc.org/github.com/casbin/gorm-adapter)\n[![Release](https://img.shields.io/github/release/casbin/gorm-adapter.svg)](https://github.com/casbin/gorm-adapter/releases/latest)\n[![Discord](https://img.shields.io/discord/1022748306096537660?logo=discord\u0026label=discord\u0026color=5865F2)](https://discord.gg/S5UjpzGZjN)\n[![Sourcegraph](https://sourcegraph.com/github.com/casbin/gorm-adapter/-/badge.svg)](https://sourcegraph.com/github.com/casbin/gorm-adapter?badge)\n\nGorm Adapter is the [Gorm](https://gorm.io/gorm) adapter for [Casbin](https://github.com/casbin/casbin). With this library, Casbin can load policy from Gorm supported database or save policy to it.\n\nBased on [Officially Supported Databases](https://v1.gorm.io/docs/connecting_to_the_database.html#Supported-Databases), The current supported databases are:\n\n- MySQL\n- PostgreSQL\n- SQL Server\n- Sqlite3\n\u003e gorm-adapter use ``github.com/glebarez/sqlite`` instead of gorm official sqlite driver ``gorm.io/driver/sqlite`` because the latter needs ``cgo`` support. But there is almost no difference between the two driver. If there is a difference in use, please submit an issue.\n\n- other 3rd-party supported DBs in Gorm website or other places.\n\n## Installation\n\n    go get github.com/casbin/gorm-adapter/v3\n\n## Simple Example\n\n```go\npackage main\n\nimport (\n\t\"github.com/casbin/casbin/v2\"\n\tgormadapter \"github.com/casbin/gorm-adapter/v3\"\n\t_ \"github.com/go-sql-driver/mysql\"\n)\n\nfunc main() {\n\t// Initialize a Gorm adapter and use it in a Casbin enforcer:\n\t// The adapter will use the MySQL database named \"casbin\".\n\t// If it doesn't exist, the adapter will create it automatically.\n\t// You can also use an already existing gorm instance with gormadapter.NewAdapterByDB(gormInstance)\n\ta, _ := gormadapter.NewAdapter(\"mysql\", \"mysql_username:mysql_password@tcp(127.0.0.1:3306)/\") // Your driver and data source.\n\te, _ := casbin.NewEnforcer(\"examples/rbac_model.conf\", a)\n\t\n\t// Or you can use an existing DB \"abc\" like this:\n\t// The adapter will use the table named \"casbin_rule\".\n\t// If it doesn't exist, the adapter will create it automatically.\n\t// a := gormadapter.NewAdapter(\"mysql\", \"mysql_username:mysql_password@tcp(127.0.0.1:3306)/abc\", true)\n\n\t// Load the policy from DB.\n\te.LoadPolicy()\n\t\n\t// Check the permission.\n\te.Enforce(\"alice\", \"data1\", \"read\")\n\t\n\t// Modify the policy.\n\t// e.AddPolicy(...)\n\t// e.RemovePolicy(...)\n\t\n\t// Save the policy back to DB.\n\te.SavePolicy()\n}\n```\n## Turn off AutoMigrate\nNew an adapter will use ``AutoMigrate`` by default for create table, if you want to turn it off, please use API ``TurnOffAutoMigrate(db *gorm.DB) *gorm.DB``. See example: \n```go\ndb, err := gorm.Open(mysql.Open(\"root:@tcp(127.0.0.1:3306)/casbin\"), \u0026gorm.Config{})\nTurnOffAutoMigrate(db)\n// a,_ := NewAdapterByDB(...)\n// a,_ := NewAdapterByDBUseTableName(...)\na,_ := NewAdapterByDBWithCustomTable(...)\n```\nFind out more details at [gorm-adapter#162](https://github.com/casbin/gorm-adapter/issues/162)\n## Customize table columns example\nYou can change the gorm struct tags, but the table structure must stay the same.\n```go\npackage main\n\nimport (\n\t\"github.com/casbin/casbin/v2\"\n\tgormadapter \"github.com/casbin/gorm-adapter/v3\"\n\t\"gorm.io/gorm\"\n)\n\nfunc main() {\n\t// Increase the column size to 512.\n\ttype CasbinRule struct {\n\t\tID    uint   `gorm:\"primaryKey;autoIncrement\"`\n\t\tPtype string `gorm:\"size:512;uniqueIndex:unique_index\"`\n\t\tV0    string `gorm:\"size:512;uniqueIndex:unique_index\"`\n\t\tV1    string `gorm:\"size:512;uniqueIndex:unique_index\"`\n\t\tV2    string `gorm:\"size:512;uniqueIndex:unique_index\"`\n\t\tV3    string `gorm:\"size:512;uniqueIndex:unique_index\"`\n\t\tV4    string `gorm:\"size:512;uniqueIndex:unique_index\"`\n\t\tV5    string `gorm:\"size:512;uniqueIndex:unique_index\"`\n\t}\n\n\tdb, _ := gorm.Open(...)\n\n\t// Initialize a Gorm adapter and use it in a Casbin enforcer:\n\t// The adapter will use an existing gorm.DB instnace.\n\ta, _ := gormadapter.NewAdapterByDBWithCustomTable(db, \u0026CasbinRule{}) \n\te, _ := casbin.NewEnforcer(\"examples/rbac_model.conf\", a)\n\t\n\t// Load the policy from DB.\n\te.LoadPolicy()\n\t\n\t// Check the permission.\n\te.Enforce(\"alice\", \"data1\", \"read\")\n\t\n\t// Modify the policy.\n\t// e.AddPolicy(...)\n\t// e.RemovePolicy(...)\n\t\n\t// Save the policy back to DB.\n\te.SavePolicy()\n}\n```\n## Transaction\nYou can modify policies within a transaction.See example:\n```go\npackage main\n\nfunc main() {\n\ta, err := NewAdapterByDB(db)\n\te, _ := casbin.NewEnforcer(\"examples/rbac_model.conf\", a)\n\terr = e.GetAdapter().(*Adapter).Transaction(e, func(e casbin.IEnforcer) error {\n\t\t_, err := e.AddPolicy(\"jack\", \"data1\", \"write\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = e.AddPolicy(\"jack\", \"data2\", \"write\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\t// handle if transaction failed\n\t\treturn\n\t}\n}\n```\n## ConditionsToGormQuery\n\n`ConditionsToGormQuery()` is a function that converts multiple query conditions into a GORM query statement\nYou can use the `GetAllowedObjectConditions()` API of Casbin to get conditions,\nand choose the way of combining conditions through `combineType`.\n\n`ConditionsToGormQuery()` allows Casbin to be combined with SQL, and you can use it to implement many functions.\n### Example: GetAllowedRecordsForUser\n* model example: [object_conditions_model.conf](examples/object_conditions_model.conf)\n* policy example: [object_conditions_policy.csv](examples/object_conditions_policy.csv)\n\nDataBase example:\n\n|id|title|author|publisher|publish_data|price|category_id|\n|--|--|--|--|--|--|--|\n|1|book1|author1|publisher1|2023-04-09 16:23:42|10|1|\n|2|book2|author1|publisher1|2023-04-09 16:23:44|20|2|\n|3|book3|author2|publisher1|2023-04-09 16:23:44|30|1|\n|4|book4|author2|publisher2|2023-04-09 16:23:45|10|3|\n|5|book5|author3|publisher2|2023-04-09 16:23:45|50|1|\n|6|book6|author3|publisher2|2023-04-09 16:23:46|60|2|\n\n\n```go\ntype Book struct {\n    ID          int\n    Title       string\n    Author      string\n    Publisher   string\n    PublishDate time.Time\n    Price       float64\n    CategoryID  int\n}\n\nfunc TestGetAllowedRecordsForUser(t *testing.T) {\n\te, _ := casbin.NewEnforcer(\"examples/object_conditions_model.conf\", \"examples/object_conditions_policy.csv\")\n\n\tconditions, err := e.GetAllowedObjectConditions(\"alice\", \"read\", \"r.obj.\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(conditions)\n\n\tdsn := \"root:root@tcp(127.0.0.1:3307)/test?charset=utf8mb4\u0026parseTime=True\u0026loc=Local\"\n\tdb, err := gorm.Open(mysql.Open(dsn), \u0026gorm.Config{})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(\"CombineTypeOr\")\n\trows, err := ConditionsToGormQuery(db, conditions, CombineTypeOr).Model(\u0026Book{}).Rows()\n\tdefer rows.Close()\n\tvar b Book\n\tfor rows.Next() {\n\t\terr := db.ScanRows(rows, \u0026b)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tlog.Println(b)\n\t}\n\n\tfmt.Println(\"CombineTypeAnd\")\n\trows, err = ConditionsToGormQuery(db, conditions, CombineTypeAnd).Model(\u0026Book{}).Rows()\n\tdefer rows.Close()\n\tfor rows.Next() {\n\t\terr := db.ScanRows(rows, \u0026b)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tlog.Println(b)\n\t}\n}\n```\n\n## Context Adapter\n\n`gormadapter` supports adapter with context, the following is a timeout control implemented using context\n\n```go\na, _ := gormadapter.NewAdapter(\"mysql\", \"mysql_username:mysql_password@tcp(127.0.0.1:3306)/\") // Your driver and data source.\n// Limited time 300s\nctx, cancel := context.WithTimeout(context.Background(), 300*time.Microsecond)\ndefer cancel()\nerr := a.AddPolicyCtx(ctx, \"p\", \"p\", []string{\"alice\", \"data1\", \"read\"})\nif err != nil {\n    panic(err)\n}\n```\n\n## Getting Help\n\n- [Casbin](https://github.com/casbin/casbin)\n\n## License\n\nThis project is under Apache 2.0 License. See the [LICENSE](LICENSE) file for the full license text.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcasbin%2Fgorm-adapter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcasbin%2Fgorm-adapter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcasbin%2Fgorm-adapter/lists"}