API Key Authentication (NFL Wallet)

In this module you will explore how Red Hat Connectivity Link protects the pre-deployed NFL Wallet application using AuthPolicy with API Key authentication and RateLimitPolicy.

Architecture

NFL Wallet is deployed in the nfl-wallet-prod namespace. It uses the same Quarkus backend but is protected by API Key instead of OIDC, making it ideal for machine-to-machine (M2M) access.

sequenceDiagram
    participant Client
    participant Gateway as Istio Gateway
    participant Auth as Kuadrant AuthPolicy
    participant RL as RateLimitPolicy
    participant Backend as NFL Wallet Backend

    Client->>Gateway: GET /api/v1/customers
    Gateway->>Auth: Check X-API-Key header
    alt No Key or Invalid Key
        Auth-->>Client: 401 Unauthorized
    else Valid Key
        Auth->>RL: Check rate limit (120 req/min)
        RL->>Backend: Forward request
        Backend-->>Client: 200 JSON response
    end

OIDC vs API Key: When to Use Each

OIDC (Neuralbank) API Key (NFL Wallet)

Auth mechanism

Keycloak JWT tokens

API Key in HTTP header

Header

Authorization: Bearer <token>

X-API-Key: <key>

Unauthorized response

302 redirect to login

401 JSON error

Best for

Interactive users (web apps)

M2M integrations, scripts, CI/CD

Key management

Keycloak issues tokens

Kubernetes Secrets with labels

Inspect the Resources

oc get pods -n nfl-wallet-prod
oc get gateway -n nfl-wallet-prod
oc get httproute -n nfl-wallet-prod
oc get authpolicy -n nfl-wallet-prod -o wide
oc get ratelimitpolicy -n nfl-wallet-prod -o wide

Verify the AuthPolicy shows ACCEPTED: True and ENFORCED: True.

AuthPolicy with API Key

apiVersion: kuadrant.io/v1
kind: AuthPolicy
metadata:
  name: nfl-wallet-auth
  namespace: nfl-wallet-prod
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: nfl-wallet-route
  defaults:
    rules:
      authentication:
        api-key-auth:
          apiKey:
            allNamespaces: true
            selector:
              matchLabels:
                app: nfl-wallet
                kuadrant.io/apikey: "true"
          credentials:
            customHeader:
              name: X-API-Key
      response:
        unauthenticated:
          code: 401
          body:
            value: '{"error":"API Key required. Include X-API-Key header."}'

List Available API Keys

API Keys are stored as Kubernetes Secrets with labels that Kuadrant/Authorino detects:

oc get secrets -n nfl-wallet-prod -l kuadrant.io/apikey=true

# Decode the admin key
oc get secret nfl-wallet-apikey-admin -n nfl-wallet-prod \
  -o jsonpath='{.data.api_key}' | base64 -d ; echo

Test: Request Without API Key (expect 401)

curl -s -o /dev/null -w "HTTP Status: %{http_code}\n" \
  https://nfl-wallet.apps.cluster.example.com/api/v1/customers
HTTP Status: 401

Test: With Valid API Key (expect 200)

API_KEY=$(oc get secret nfl-wallet-apikey-admin -n nfl-wallet-prod \
  -o jsonpath='\{.data.api_key}' | base64 -d)

curl -s -H "X-API-Key: $API_KEY" \
  "https://nfl-wallet.apps.cluster.example.com/api/v1/customers" \
  | python3 -m json.tool | head -20

Test: Create a Customer (POST)

curl -s -X POST \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "nombre": "API Key",
    "apellido": "Test",
    "email": "apikey.test@wallet.io",
    "tipoCliente": "EMPRESA",
    "ciudad": "Miami",
    "pais": "USA"
  }' \
  "https://nfl-wallet.apps.cluster.example.com/api/v1/customers" \
  | python3 -m json.tool

Quick Rate-Limit Test

The RateLimitPolicy allows 120 requests per minute:

for i in $(seq 1 10); do
  code=$(curl -s -o /dev/null -w '%{http_code}' \
    -H "X-API-Key: $API_KEY" \
    "https://nfl-wallet.apps.cluster.example.com/api/v1/customers")
  echo "Request $i: HTTP $code"
done

All 10 should return 200. Beyond 120 requests per minute, you will see 429 Too Many Requests.

How API Key Auth Works

sequenceDiagram
    participant Client
    participant Authorino as Kuadrant Authorino
    participant K8s as Kubernetes API
    participant Backend

    Note over Authorino,K8s: Authorino watches Secrets with label kuadrant.io/apikey=true
    Client->>Authorino: Request with X-API-Key header
    Authorino->>K8s: Lookup matching Secret
    alt Key Found
        Authorino->>Backend: Forward request
        Backend-->>Client: 200 JSON
    else Key Not Found
        Authorino-->>Client: 401 Unauthorized
    end

Summary

The API Key pattern is ideal for:

  • Machine-to-machine (M2M) integrations

  • CI/CD pipelines consuming APIs

  • External partners with long-lived credentials

Both patterns (OIDC and API Key) are powered by the same stack: Istio Gateway + HTTPRoute + Kuadrant policies, demonstrating the flexibility of Red Hat Connectivity Link.