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

# Secure Http4k APIs with API Key Authentication

Secure your Http4k API using a shared secret.

## How Zuplo Handles It

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

## Http4k Backend Code

```kotlin
import org.http4k.core.Filter
import org.http4k.core.HttpHandler
import org.http4k.core.Request
import org.http4k.core.Response
import org.http4k.core.Status
import org.http4k.filter.ServerFilters
import org.http4k.lens.Header
import java.security.MessageDigest
import java.util.Base64
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec

val sharedSecret = System.getenv("SHARED_SECRET") ?: error("Server configuration error")

fun timingSafeEqual(a: ByteArray, b: ByteArray): Boolean {
    if (a.size != b.size) return false
    var result = 0
    for (i in a.indices) {
        result = result or (a[i].toInt() xor b[i].toInt())
    }
    return result == 0
}

fun validateSharedSecret(): Filter = Filter { next ->
    { request ->
        val secretHeader = Header.required("x-shared-secret")

        val secret = secretHeader(request)
        val expectedSecretBytes = sharedSecret.toByteArray()
        val secretBytes = secret.toByteArray()

        if (!timingSafeEqual(secretBytes, expectedSecretBytes)) {
            Response(Status.UNAUTHORIZED).body("Invalid secret")
        } else {
            next(request)
        }
    }
}

val app: HttpHandler = ServerFilters.InitialiseRequestContext()
    .then(validateSharedSecret())
    .then { Response(Status.OK).body("Access granted") }

fun main() {
    val request = Request(GET, "/protected").header("x-shared-secret", System.getenv("SHARED_SECRET") ?: "")
    println(app(request))
}
```

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