---
title: "Add JWT Authentication to Your Echo API"
description: "Secure your Echo API using JWT authentication with JWKS."
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/go/echo/jwt-backend"
framework: "Echo"
language: "Go"
authStrategy: "JWT with JWKS"
pageType: use-case
---

# Add JWT Authentication to Your Echo API

Secure your Echo API using JWT authentication with JWKS.

## How Zuplo Handles It

Let Zuplo issue short-lived JWTs signed with a JWKS your Echo backend can verify — no long-lived API keys touch your origin.

## Echo Backend Code

```go
package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"github.com/MicahParks/keyfunc"
)

const ISSUER = "https://my-api-a32f34.zuplo.api/__zuplo/issuer"

func main() {
	e := echo.New()

	// JWKS URL
	jwksURL := fmt.Sprintf("%s/.well-known/jwks.json", ISSUER)

	// Create the JWKS client
	jwks, err := keyfunc.Get(jwksURL, keyfunc.Options{
		RefreshErrorHandler: func(err error) {
			log.Printf("JWKS refresh error: %v", err)
		},
		RefreshTimeout: 10,
		MinRefreshInterval: 600, // 10 minutes
	})
	if err != nil {
		log.Fatalf("Failed to create JWKS: %v", err)
	}

	// Middleware to validate JWT
	e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
		SigningKeyFunc: func(token *jwt.Token) (interface{}, error) {
			return jwks.KeyFunc(token)
		},
		ContextKey: "user",
		TokenLookup: "header:Authorization",
		AuthScheme:  "Bearer",
	}))

	// Protected route
	e.GET("/protected", func(c echo.Context) error {
		user := c.Get("user")
		return c.JSON(http.StatusOK, echo.Map{
			"message": "Access granted",
			"user":    user,
		})
	})

	e.Logger.Fatal(e.Start(":8080"))
}
```

## Example Request

```bash
curl -X GET \
  'https://your-api.zuplo.dev/your-route' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## Learn More

- [API Key Authentication on Zuplo](https://zuplo.com/docs/policies/api-key-auth-inbound)
- [JWT Authentication on Zuplo](https://zuplo.com/docs/policies/open-id-jwt-auth-inbound)
- [All use cases](https://zuplo.com/use-cases)
