---
title: "Add JWT Authentication to Your ServiceStack API"
description: "Secure your ServiceStack API using JWT authentication with JWKS."
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/csharp/servicestack/jwt-backend"
framework: "ServiceStack"
language: "C#"
authStrategy: "JWT with JWKS"
pageType: use-case
---

# Add JWT Authentication to Your ServiceStack API

Secure your ServiceStack API using JWT authentication with JWKS.

## How Zuplo Handles It

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

## ServiceStack Backend Code

```csharp
using System;
using System.Collections.Generic;
using ServiceStack;
using ServiceStack.Auth;
using ServiceStack.Configuration;
using ServiceStack.Web;

public class AppHost : AppSelfHostBase
{
    public AppHost()
        : base("My API", typeof(MyServices).Assembly) {}

    public override void Configure(Container container)
    {
        var appSettings = new AppSettings();
        Plugins.Add(new AuthFeature(() => new AuthUserSession(),
            new IAuthProvider[] {
                new JwtAuthProviderReader(appSettings) {
                    AuthKeyBase64 = "your-base64-secret", // Remove this when using JWKS
                    RequireSecureConnection = false,
                    JwtAuthProviderReader = new ExternalJwtAuthProviderReader {
                        ValidAudiences = new List<string> { "your-audience" },
                        ValidIssuers = new List<string> { "https://my-api-a32f34.zuplo.api/__zuplo/issuer" },
                        AuthKeyResolver = GetAuthKeyFromJwks
                    }
                }
            }));
    }

    private static Func<JsonWebKey> GetAuthKeyFromJwks(string kid)
    {
        try
        {
            var jwksUri = "https://my-api-a32f34.zuplo.api/__zuplo/issuer/.well-known/jwks.json";
            var json = jwksUri.GetStringFromUrl();
            var keys = json.FromJson<JsonWebKeySet>();

            return kid != null ? new Func<JsonWebKey>(() => keys.Keys.FirstOrDefault(k => k.Kid == kid)) : null;
        }
        catch (Exception ex)
        {
            throw new Exception("Could not retrieve JWKS", ex);
        }
    }
}

public class MyServices : Service
{
    [Authenticate]
    public object Any(ProtectedRequest request)
    {
        return new { Message = "Access granted", UserId = base.GetSession().UserAuthId };
    }
}

[Route("/protected", "GET")]
public class ProtectedRequest : IReturn<object> {}
```

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