micro/go-micro · error

ErrForbidden

ErrForbidden

Error message

resource forbidden

What it means

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.

Source

Thrown at auth/auth.go:23

	"context"
	"errors"
	"time"
)

const (
	// BearerScheme used for Authorization header.
	BearerScheme = "Bearer "
	// ScopePublic is the scope applied to a rule to allow access to the public.
	ScopePublic = ""
	// ScopeAccount is the scope applied to a rule to limit to users with any valid account.
	ScopeAccount = "*"
)

var (
	// ErrInvalidToken is when the token provided is not valid.
	ErrInvalidToken = errors.New("invalid token provided")
	// ErrForbidden is when a user does not have the necessary scope to access a resource.
	ErrForbidden = errors.New("resource forbidden")
)

// Auth provides authentication and authorization.
type Auth interface {
	// Init the auth
	Init(opts ...Option)
	// Options set for auth
	Options() Options
	// Generate a new account
	Generate(id string, opts ...GenerateOption) (*Account, error)
	// Inspect a token
	Inspect(token string) (*Account, error)
	// Token generated using refresh token or credentials
	Token(opts ...TokenOption) (*Token, error)
	// String returns the name of the implementation
	String() string
}

View on GitHub (pinned to 24529f1404)

Solutions

  1. 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
  2. Use auth.Rule{Scope: auth.ScopePublic} or AccessGranted with higher Priority if the resource should be openly accessible
  3. List existing rules with Rules.List to inspect which rule matches the Resource (Name/Type/Endpoint) and adjust it
  4. Verify the resource fields (Name, Type, Endpoint) match exactly what the rules were written for

Example fix

// before: account missing scope, Verify returns ErrForbidden
acc, _ := auth.Generate("user-1")
rules.Verify(acc, &auth.Resource{Name: "notes", Type: "service", Endpoint: "Notes.Create"})
// after: grant a rule covering the required scope
rules.Grant(&auth.Rule{ID: "notes-write", Scope: "notes.write", Resource: &auth.Resource{Name: "notes", Type: "service", Endpoint: "Notes.Create"}, Access: auth.AccessGranted})
acc, _ := auth.Generate("user-1", auth.WithScopes("notes.write"))
Defensive patterns

Strategy: type-guard

Validate before calling

// pre-check the account's scopes against the required scope before calling Verify
func hasScope(acc *auth.Account, scope string) bool {
    for _, s := range acc.Scopes {
        if s == scope { return true }
    }
    return false
}
if !hasScope(acc, "notes.write") { return fmt.Errorf("pre-check: missing scope notes.write") }

Type guard

func isForbidden(err error) bool {
    return errors.Is(err, auth.ErrForbidden)
}

Try / catch

if err := rules.Verify(acc, res); err != nil {
    if errors.Is(err, auth.ErrForbidden) {
        // authorization failed: 403 path, audit and deny
        return status.Forbidden("access denied")
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/a3df298b4c1c460d. Report an issue: GitHub.