{"record":{"id":"192d4e307af36417","repo":"vxcontrol/pentagi","slug":"privilegesrequired","errorCode":"PrivilegesRequired","errorMessage":"privileges are not set","messagePattern":"privileges are not set","errorType":"http","errorClass":"HttpError","httpStatus":403,"severity":"error","filePath":"backend/pkg/server/auth/permissions.go","lineNumber":15,"sourceCode":"package auth\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\n\t\"pentagi/pkg/server/response\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc getPrms(c *gin.Context) ([]string, error) {\n\tprms := c.GetStringSlice(\"prm\")\n\tif len(prms) == 0 {\n\t\treturn nil, fmt.Errorf(\"privileges are not set\")\n\t}\n\treturn prms, nil\n}\n\nfunc PrivilegesRequired(privs ...string) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tif c.IsAborted() {\n\t\t\treturn\n\t\t}\n\n\t\tprms, err := getPrms(c)\n\t\tif err != nil {\n\t\t\tresponse.Error(c, response.ErrPrivilegesRequired, err)\n\t\t\tc.Abort()\n\t\t\treturn\n\t\t}\n\n\t\tfor _, priv := range privs {","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/server/auth/permissions.go#L1-L33","documentation":"getPrms reads the \"prm\" string-slice (privileges) that authentication middleware must set in the Gin context. If it is empty/absent, it returns \"privileges are not set\" with code PrivilegesRequired; PrivilegesRequired then aborts the request. It means the request reached an authorization guard without a preceding authentication step populating privileges.","triggerScenarios":"A route uses PrivilegesRequired(...) middleware but the auth middleware that calls c.Set(\"prm\", prms) (tryUserCookieAuthentication/tryProtoTokenAuthentication) did not run, failed silently, or the request bypassed it; calling an API without any credentials so no middleware set \"prm\".","commonSituations":"Route registered without the auth middleware before PrivilegesRequired; misconfigured reverse proxy stripping cookies/Authorization headers so auth fails but a later middleware chain still reaches the guard; tests invoking handlers without running auth middleware.","solutions":["Register the authentication middleware before PrivilegesRequired on the route group so \"prm\" is populated","Ensure the client sends valid credentials (session cookie or Bearer API token) with the request","Fix auth-middleware failures (see wrapped auth errors) that leave \"prm\" unset instead of aborting","In tests, run the auth middleware or set c.Set(\"prm\", ...) before exercising guarded handlers"],"exampleFix":"// before\napi.POST(\"/flows\", PrivilegesRequired(\"flows_create\"), createFlow)\n// after\napi.POST(\"/flows\", authMiddleware(), PrivilegesRequired(\"flows_create\"), createFlow)","handlingStrategy":"validation","validationCode":null,"typeGuard":"func hasPrivileges(c *gin.Context) bool {\n    return len(c.GetStringSlice(\"prm\")) > 0\n}","tryCatchPattern":null,"preventionTips":["Always register authentication middleware before PrivilegesRequired in route groups","Ensure clients always send credentials (cookie or Bearer token) with guarded requests","In tests, seed the context (c.Set(\"prm\", ...)) or run the auth middleware before guards","Verify reverse proxies do not strip Authorization headers/Cookies en route to the API"],"tags":["authentication","authorization","middleware"],"backgroundTag":"missing-auth-context","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}