---
title: "Secure undefined APIs with API Key Authentication"
description: undefined
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/javascript/hapi/secure-header"
framework: undefined
language: undefined
authStrategy: "shared secret header"
pageType: use-case
---

# Secure undefined APIs with API Key Authentication



## How Zuplo Handles It

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

## undefined Backend Code

```javascript
const Hapi = require("@hapi/hapi");
const crypto = require("crypto");

const validateSharedSecret = (request, h) => {
  const secret = request.headers["x-shared-secret"];
  const expectedSecret = process.env.SHARED_SECRET;

  if (!expectedSecret) {
    return h
      .response({ error: "Server configuration error" })
      .code(500)
      .takeover();
  }

  if (!secret) {
    return h.response({ error: "No secret provided" }).code(401).takeover();
  }

  // Use timing-safe comparison to prevent timing attacks
  if (
    secret.length !== expectedSecret.length ||
    !crypto.timingSafeEqual(Buffer.from(secret), Buffer.from(expectedSecret))
  ) {
    return h.response({ error: "Invalid secret" }).code(401).takeover();
  }

  return h.continue;
};

const init = async () => {
  const server = Hapi.server({
    port: 3000,
    host: "localhost",
  });

  server.route({
    method: "GET",
    path: "/protected",
    options: {
      pre: [{ method: validateSharedSecret }],
    },
    handler: (request, h) => {
      return { message: "Access granted" };
    },
  });

  await server.start();
  console.log("Server running on %s", server.info.uri);
};

process.on("unhandledRejection", (err) => {
  console.log(err);
  process.exit(1);
});

init();
```

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