---
title: "Add JWT Authentication to Your undefined API"
description: undefined
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/python/hug/jwt-backend"
framework: undefined
language: undefined
authStrategy: "JWT with JWKS"
pageType: use-case
---

# Add JWT Authentication to Your undefined API



## How Zuplo Handles It

Let Zuplo issue short-lived JWTs signed with a JWKS your undefined backend can verify — no long-lived API keys touch your origin.

## undefined Backend Code

```python
import hug
import jwt
import requests
from jwt import PyJWKClient

ISSUER = "https://my-api-a32f34.zuplo.api/__zuplo/issuer"
JWKS_URL = f"{ISSUER}/.well-known/jwks.json"

def get_public_key(token):
    jwks_client = PyJWKClient(JWKS_URL)
    signing_key = jwks_client.get_signing_key_from_jwt(token)
    return signing_key.key

def validate_jwt(token):
    try:
        public_key = get_public_key(token)
        decoded = jwt.decode(
            token,
            public_key,
            algorithms=["RS256"],
            options={"verify_aud": False},
            issuer=ISSUER
        )
        return decoded
    except jwt.ExpiredSignatureError:
        raise hug.HTTPUnauthorized("Token has expired")
    except jwt.InvalidTokenError as e:
        raise hug.HTTPUnauthorized(f"Invalid token: {str(e)}")

def jwt_authentication(request, response, **kwargs):
    auth_header = request.get_header('Authorization')
    if auth_header is None or not auth_header.startswith('Bearer '):
        raise hug.HTTPUnauthorized("No token provided")

    token = auth_header.split(' ')[1]
    return validate_jwt(token)

@hug.get('/protected', requires=hug.authentication.basic(jwt_authentication))
def protected_route(user):
    return {'message': 'Access granted', 'user': user}
```

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