diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 96c6478a269158740ad5416baf1863bca7f930c9..8b44e556ec6be305c6cb4007c6212cfca05498e5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -6,7 +6,7 @@ before_script:
   - cd /go/src/gitlab.com/${CI_PROJECT_PATH}
 
 unit tests:
-  image: golang:1.17.8
+  image: golang:1.19.2
   stage: test
   tags:
     - amd64-docker
@@ -14,15 +14,25 @@ unit tests:
     - go version
     - go test -race -coverprofile=coverage.out ./...
     - go tool cover -func=coverage.out
+  coverage: '/total:\s+\(statements\)\s+(\d+.\d+\%)/'
+
 
 lint:
-  image: golangci/golangci-lint:v1.45.0
+  image: golangci/golangci-lint:v1.50.0
   stage: test
   tags:
     - amd64-docker
   script:
+    - go version
     - golangci-lint --version
     - golangci-lint run
-  before_script:
-    - ln -s /builds /go/src/gitlab.com
-    - cd /go/src/gitlab.com/${CI_PROJECT_PATH}
+
+govulncheck:
+  image: golang:1.19.2
+  stage: test
+  tags:
+    - amd64-docker
+  script:
+    - go version
+    - go install golang.org/x/vuln/cmd/govulncheck@latest
+    - govulncheck ./...
diff --git a/.golangci.yml b/.golangci.yml
index e6ba71d0fff71ba18fa18f4bd0f55fbaad679ab2..a31b66b24000f23ec82f765c828a26cf2bef07bd 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -12,7 +12,6 @@ linters:
   enable:
     - megacheck
     - govet
-    - deadcode
     - errcheck
     - goconst
     - gocyclo
@@ -22,10 +21,9 @@ linters:
     - ineffassign
     - nakedret
     - staticcheck
-    - structcheck
     - unconvert
-    - varcheck
     - vet
     - vetshadow
     - misspell
     - staticcheck
+    - unused
diff --git a/auth/auth.go b/auth/auth.go
index 41aeb4e415feca5578da8fa60845196d43e5e88c..43d54064aa4c1787e37fb8abc6792a19aa55939a 100644
--- a/auth/auth.go
+++ b/auth/auth.go
@@ -11,7 +11,7 @@ import (
 	"github.com/lestrrat-go/jwx/v2/jwt"
 )
 
-// AuthMiddleware is standard HTTP middleware used for authenticating
+// Middleware is standard HTTP middleware used for authenticating
 // requests carrying a bearer JWT token.
 //
 // It uses an internal caching mechanism for fetching Json Web Keys from
