---
title: "Add JWT Authentication to Your undefined API"
description: undefined
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/ruby/grape/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

```ruby
require 'grape'
require 'jwt'
require 'net/http'
require 'uri'
require 'json'

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

def fetch_jwks
  uri = URI(JWKS_URI)
  response = Net::HTTP.get(uri)
  JSON.parse(response)
end

def find_key(kid)
  jwks = fetch_jwks
  key_data = jwks['keys'].find { |key| key['kid'] == kid }
  JSON::JWK.new(key_data) if key_data
end

def decode_jwt(token)
  begin
    header = JWT.decode(token, nil, false).first
    key = find_key(header['kid'])
    raise 'Key not found' unless key

    decoded_token = JWT.decode(
      token,
      key.to_key,
      true,
      {
        algorithm: 'RS256',
        iss: ISSUER,
        verify_iss: true
      }
    )
    decoded_token.first
  rescue JWT::DecodeError, JWT::VerificationError => e
    nil
  end
end

class API < Grape::API
  before do
    error!('Unauthorized', 401) unless headers['Authorization']

    token = headers['Authorization'].to_s.split(' ').last
    @current_user = decode_jwt(token)

    error!('Invalid token', 401) unless @current_user
  end

  get :protected do
    { message: 'Access granted', user: @current_user }
  end
end
```

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