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

# Secure LoopBack APIs with API Key Authentication

Secure your LoopBack API using a shared secret.

## How Zuplo Handles It

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

## LoopBack Backend Code

```typescript
import {
  inject,
  MiddlewareSequence,
  RequestContext,
  RestBindings,
} from "@loopback/rest";
import { Middleware } from "@loopback/core";
import { HttpErrors } from "@loopback/rest";
import { request } from "@loopback/rest";
import * as crypto from "crypto";

// Middleware to validate shared secret header
const validateSharedSecret: Middleware = async (ctx, next) => {
  const req = await ctx.get(RestBindings.Http.REQUEST);
  const secret = req.headers["x-shared-secret"];
  const expectedSecret = process.env.SHARED_SECRET;

  if (!expectedSecret) {
    throw new HttpErrors.InternalServerError("Server configuration error");
  }

  if (!secret) {
    throw new HttpErrors.Unauthorized("No secret provided");
  }

  // Use timing-safe comparison to prevent timing attacks
  const isValid =
    secret.length === expectedSecret.length &&
    crypto.timingSafeEqual(Buffer.from(secret), Buffer.from(expectedSecret));

  if (!isValid) {
    throw new HttpErrors.Unauthorized("Invalid secret");
  }

  return next();
};

// Application setup
export class MyApplication extends MiddlewareSequence {
  constructor(@inject(RestBindings.Http.CONTEXT) public ctx: RequestContext) {
    super(ctx);
  }

  // Override the setup of the sequence to include middleware
  @inject(RestBindings.SequenceActions.MIDDLEWARE)
  middleware(@request validateSharedSecret: Middleware) {
    return super.middleware(validateSharedSecret);
  }
}

// Example usage in a controller
import { get } from "@loopback/rest";

export class ProtectedController {
  constructor() {}

  @get("/protected")
  async protectedEndpoint(): Promise<object> {
    return {
      message: "Access granted",
    };
  }
}
```

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