@@ -19,11 +19,11 @@ import (
 //
 // JWT tokens are expected to carry a Header *kid* claim specifying the
 // ID of the public key which should be used for verification.
-type AuthMiddleware struct {
+type Middleware struct {
 	jwkSet jwk.Set
 }
 
-func NewMiddleware(jwkURL string, refreshInterval time.Duration, c *http.Client) (*AuthMiddleware, error) {
+func NewMiddleware(jwkURL string, refreshInterval time.Duration, c *http.Client) (*Middleware, error) {
 	if jwkURL == "" {
 		return nil, fmt.Errorf("missing JWK url")
 	}
@@ -37,12 +37,12 @@ func NewMiddleware(jwkURL string, refreshInterval time.Duration, c *http.Client)
 		return nil, fmt.Errorf("fail to refresh JWK cache: %v", err)
 	}
 
-	return &AuthMiddleware{
+	return &Middleware{
 		jwkSet: jwk.NewCachedSet(cache, jwkURL),
 	}, nil
 }
 
-func (a *AuthMiddleware) Handler() func(http.Handler) http.Handler {
+func (a *Middleware) Handler() func(http.Handler) http.Handler {
 	return func(h http.Handler) http.Handler {
 		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 			token, err := tokenFromRequest(r)
diff --git a/auth/auth_test.go b/auth/auth_test.go
index 87431ceb223e9c6e44232ddaacb64d42b576ddae..426988fe0fea15f6c48620e5c984d0670a6953ba 100644
--- a/auth/auth_test.go
+++ b/auth/auth_test.go
@@ -128,7 +128,7 @@ func TestAuthMiddleware_Handler(t *testing.T) {
 		req, err := http.NewRequest(http.MethodGet, "https://example.com", nil)
 		assert.NoError(t, err)
 
-		token := "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtleTEifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTY2NDk2MDg2OCwiZXhwIjoxNjY0OTY0NDY4fQ.FrIA3A228den86qX72o4yP3TiEA9uOf46Yav_vY5daCQ8yeAm3GaBzC_nikt0y9NSCR6K2G2GCm7RcdfP3vQ9CFh2R7FtL4nfjffdauLmXVzp3z_lyBIKYL3RsTGChctfMeYZzk2F6EDmGHeI8xV3KiDC5Gfkvfdp9MfFxVy7DcuEV9MLo_9j4Y-7nfuB1CbdF_1vzSsO0twitePjsB59CNndugJgTUGFjKUJU2_e7vKMR_i9NvFHfJZS2VbtX3vrZ5f_pfOvBSSZJBxG50Uwf6COhtABieVHhhmLBSJq1P1EWRAI26Bk-YtE8k-jfjra9W1RF5DLF7Jh9Lw-utc5A"
+		token := "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImtleTEifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTY2NDk2MDg2OCwiZXhwIjoxNjY0OTY0NDY4fQ.FrIA3A228den86qX72o4yP3TiEA9uOf46Yav_vY5daCQ8yeAm3GaBzC_nikt0y9NSCR6K2G2GCm7RcdfP3vQ9CFh2R7FtL4nfjffdauLmXVzp3z_lyBIKYL3RsTGChctfMeYZzk2F6EDmGHeI8xV3KiDC5Gfkvfdp9MfFxVy7DcuEV9MLo_9j4Y-7nfuB1CbdF_1vzSsO0twitePjsB59CNndugJgTUGFjKUJU2_e7vKMR_i9NvFHfJZS2VbtX3vrZ5f_pfOvBSSZJBxG50Uwf6COhtABieVHhhmLBSJq1P1EWRAI26Bk-YtE8k-jfjra9W1RF5DLF7Jh9Lw-utc5A" //nolint:gosec
 		req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
 
 		response := httptest.NewRecorder()
@@ -153,7 +153,7 @@ func TestAuthMiddleware_Handler(t *testing.T) {
 
 		token, err := createSignedToken()
 		assert.NoError(t, err)
-		req.Header.Set("Authorization", fmt.Sprintf("%s", token))
+		req.Header.Set("Authorization", token)
 
 		response := httptest.NewRecorder()
 		authHandler.ServeHTTP(response, req)
@@ -171,7 +171,7 @@ func createSignedToken() (string, error) {
 		Audience([]string{"skynet"}).
 		Build()
 	if err != nil {
-		return "", fmt.Errorf("failed to build token: %s\n", err)
+		return "", fmt.Errorf("failed to build token: %s", err)
 	}
 
 	signed, err := jwt.Sign(token, jwt.WithKey(jwa.RS256, privateKey))
diff --git a/errors/errors.go b/errors/errors.go
index 8c3afe9ce39b4e2cdc4b73b91862503df1b5df9e..2f1c0906a3da5f9b860c2587f9c5fdf9b18798b1 100644
--- a/errors/errors.go
+++ b/errors/errors.go
@@ -73,16 +73,17 @@ func (k Kind) String() string {
 // recorded.
 //
 // The supported types are:
-//   errors.Kind:
-//       The kind of the error.
-//   *errors.Error
-//       The underlying error that triggered this one. If the error has
-//       non-empty ID and Kind fields, they are promoted as values of the
-//       returned one.
-//   error:
-//       The underlying error that triggered this one.
-//   string:
-//       Treated as an error message and assigned to the Message field.
+//
+//	errors.Kind:
+//	    The kind of the error.
+//	*errors.Error
+//	    The underlying error that triggered this one. If the error has
+//	    non-empty ID and Kind fields, they are promoted as values of the
+//	    returned one.
+//	error:
+//	    The underlying error that triggered this one.
+//	string:
+//	    Treated as an error message and assigned to the Message field.
 func New(args ...interface{}) error {
 	if len(args) == 0 {
 		panic("call to errors.New without arguments")
diff --git a/goadec/bytes_decoder.go b/goadec/bytes_decoder.go
index b3ce113e4a8e168e391219377381dbf375f04b0e..1494d03346c841584af66d1ea05d581436d74368 100644
--- a/goadec/bytes_decoder.go
+++ b/goadec/bytes_decoder.go
@@ -4,7 +4,6 @@ package goadec
 import (
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 
 	goahttp "goa.design/goa/v3/http"
@@ -25,7 +24,7 @@ func newBytesDecoder(r io.Reader) *bytesDecoder {
 }
 
 func (d *bytesDecoder) Decode(v interface{}) error {
-	b, err := ioutil.ReadAll(d.r)
+	b, err := io.ReadAll(d.r)
 	if err != nil {
 		return err
 	}
diff --git a/graceful/graceful_test.go b/graceful/graceful_test.go
index f27ef80193c03c81c34732a9568c1d54fae98ec6..5e0c60c1011fcfc5e6d6a2eb8bf5d7559f42a2ff 100644
--- a/graceful/graceful_test.go
+++ b/graceful/graceful_test.go
@@ -5,6 +5,7 @@ import (
 	"errors"
 	"net/http"
 	"os"
+	"syscall"
 	"testing"
 	"time"
 
@@ -65,7 +66,7 @@ func TestShutdownWithSignal(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			srv := &http.Server{
+			srv := &http.Server{ //nolint:gosec
 				Addr:    test.addr,
 				Handler: &handler{requestTime: test.reqTime},
 			}
@@ -89,7 +90,7 @@ func TestShutdownWithSignal(t *testing.T) {
 
 			proc, err := os.FindProcess(os.Getpid())
 			require.NoError(t, err)
-			require.NoError(t, proc.Signal(os.Interrupt))
+			require.NoError(t, proc.Signal(syscall.SIGTERM))
 
 			err = <-reqerr
 
@@ -140,7 +141,7 @@ func TestShutdownWithContext(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			srv := &http.Server{
+			srv := &http.Server{ //nolint:gosec
 				Addr:    test.addr,
 				Handler: &handler{requestTime: test.reqTime},
 			}