Skip to content

CLI

The shield CLI is a thin HTTP client that talks to a running ShieldAdmin instance over HTTP. Install it separately if you only need the command-line tool:

uv add "api-shield[cli]"

First-time setup

1. Start your app with ShieldAdmin mounted

main.py
app.mount("/shield", ShieldAdmin(engine=engine, auth=("admin", "secret")))

2. Configure the server URL

Drop a .shield file in your project root (commit it alongside your code so the whole team gets the right URL automatically):

.shield
SHIELD_SERVER_URL=http://localhost:8000/shield

Or set it manually:

shield config set-url http://localhost:8000/shield

3. Log in

shield login admin
# Password: ••••••

Credentials are stored in ~/.shield/config.json with an expiry timestamp.


Route management

shield status                          # show all registered routes
shield status GET:/payments            # inspect one route

shield enable GET:/payments            # restore to ACTIVE
shield disable GET:/payments --reason "Use /v2/payments instead"

shield maintenance GET:/payments --reason "DB migration"

shield maintenance GET:/payments \
  --reason "Planned migration" \
  --start 2025-06-01T02:00Z \
  --end   2025-06-01T04:00Z

shield schedule GET:/payments \
  --start 2025-06-01T02:00Z \
  --end   2025-06-01T04:00Z \
  --reason "Planned migration"

shield disable GET:/payments --reason "hotfix" --until 2h
Sample shield status output
Route Status Reason Since
GET /payments MAINTENANCE DB migration 2 hours ago
GET /debug ENV_GATED dev, staging only startup
GET /health ACTIVE

Global maintenance

shield global enable --reason "Deploying v2"

# Exempt specific paths so they keep responding
shield global enable --reason "Deploying v2" --exempt /health --exempt GET:/status

# Block even @force_active routes
shield global enable --reason "Hard lockdown" --include-force-active

# Adjust exemptions while active
shield global exempt-add /monitoring/ping
shield global exempt-remove /monitoring/ping

shield global status    # check current state
shield global disable   # restore normal operation

Environment gating

Restrict a route to specific environments at runtime without redeploying.

shield env set /api/debug dev                    # allow only the "dev" environment
shield env set /api/internal dev staging         # allow dev and staging
shield env clear /api/debug                      # remove the gate, restore to ACTIVE

Note

The engine's current_env is set at startup (ShieldEngine(current_env="prod")). Requests from an environment not in allowed_envs receive a 403 ENV_GATED response. shield env clear is equivalent to calling shield enable — it transitions the route back to ACTIVE.


Multi-service context

When the Shield Server manages multiple services, scope every command to the right service.

export SHIELD_SERVICE=payments-service
shield status               # only payments-service routes
shield disable GET:/payments --reason "hotfix"
shield enable  GET:/payments

All route commands (status, enable, disable, maintenance, schedule) read SHIELD_SERVICE automatically. An explicit --service flag always overrides it.

Option B — --service flag per command

shield status --service payments-service
shield disable GET:/payments --service payments-service --reason "hotfix"

Discover active context and connected services

shield current-service          # show which service SHIELD_SERVICE points to
shield services                 # list all services registered with the Shield Server
Sample shield services output
Connected services
┌──────────────────────┐
│ Service              │
├──────────────────────┤
│ orders-service       │
│ payments-service     │
└──────────────────────┘

Rate limits

Manage rate limit policies and view blocked requests. Requires api-shield[rate-limit] on the server.

shield rl and shield rate-limits are aliases — use whichever you prefer.

shield rl list                              # show all registered policies
shield rl set GET:/public/posts 20/minute   # set or update a policy
shield rl set GET:/search 5/minute --algorithm fixed_window --key global
shield rl reset GET:/public/posts           # clear counters immediately
shield rl delete GET:/public/posts          # remove persisted policy override
shield rl hits                              # blocked requests log, page 1
shield rl hits --page 2                     # next page
shield rl hits --per-page 50               # 50 rows per page

# identical — shield rate-limits is the full name
shield rate-limits list
shield rate-limits set GET:/public/posts 20/minute

SDK clients receive policy changes in real time

When using Shield Server + ShieldSDK, rate limit policies set via shield rl set are broadcast over the SSE stream and applied to every connected SDK client immediately — no restart required.

Sample shield rl list output
Route Limit Algorithm Key Strategy
GET /public/posts 10/minute fixed_window ip
GET /search 5/minute fixed_window global
GET /users/me 100/minute fixed_window user

Audit log

shield log                          # page 1, 20 entries per page
shield log --route GET:/payments    # filter by route
shield log --page 2                 # next page
shield log --per-page 50           # 50 rows per page
Sample shield log output
Timestamp Route Action Actor Platform Status Reason
2025-06-01 02:00:01 GET:/payments maintenance alice cli active > maintenance DB migration
2025-06-01 01:59:00 GET:/debug disable system system active > disabled
2025-06-01 01:58:00 GET:/payments rl_policy_set alice cli set

Auth commands

shield login admin                          # prompts for password interactively
shield login admin --password "$SHIELD_PASS"  # inline, useful in CI

shield config show   # check current session and resolved URL
shield logout        # revokes server-side token and clears local credentials

Config commands

shield config set-url http://prod.example.com/shield   # override server URL
shield config show                                      # show URL, source, session

Server URL discovery

The CLI resolves the server URL using this priority order (highest wins):

Priority Source How to set
1 SHIELD_SERVER_URL environment variable export SHIELD_SERVER_URL=http://...
2 SHIELD_SERVER_URL in a .shield file (walked up from cwd) Add to project root
3 server_url in ~/.shield/config.json shield config set-url ...
4 Default http://localhost:8000/shield

Route key format

Routes are identified by a method-prefixed key. Use the same format in all CLI commands:

Decorator Route key
@router.get("/payments") GET:/payments
@router.post("/payments") POST:/payments
@router.get("/api/v1/users") GET:/api/v1/users
shield disable "GET:/payments"   # method-specific
shield enable "/payments"        # applies to all methods under /payments

Next step

Dive into the full Reference documentation →