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

# Secure Nginx APIs with API Key Authentication

Secure your Nginx API using a shared secret.

## How Zuplo Handles It

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

## Nginx Backend Code

```c
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include <openssl/crypto.h>
#include <string.h>

// Preprocessor for environment variable
#define SHARED_SECRET_ENV "SHARED_SECRET"

static ngx_int_t ngx_http_shared_secret_handler(ngx_http_request_t *r);
static char *ngx_http_shared_secret(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

// Module context
static ngx_http_module_t ngx_http_shared_secret_module_ctx = {
    NULL,                          /* preconfiguration */
    NULL,                          /* postconfiguration */

    NULL,                          /* create main configuration */
    NULL,                          /* init main configuration */

    NULL,                          /* create server configuration */
    NULL,                          /* merge server configuration */

    NULL,                          /* create location configuration */
    NULL                           /* merge location configuration */
};

// Commands
static ngx_command_t ngx_http_shared_secret_commands[] = {

    { ngx_string("shared_secret"),
      NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
      ngx_http_shared_secret,
      0,
      0,
      NULL },

    ngx_null_command
};

// Module
ngx_module_t ngx_http_shared_secret_module = {
    NGX_MODULE_V1,
    &ngx_http_shared_secret_module_ctx, /* module context */
    ngx_http_shared_secret_commands,    /* module directives */
    NGX_HTTP_MODULE,                    /* module type */
    NULL,                               /* init master */
    NULL,                               /* init module */
    NULL,                               /* init process */
    NULL,                               /* init thread */
    NULL,                               /* exit thread */
    NULL,                               /* exit process */
    NULL,                               /* exit master */
    NGX_MODULE_V1_PADDING
};

// Handler function
static ngx_int_t ngx_http_shared_secret_handler(ngx_http_request_t *r) {
    ngx_str_t secret_header_name = ngx_string("x-shared-secret");
    ngx_table_elt_t *secret_header;
    u_char *env_secret;

    secret_header = ngx_http_get_header(r, secret_header_name);
    env_secret = (u_char *) getenv(SHARED_SECRET_ENV);

    if (env_secret == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (secret_header == NULL) {
        return NGX_HTTP_UNAUTHORIZED;
    }

    if (strlen((char *)secret_header->value.data) != strlen((char *)env_secret) ||
        CRYPTO_memcmp(secret_header->value.data, env_secret, strlen((char *)env_secret)) != 0) {
        return NGX_HTTP_UNAUTHORIZED;
    }

    return NGX_DECLINED; // Proceed with request
}

// Configuration function
static char *ngx_http_shared_secret(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
    ngx_http_core_loc_conf_t  *clcf;

    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);

    clcf->handler = ngx_http_shared_secret_handler;

    return NGX_CONF_OK;
}
```

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