title: Check user Authorization for certain Service methods in go-kit with JWT
body: <p>I'm fairly new to go-kit and micro-service architecture as well.</p>
  
  <p>I have a JWT that contains the authenticated user's id as a claim, and each service's method, I want to check if the user has permission to update its own <strong>client</strong> record, but it seems that wherever I put it, it feels wrong. What are the best practices to doing something like this?</p>
  
  <pre><code>// client.go
  type Client struct {
      ID     string `json:"id"`
      UserID string `json:"user_id"`
      // ...
  }
  
  type ClientDataLayer interface {
      Load(db *sql.DB, id string) *Client
      Update(db *sql.DB, cl *Client) *Client
      // ... more CRUD methods
  }
  </code></pre>
  
  <p>Doing it within a service middleware I would have to call another service's method which seems to break the purpose of the architecture:</p>
  
  <pre><code>// service.go
  type Service interface {
      UpdateClient(ctx context.Context, cl *Client) (*Client, error)
      // ... more methods
  }
  
  func NewClientService(db *sql.DB, cdl ClientDataLayer) {
      // ....
  }
  
  type service struct {
      db  *sql.DB
      cdl ClientDataLayer
  }
  
  func (svc *service) UpdateClient(ctx context.Context, id string) (*Client, error) {
      return nil, nil
  }
  
  // service middleware
  type accessControl struct {
      svc Service
  }
  
  func (ac *accessControl) UpdateClient(ctx context.Context, cl *Client) (*Client, error) {
      // ... get token and claims from context
      // scopes := jwt.Claims().Get("scopes")
  
      // Here I don't have the client's user_id, 
      // and it does not feel right to call another service's method
      if !strings.Contains(scopes, "client:write") || cl.UserID != userID {
          return nil, errors.New("forbidden")
      }
  
      // ...
      return nil, nil
  }
  </code></pre>
  
  <p>Doing it on the endpoint its pretty much the same</p>
  
  <pre><code>// transport.go
  func makeUpdateClientEndpoint(svc Service) endpoint.Endpoint {
      return func(ctx context.Context, request interface{}) (interface{}, error) {
          // type cast request
          // ... get token and claims from context
          // scopes := jwt.Claims().Get("scopes")
  
          // Same problem as before, I don't have the client's user_id
  
          if !strings.Contains(scopes, "client:write") || cl.UserID != userID {
              return nil, errors.New("forbidden")
          }
  
          cl, _ := svc.UpdateClient(ctx, request.ClientID)
  
          // ...
  
          return nil, nil
      }
  }
  </code></pre>
  
  <p>I probably could get away by using the ClientDataLayer to retrieve the client and checking the user's id. As a way to avoid messing with another service method to load the client because it may have middlewares for logging or metrics too. </p>
  
  <p>How could I achieve this without so much hassle where I feel like breaking the patterns?</p>