{"record":{"id":"a3df298b4c1c460d","repo":"micro/go-micro","slug":"errforbidden","errorCode":"ErrForbidden","errorMessage":"resource forbidden","messagePattern":"resource forbidden","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"auth/auth.go","lineNumber":23,"sourceCode":"\t\"context\"\n\t\"errors\"\n\t\"time\"\n)\n\nconst (\n\t// BearerScheme used for Authorization header.\n\tBearerScheme = \"Bearer \"\n\t// ScopePublic is the scope applied to a rule to allow access to the public.\n\tScopePublic = \"\"\n\t// ScopeAccount is the scope applied to a rule to limit to users with any valid account.\n\tScopeAccount = \"*\"\n)\n\nvar (\n\t// ErrInvalidToken is when the token provided is not valid.\n\tErrInvalidToken = errors.New(\"invalid token provided\")\n\t// ErrForbidden is when a user does not have the necessary scope to access a resource.\n\tErrForbidden = errors.New(\"resource forbidden\")\n)\n\n// Auth provides authentication and authorization.\ntype Auth interface {\n\t// Init the auth\n\tInit(opts ...Option)\n\t// Options set for auth\n\tOptions() Options\n\t// Generate a new account\n\tGenerate(id string, opts ...GenerateOption) (*Account, error)\n\t// Inspect a token\n\tInspect(token string) (*Account, error)\n\t// Token generated using refresh token or credentials\n\tToken(opts ...TokenOption) (*Token, error)\n\t// String returns the name of the implementation\n\tString() string\n}\n","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/auth/auth.go#L5-L41","documentation":"ErrForbidden (message \"resource forbidden\") is a sentinel error in the auth package indicating the authenticated account does not have the scope required by an access rule for the requested resource. It is returned by Rules.Verify (and surfaced via TestVerify) after the token itself was valid but authorization failed. This is an authorization failure, not an authentication one.","triggerScenarios":"Rules.Verify(acc, res) or TestVerify is called and no matching rule grants the account's scopes access to the resource; the account's Scopes slice lacks the scope a rule requires; a rule with AccessDenied matches first due to higher Priority.","commonSituations":"Deploying a service whose account was created without the scope newly required by a rule; rules stored in an auth service were revoked or reordered; copying rules between environments (staging rules stricter than dev); misspelling the scope string in Grant.","solutions":["Check the account's Scopes and the rule's Scope: grant the missing scope via Rules.Grant or by regenerating the account with the right GenerateOption scopes","Use auth.Rule{Scope: auth.ScopePublic} or AccessGranted with higher Priority if the resource should be openly accessible","List existing rules with Rules.List to inspect which rule matches the Resource (Name/Type/Endpoint) and adjust it","Verify the resource fields (Name, Type, Endpoint) match exactly what the rules were written for"],"exampleFix":"// before: account missing scope, Verify returns ErrForbidden\nacc, _ := auth.Generate(\"user-1\")\nrules.Verify(acc, &auth.Resource{Name: \"notes\", Type: \"service\", Endpoint: \"Notes.Create\"})\n// after: grant a rule covering the required scope\nrules.Grant(&auth.Rule{ID: \"notes-write\", Scope: \"notes.write\", Resource: &auth.Resource{Name: \"notes\", Type: \"service\", Endpoint: \"Notes.Create\"}, Access: auth.AccessGranted})\nacc, _ := auth.Generate(\"user-1\", auth.WithScopes(\"notes.write\"))","handlingStrategy":"type-guard","validationCode":"// pre-check the account's scopes against the required scope before calling Verify\nfunc hasScope(acc *auth.Account, scope string) bool {\n    for _, s := range acc.Scopes {\n        if s == scope { return true }\n    }\n    return false\n}\nif !hasScope(acc, \"notes.write\") { return fmt.Errorf(\"pre-check: missing scope notes.write\") }","typeGuard":"func isForbidden(err error) bool {\n    return errors.Is(err, auth.ErrForbidden)\n}","tryCatchPattern":"if err := rules.Verify(acc, res); err != nil {\n    if errors.Is(err, auth.ErrForbidden) {\n        // authorization failed: 403 path, audit and deny\n        return status.Forbidden(\"access denied\")\n    }\n    return err\n}","preventionTips":["Keep rules and account scopes in sync; test Grant/Verify pairs in CI","Use Rules.List at startup to log effective rules per environment","Prefer explicit scopes over \"*\" and review Priority ordering of deny rules"],"tags":["auth","authorization","go-micro"],"backgroundTag":"authorization-forbidden","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}