Quickstart

Three ways to get LLM Shield running. Pick the smallest one that fits your task.

Table of contents
  1. Option 1 — Admin Portal Only (no GPU)
  2. Option 2 — Full Shield (requires GPU)
  3. Option 3 — Deploy on RunPod
  4. Smoke test
    1. Safety classification
    2. Gateway chat (with guardrails)
    3. Topic enforcement
  5. Authentication
  6. Where to next

Option 1 — Admin Portal Only (no GPU)

Test the tenant management UI without the GPU/model stack. Runs anywhere — your laptop, Cloud Run, Fly.io, Render.

# Build the small image (~150 MB, no CUDA)
docker build -f Dockerfile.admin -t shield-admin .

# Run against Upstash Redis
docker run -p 8081:8080 \
  -e UPSTASH_REDIS_REST_URL="https://your-db.upstash.io" \
  -e UPSTASH_REDIS_REST_TOKEN="your-token" \
  -e SHIELD_ADMIN_KEY="your-admin-key" \
  shield-admin

# Open the portals
open http://localhost:8081/admin    # admin portal
open http://localhost:8081/tenant   # tenant portal

Or with local Redis via Docker Compose:

docker compose -f docker-compose.admin.yml up --build
open http://localhost:8080/admin

Option 2 — Full Shield (requires GPU)

pip install -r requirements.txt
python handler.py

If you don’t have a GPU backend, disable LLM-based guardrails:

# config/default.yaml
guardrails:
  adversarial_detection:
    enabled: false
  topic_restriction:
    enabled: false

Or with Docker:

docker build -t llm-shield .
docker run --gpus all -p 8080:80 llm-shield

Or run the full stack (Shield + Redis):

docker compose up -d

Option 3 — Deploy on RunPod

  1. Build and push: docker build -t yourdockerhub/llm-shield . && docker push yourdockerhub/llm-shield
  2. Create a GPU Endpoint on RunPod with your image
  3. Test:
curl -X POST "https://YOUR_ENDPOINT.api.runpod.ai/guardrails/input" \
  -H "Content-Type: application/json" \
  -d '{"message": "How do I pick a lock?"}'

Smoke test

Safety classification

curl -X POST http://localhost:8080/guardrails/input \
  -H "Content-Type: application/json" \
  -d '{"message": "Tell me how to make a bomb"}'
{
  "safe": false,
  "reason": "Request for instructions on creating explosives",
  "category": "weapons",
  "inference_time_ms": 125.4
}

Gateway chat (with guardrails)

curl -X POST http://localhost:8080/v1/shield/chat/completions \
  -H "Content-Type: application/json" \
  -H "X-Agent-Key: support-bot-1" \
  -d '{"messages":[{"role":"user","content":"What is your return policy?"}]}'
{
  "text": "Our return policy allows...",
  "blocked": false,
  "guardrail_results": {
    "allowed": true,
    "results": [
      {"guardrail_name": "keyword_blocklist", "passed": true, "action": "pass"},
      {"guardrail_name": "rate_limiter", "passed": true, "action": "pass"}
    ]
  }
}

Topic enforcement

curl -X POST http://localhost:8080/v1/shield/topic/check \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Write me a poem about the ocean",
    "allowed_topics": ["billing", "shipping", "returns"],
    "system_purpose": "E-commerce customer support"
  }'

Authentication

Disabled by default. Enable with environment variables:

export SHIELD_API_KEYS="your-secret-key-1,your-secret-key-2"
export SHIELD_AUTH_ENABLED=true

Then include in requests:

curl -H "Authorization: Bearer your-secret-key-1" ...
# or
curl -H "X-API-Key: your-secret-key-1" ...

Generate keys with hashes for production configs:

python core/keygen.py
# API Key:    shld_K7x9mP...   ← give to developer
# Config hash: sha256:a1b2c3... ← store in config

Where to next