Validating the Management Key
On this page
Verify the integrity of your keys
Management key validation is your API infrastructure’s first line of defense. Before any critical operation—deployment, rotation, billing changes—verify that your key is valid and its permissions are correct.
Validation endpoint
GET /auth/management-keys/validation
curl "https://management-api.x.ai/auth/management-keys/validation" \
-H "Authorization: Bearer $MANAGEMENT_API_KEY"
The response confirms the key is active and returns the team, permissions, and associated dates. Do not overlook the expiration date: this is the only information that lets you anticipate an outage instead of suffering it, since an expired key does not warn you—it simply returns 401 on the first call that follows.
Error cases
- 401 Unauthorized: The key is invalid, expired, or has been deleted
- 403 Forbidden: The key is valid but lacks the necessary permissions for the requested operation
Integrating into your scripts
Startup verification
Validating at startup moves failure to where it costs the least. Without this check, an invalid key manifests on the first useful call—that is, in the middle of processing, sometimes after several steps have already executed. With it, the script stops in three seconds with a message that names the cause.
import requests
import sys
MANAGEMENT_API = "https://management-api.x.ai"
MGMT_KEY = "xai-mgmt-..."
def validate_management_key():
"""Checks that the management key is valid."""
try:
response = requests.get(
f"{MANAGEMENT_API}/auth/management-keys/validation",
headers={"Authorization": f"Bearer {MGMT_KEY}"},
timeout=10
)
if response.status_code == 200:
print("Management key valid")
return True
elif response.status_code == 401:
print("ERROR: Management key invalid or expired")
return False
else:
print(f"ERROR: Unexpected status {response.status_code}")
return False
except requests.exceptions.RequestException as e:
print(f"CONNECTION ERROR: {e}")
return False
if not validate_management_key():
sys.exit(1)
Periodic healthcheck
The periodic healthcheck covers what startup validation misses: long-running services, started weeks ago, whose key may expire or be revoked along the way. An hourly check is enough—the endpoint is lightweight and consumes no inference tokens.
#!/bin/bash
# healthcheck-xai.sh — run every hour via cron
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
"https://management-api.x.ai/auth/management-keys/validation" \
-H "Authorization: Bearer $MANAGEMENT_API_KEY")
if [ "$STATUS" != "200" ]; then
echo "ALERT: xAI management key invalid (HTTP $STATUS)"
# Send an alert (PagerDuty, Slack, email)
fi
Auditing inference keys
Periodic auditing answers three questions no alert will ask for you: which keys still carry a wildcard, which have no rate limits, and which haven’t been used in months. The first two are risks, the third an opportunity to clean up—and all three are handled in one pass.
import requests
from datetime import datetime
MANAGEMENT_API = "https://management-api.x.ai"
MGMT_KEY = "xai-mgmt-..."
TEAM_ID = "team-..."
def audit_api_keys():
"""Audits all API keys for the team."""
response = requests.get(
f"{MANAGEMENT_API}/auth/teams/{TEAM_ID}/api-keys",
headers={"Authorization": f"Bearer {MGMT_KEY}"}
)
keys = response.json().get("apiKeys", [])
print(f"=== API Key Audit — {datetime.now().strftime('%d/%m/%Y %H:%M')} ===")
print(f"Total number of keys: {len(keys)}")
for key in keys:
name = key.get("name", "Unnamed")
acls = key.get("acls", [])
expire = key.get("expireTime", "Never")
created = key.get("createdAt", "N/A")
# Alerts
warnings = []
# Key with wildcard access
if "api-key:endpoint:*" in acls and "api-key:model:*" in acls:
warnings.append("TOTAL ACCESS (wildcards)")
# Key without expiration
if expire == "Never" or not expire:
warnings.append("NO EXPIRATION")
# Key without rate limits
if not key.get("qps") and not key.get("qpm"):
warnings.append("NO RATE LIMITS")
status = " | ".join(warnings) if warnings else "OK"
print(f" [{name}] ACLs: {len(acls)} | Expire: {expire} | {status}")
audit_api_keys()
Key security checklist
Management keys
Management keys control everything else—their compromise grants access to create, modify, and delete all inference keys. They therefore demand the strictest handling: exclusive storage in a vault, never in plaintext in code or versioned configuration; access limited to infrastructure administrators only, not application developers; and regular validation via GET /auth/management-keys/validation, ideally automated as a healthcheck—an expired management key discovered when you urgently need it is the worst operational scenario.
Inference keys (API keys)
For inference keys, the guiding principle is isolation: each application receives its own key, never a key shared between services—otherwise rotating a compromised key breaks all services at once, and analytics no longer allow attributing consumption. Each key carries restrictive ACLs calibrated to its actual usage (no wildcards in production), rate limits sized for expected traffic, and an expiration date when usage is temporary—a POC meant to last two weeks does not need an eternal key. Regular auditing via the script above closes the loop: it reveals forgotten, over-privileged, or expiring keys before they become problems.
Principle of separation of duties
Maintain a clear separation between keys:
| Type | Usage | Who has access |
|---|---|---|
| Management key | Administration, billing, analytics | Infrastructure admins |
| Prod key | API calls in production | Production application |
| Staging key | Pre-production testing | Development team |
| Dev key | Local development | Individual developer |
Each key has a defined scope. If a developer leaves the team, only their dev key is deleted—the others remain intact.
Key takeaways
GET /auth/management-keys/validationchecks the validity of your management key- Integrate validation into your script startup and monitoring
- Regularly audit all keys to detect overly broad access
- Separate keys by environment and responsibility
- Alert immediately on an invalid key (expired or deleted)