code: func (a *Authenticator) refreshToken(prev *internal.Token, lifetime time.Duration) (*internal.Token, error) {
  	return a.authToken.compareAndRefresh(a.ctx, compareAndRefreshOp{
  		lock:     &a.lock,
  		prev:     prev,
  		lifetime: lifetime,
  		refreshCb: func(ctx context.Context, prev *internal.Token) (*internal.Token, error) {
  			// In Actor mode, need to make sure we have a sufficiently fresh base
  			// token first, since it's needed to get the new auth token. 30 sec should
  			// be more than enough to make an IAM call.
  			var base *internal.Token
  			if a.isActing() {
  				var err error
  				if base, err = a.getBaseTokenLocked(ctx, 30*time.Second); err != nil {
  					return nil, err
  				}
  			}
  			return a.authToken.renewToken(ctx, prev, base)
  		},
  	})
  }
docs: // refreshToken compares current auth token to 'prev' and launches token refresh
  // procedure if they still match.
  //
  // Returns a refreshed token (if a refresh procedure happened) or the current
  // token, if it's already different from 'prev'. Acts as "Compare-And-Swap"
  // where "Swap" is a token refresh procedure.
  //
  // If the token can't be refreshed (e.g. the base token or the credentials were
  // revoked), sets the current auth token to nil and returns an error.