This guide explains how to generate, use, and manage your Phoenix Security platform API keys directly from your account dashboard — without needing admin intervention.
A platform API key authenticates your applications, scripts, and CI pipelines when they call Phoenix Security APIs. There are four categories, each for a different purpose — and a different key prefix so they can be rate-limited and revoked independently:
| Category | What it's for | Header value starts with |
|---|---|---|
| Vulnerability Fetch | CVE lookups, search, batch enrichment over REST and GraphQL | phx_api_basic_, phx_api_power_, phx_api_int_, phx_api_unl_ |
| MCP Client | Connect Claude / Continue / Cursor / any MCP-capable client to Phoenix as a data source | phx_mcp_ |
| Malware Firewall | phoenix-firewall CLI, agent, GitHub Action, and CI gates that retrieve rules and block malicious packages | phx_fw_ |
| Webhook Ingress | Inbound GitHub PR diff, GitLab MR, Jenkins / Azure DevOps callbacks into /api/v1/firewall/webhook/scan | phx_whk_ |
403 scope not permitted. This is intentional: a leaked CI webhook key cannot drain your interactive-fetch quota, and a leaked Fetch key cannot block packages in production.https://phxintel.security (or https://phxintel.appsecphoenix.io for pre-prod).prod-scanner, gha-firewall, github-pr-webhook), pick an Expires value (30–365 days), click Generate Key.All keys are sent in the same header on every request:
X-API-Key: phx_api_basic_…
Authorization: ApiKey … and Authorization: Bearer phx_… are also accepted.
curl -H "X-API-Key: phx_api_basic_xxxx…" \
https://phxintel.security/api/v1/cves/CVE-2024-3094
curl -X POST https://phxintel.security/api/v1/graphql \
-H "X-API-Key: phx_api_power_xxxx…" \
-H "Content-Type: application/json" \
-d '{"query":"{ cve(id: \"CVE-2024-3094\") { id ps_hp { score } } }"}'
~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"phoenix-security": {
"url": "https://phxintel.security/api/v1/mcp",
"headers": { "X-API-Key": "phx_mcp_xxxx…" }
}
}
}
export PHOENIX_FW_API_KEY=phx_fw_xxxx… phoenix-firewall scan ./package-lock.json
- uses: Security-Phoenix-demo/phoenix-firewall-action@v1
with:
api-key: ${{ secrets.PHOENIX_FW_API_KEY }}
# List the rules attached to your account (what blocks what):
curl -H "X-API-Key: $PHOENIX_API_KEY" \
https://phxintel.security/api/v1/firewall/rules
# Evaluate a package:
curl -X POST https://phxintel.security/api/v1/firewall/evaluate \
-H "X-API-Key: $PHOENIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"packages":[{"ecosystem":"npm","name":"lodash","version":"4.17.21"}]}'
curl -X POST https://phxintel.security/api/v1/firewall/webhook/scan \
-H "X-API-Key: phx_whk_xxxx…" \
-H "Content-Type: application/json" \
-d '{
"source": "github-actions",
"event_type": "pull_request",
"repository": "acme/web",
"ref": "refs/pull/42/head",
"lockfiles": [{"path":"package-lock.json","content":"..."}],
"callback_url": "https://ci.acme.com/hooks/phoenix"
}'
| Capability | Registered | Pro (Premium) | Enterprise (Premium Plus) |
|---|---|---|---|
| Vulnerability Fetch (REST/GraphQL) | Basic | Power / Integration | Unlimited |
| MCP Client | No | Yes | Yes |
| Malware Firewall | Yes | Yes | Yes |
| Webhook Ingress | No | Yes | Yes |
| Max active keys | 1 (30-day, one-time issuance) | 5 | Unlimited |
| Rate limit / hour (fetch) | 100 | 5,000 | 50,000 |
| Rate limit / hour (MCP) | — | 500 | 5,000 |
| Rate limit / hour (firewall) | 1,000 | 1,000 | 1,000 |
| Rate limit / hour (webhook) | — | 5,000 | 5,000 |
Free-tier users do not get platform API keys. Upgrade to Registered for self-service.
| Action | Where | Notes |
|---|---|---|
| Create | My Account → Platform API Keys → Generate | Secret shown once |
| List | Same panel, "Your Keys" table | Shows prefix, scope, last-used, expiry |
| Revoke | Revoke button in row | Takes effect within seconds across all edges. Intel Bundle and Malware Firewall keys can also be revoked by an org admin or the key's team admin |
| Rotate | Rotate button (Intel Bundle and Malware Firewall keys) | New key shown once; the old key stops working immediately. The new key keeps the old key's expiry. Org admins and the key's team admin can rotate too and must hand the new key to the owner (POST /api/v1/user/me/api-keys/{key_id}/rotate). Other categories: revoke + create new |
| Auto-expiry | At the Expires date you picked | Pick short TTLs and re-issue on a cron for production |
.env, GitHub Actions secrets, or your secret manager.dev, staging, prod) — easy to revoke without taking down everything.phoenix-firewall calls, not a Fetch key — keeps rate-limit buckets isolated.| Symptom | Likely cause | Fix |
|---|---|---|
401 Invalid or expired API key | Key revoked, expired, or typo | Check the key prefix; re-issue from the dashboard |
403 scope not permitted | Used a Fetch key against MCP or Firewall endpoint (or vice versa) | Generate a key of the correct category |
429 Rate limit exceeded | Burst exceeded minute/hour/day cap | Check X-RateLimit-Remaining header; back off; or upgrade tier |
| Generation button disabled | Tier doesn't grant that category, or max-active-keys reached | Revoke unused keys, or upgrade tier |
| Key works locally but not in CI | Secret quoted/escaped incorrectly in CI store | Re-paste with no leading/trailing whitespace |
Can I share a key across my team?
No — each key is tied to the user who created it for audit purposes. Use a service account if you need shared credentials.
Is there a separate key for the Phoenix Firewall agent (phx_fwagent_*)?
Yes, but that key is provisioned via phoenix-firewall enroll — with an existing platform API key (phoenix-firewall enroll --api-key <phx_fw_ key>), with a one-time bootstrap token you self-generate (phoenix-firewall enroll --bootstrap-token <token>; see §9.4, flag-gated), or with a one-time bootstrap token issued by your global admin. None of these mint a raw agent key directly from this dashboard. Use a phx_fw_* Malware Firewall key for CLI / CI / agent-bridge flows.
What's the difference between phx_api_basic_ and phx_api_unl_?
Just the rate-limit tier. Endpoints and response payloads are identical (modulo tier-based field redaction enforced server-side by data_shield).
Can I get a key without expiry?
No. All self-service keys must expire (max 365 days). This is a security guard, not a billing limit.
phoenix-firewall CLIThe same phx_fw_* key works across all official Phoenix Firewall clients. Both repos read the key from the standard environment variable / config slot:
# Option A — env var (recommended for CI): export PHOENIX_API_KEY=phx_fw_xxxxxxxx... phoenix-firewall scan ./package-lock.json # Option B — config.toml (recommended for laptops): # ~/.config/phoenix-firewall/config.toml api_key = "phx_fw_xxxxxxxx..." api_url = "https://phxintel.security"
| Subcommand | Endpoint | Works with phx_fw_* |
|---|---|---|
scan | POST /api/v1/firewall/evaluate | Yes |
doctor | health probe | Yes |
agent-bridge | POST /api/v1/firewall/evaluate | Yes |
enroll | POST /api/v1/firewall/agent/enroll | Yes (bootstrap step only; subsequent calls use phx_fwagent_*) |
system (endpoint mode) | /api/v1/firewall/agent/* | No — requires device-enrolled phx_fwagent_* key |
export PHOENIX_API_KEY=phx_fw_xxxxxxxx... npx @phoenix-security/cli scan ./package.json npx @phoenix-security/cli install-hooks npx @phoenix-security/mcp-firewall
- uses: Security-Phoenix-demo/phoenix-firewall-action@v1
with:
api-key: ${{ secrets.PHOENIX_API_KEY }}
phx_fwenroll_*, single-use)As an alternative to enroll --api-key, a logged-in user can generate a single-use enrollment token instead of handing a reusable phx_fw_* key to a device:
POST /api/v1/firewall/enrollment-tokens (JWT/cookie auth; see the Public REST API reference for the full request/response contract).phoenix-firewall enroll --bootstrap-token <token>.phoenix-firewall enroll --bootstrap-token phx_fwenroll_xxxxxxxx...
The token is prefixed phx_fwenroll_, is single-use (rejected on a second redemption attempt), and self-binding — the enrolling device binds itself to the token on first use, so no pre-registration step is required. Tokens expire after ttl_hours (default 168h / 7 days, max 720h / 30 days).
enable_firewall_enrollment_token_issuance, default off, plus the master enable_firewall_endpoint_mode gate) and requires the caller's org to hold an active api_firewall entitlement; the issuance endpoint returns 404 when either flag is off or the entitlement is missing, so its existence is not leaked to ineligible accounts.