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

# Secure BlackSheep APIs with API Key Authentication

Secure your BlackSheep API using a shared secret.

## How Zuplo Handles It

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

## BlackSheep Backend Code

```python
import os
from blacksheep import FromHeader, Response, Application
from blacksheep.server.authorization import Unauthorized
from hmac import compare_digest

app = Application()

async def validate_shared_secret(secret: FromHeader[str]) -> bool:
    expected_secret = os.getenv("SHARED_SECRET")

    if not expected_secret:
        # Raise a server error if the secret is not configured
        raise RuntimeError("Server configuration error")

    # Return False if no secret is provided
    if secret is None:
        return False

    # Timing-safe comparison to prevent timing attacks
    return compare_digest(secret, expected_secret)

@app.router.get("/protected")
async def protected_route(secret: FromHeader[str]) -> Response:
    if not await validate_shared_secret(secret):
        raise Unauthorized("Invalid or missing secret")

    return Response(200, content=b"Access granted")

# To use environment variables in Python, you need to set them accordingly
# For testing purposes, you might set an environment variable like this:
# os.environ["SHARED_SECRET"] = "your-expected-secret"
```

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