---
title: "Secure Tyk APIs with API Key Authentication"
description: "Secure your Tyk API using a shared secret."
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/go/tyk/secure-header"
framework: "Tyk"
language: "Go"
authStrategy: "shared secret header"
pageType: use-case
---

# Secure Tyk APIs with API Key Authentication

Secure your Tyk API using a shared secret.

## How Zuplo Handles It

Put Zuplo in front of your Tyk backend to authenticate API keys and forward a shared secret header so your origin only accepts traffic from Zuplo.

## Tyk Backend Code

```go
package main

import (
	"context"
	"errors"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/TykTechnologies/tyk"
)

// SharedSecretMiddleware creates a new Tyk middleware for validating a shared secret
type SharedSecretMiddleware struct {
	BaseMiddleware tyk.BaseMiddleware
}

// NewSharedSecretMiddleware initializes the middleware
func NewSharedSecretMiddleware() *SharedSecretMiddleware {
	return &SharedSecretMiddleware{}
}

// ProcessRequest checks for the shared secret in the header
func (m *SharedSecretMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Request) (error, int) {
	secret := r.Header.Get("x-shared-secret")
	expectedSecret := os.Getenv("SHARED_SECRET")

	if expectedSecret == "" {
		return errors.New("server configuration error"), http.StatusInternalServerError
	}

	if secret == "" {
		return errors.New("no secret provided"), http.StatusUnauthorized
	}

	if !secureCompare(secret, expectedSecret) {
		return errors.New("invalid secret"), http.StatusUnauthorized
	}

	return nil, 0
}

// secureCompare performs a timing-safe comparison
func secureCompare(given string, expected string) bool {
	if len(given) != len(expected) {
		return false
	}

	return subtle.ConstantTimeCompare([]byte(given), []byte(expected)) == 1
}

func main() {
	// Initialize Tyk middleware
	config := &tyk.MiddlewareConfig{
		Path:  "/protected",
		Phase: tyk.PostKeyAuth,
	}

	middleware := NewSharedSecretMiddleware()
	tyk.NewMiddleware(middleware, config)

	// Example handler
	http.HandleFunc("/protected", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`{"message": "Access granted"}`))
	})

	// Start server (example purposes only; Tyk handles this differently)
	server := &http.Server{
		Addr:         ":8080",
		Handler:      nil,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
		IdleTimeout:  15 * time.Second,
	}

	server.ListenAndServe()
}
```

## 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)
