{"record":{"id":"02b52859f5101743","repo":"amir20/dozzle","slug":"forbidden","errorCode":null,"errorMessage":"Forbidden","messagePattern":"Forbidden","errorType":"http","errorClass":null,"httpStatus":403,"severity":"warning","filePath":"internal/web/actions.go","lineNumber":29,"sourceCode":"\t\"github.com/rs/zerolog/log\"\n)\n\nfunc (h *handler) findContainerWithActions(w http.ResponseWriter, r *http.Request) (*container_support.ContainerService, bool) {\n\tid := chi.URLParam(r, \"id\")\n\n\tuserLabels := h.config.Labels\n\tpermit := true\n\tif h.config.Authorization.Provider != NONE {\n\t\tuser := auth.UserFromContext(r.Context())\n\t\tif user.ContainerLabels.Exists() {\n\t\t\tuserLabels = user.ContainerLabels\n\t\t}\n\t\tpermit = user.Roles.Has(auth.Actions)\n\t}\n\n\tif !permit {\n\t\tlog.Warn().Msg(\"user is not permitted to perform actions on container\")\n\t\thttp.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)\n\t\treturn nil, false\n\t}\n\n\tcontainerService, err := h.hostService.FindContainer(hostKey(r), id, userLabels)\n\tif err != nil {\n\t\tlog.Error().Err(err).Msg(\"error while trying to find container\")\n\t\thttp.Error(w, err.Error(), http.StatusNotFound)\n\t\treturn nil, false\n\t}\n\n\treturn containerService, true\n}\n\nfunc (h *handler) containerActions(w http.ResponseWriter, r *http.Request) {\n\taction := chi.URLParam(r, \"action\")\n\n\tcontainerService, ok := h.findContainerWithActions(w, r)\n\tif !ok {","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/web/actions.go#L11-L47","documentation":"findContainerWithActions enforces that the authenticated user has the Actions role (or is admin) before performing start/stop/restart/update on a container. Without the role the handler logs a warning and returns 403 Forbidden.","triggerScenarios":"POST /api/hosts/{host}/containers/{id}/actions/{action} or /update by a user whose roles lack auth.Actions; non-admin users in simple auth; forward-proxy setups mapping the user to a read-only role.","commonSituations":"Users file configured without the actions role in users.yml; proxy header omitting roles so defaults exclude Actions; orgs restricting destructive actions deliberately.","solutions":["Grant the user the actions role (admin level or explicit role in users.yml / proxy role header)","Perform the action as an admin user","If restriction is intentional, perform start/stop/restart with docker CLI instead","Verify the proxy is forwarding the roles header if using forward auth"],"exampleFix":"# before (users.yml)\nadmin: {email: admin@example.com, password: \"...\"}\n# after\nadmin: {email: admin@example.com, password: \"...\", name: admin, roles: [admin]}","handlingStrategy":"validation","validationCode":"const me = await (await fetch('/api/user', {credentials:'include'})).json();\nconst canAct = me.roles?.includes('admin') || me.roles?.includes('actions');\nif (!canAct) console.warn('user lacks container action permissions');","typeGuard":null,"tryCatchPattern":"const res = await fetch(actionUrl, {method: 'POST', credentials: 'include'});\nif (res.status === 403) {\n  showError('Your account is not allowed to control containers');\n}","preventionTips":["Grant the actions/admin role to users who need start/stop/restart","Verify the proxy forwards the roles header in forward-auth setups","Check permissions before rendering action buttons in custom UIs"],"tags":["auth","forbidden","rbac","container-actions"],"backgroundTag":"permission-denied","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}