Conversation
…ermission scans
Adds 'forge rbac sync' which AST-scans every .go file under the
module root for RequirePermission(code, …) and RequireAnyPermission(
[]string{code, code, …}, …) middleware references and upserts the
discovered codes into the permissions table.
The point: eliminate 'permission drift' where a route enforces a
code the database has never heard of (or vice versa). Run it as
part of the CI/CD pipeline after migrations complete.
Resource and action columns are derived from the first dot-segment /
remainder convention (orders.refund -> resource=orders, action=refund).
Descriptions are left empty so human-curated descriptions added in
the admin UI are never overwritten - the upsert uses
ON CONFLICT (code) DO NOTHING.
Subcommands:
forge rbac sync # apply to GOFORGE_DATABASE_DSN
forge rbac sync --dry-run # diff without writing
forge rbac sync --print-only # only list discovered codes
forge rbac sync --root ./api # scan a different module
Skips vendor/, node_modules/, dot-prefixed dirs. Tolerates single-
file parse errors so broken generator output doesn't abort the scan.
go test -race ./cmd/forge/... clean; golangci-lint clean. Local run
on the framework itself discovers menu.manage and rbac.manage from
internal/infrastructure/server/router.go.
Co-Authored-By: dede febriansyah <febriansyahd65@gmail.com>
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
forge rbac sync— a static-analysis pass that scans every.gofile under the module forRequirePermission(code, …)andRequireAnyPermission([]string{code, code, …}, …)middleware references and upserts the discovered codes into thepermissionstable. Eliminates the "permission drift" failure mode where a route enforces a code the database has never heard of (or vice versa).Why
Tier-A #2 from the framework-improvement plan. Today, when a developer adds
middleware.RequirePermission("orders.refund", …)to a new route, they also have to remember to insert a matching row intopermissionsand grant it to the appropriate role(s). When they forget, the route silently 403s for everyone. The reverse happens too — codes get added to the DB and never enforced anywhere. A boot-time auto-registry collapses both classes into "didforge rbac syncrun after deploy?" — easy to put in CI.How
cmd/forge/rbac.go— AST scanner usinggo/parser+go/astextracts string literals from the first argument ofRequirePermissioncalls and from the elements of the slice literal passed toRequireAnyPermission. Tolerates parse errors on individual files (broken generator output won't abort the scan). Skipsvendor/,node_modules/, dot-prefixed directories. Handles bothpkg.RequirePermission(...)and bareRequirePermission(...)(after dot-import).<resource>.<action>convention (orders.refund→resource=orders,action=refund). For codes without a dot, action is empty.ON CONFLICT (code) DO NOTHINGso re-runs are safe and human-curated descriptions added in the admin UI are never overwritten.cmd/forge/main.go—rbacregistered alongsidedoctor,gen,migrate, etc.cmd/forge/rbac_test.go— synthetic Go fixtures covering both middleware forms, vendor skipping, test-file inclusion, bare-ident calls, plussplitCodetable.Subcommands:
Local run on the framework itself discovers
menu.manageandrbac.managefrom the router.Test plan
make lintclean (golangci-lint run ./...)make testclean (go test -race ./cmd/forge/...)go run ./cmd/forge rbac sync --print-onlyprints the two codes currently enforcedRisk
permissions, never touchesrole_permissions, and never overwrites descriptions. Worst case: a removedRequirePermissionleaves an orphan row (harmless). A--pruneflag can be added later if that becomes annoying.RequirePermission(somevar, …)) are silently ignored. Framework convention is to always pass a string literal so this is a fine policy.Checklist
fmt.Printlnleft behindLink to Devin session: https://app.devin.ai/sessions/8fdfc20358514c97a766adca630a2527
Requested by: @dedeez14