Key Anatomy
Every ZendFi API key follows a predictable format:| Prefix | Mode | Environment |
|---|---|---|
zfi_test_ | Test | Solana Devnet |
zfi_live_ | Live | Solana Mainnet |
Key Lifecycle
Creation
When a key is created, the full key value is returned exactly once. After that, only the prefix is available through the API or CLI.Storage on the Server
ZendFi never stores your raw API key:- The key prefix is stored in plaintext for display purposes.
- A SHA-256 hash is stored for fast lookup during authentication.
- An Argon2id hash is stored for brute-force-resistant verification.
Rotation
Rotation generates a new key and immediately invalidates the old one:- Generate the new key
- Update all services and environments
- Verify the new key works
- The old key is already invalid
Revocation
Keys can be permanently revoked through the dashboard or API. Revoked keys cannot be restored.Storage Best Practices
Environment Variables
The simplest and most portable approach:ZENDFI_API_KEY from the environment. No configuration code needed.
Secrets Managers
For production deployments, use a dedicated secrets manager:| Platform | Service |
|---|---|
| AWS | AWS Secrets Manager or SSM Parameter Store |
| GCP | Google Secret Manager |
| Azure | Azure Key Vault |
| Kubernetes | Kubernetes Secrets |
| Vercel | Environment Variables (encrypted at rest) |
| Railway | Variables (encrypted at rest) |
What NOT to Do
Key Scoping
Keys can be scoped to limit their permissions. This follows the principle of least privilege:| Scope | Permissions |
|---|---|
full_access | All operations (default) |
payments_read | Read payment data only |
payments_write | Create and manage payments |
webhooks_manage | Manage webhook endpoints |
keys_manage | Manage API keys |
Example: Read-Only Key for Analytics
Create a key that can only read payment data for your analytics dashboard:GET /payments and GET /payments/:id but will receive a 403 Forbidden if it tries to create a payment.
Rate Limits
API key operations have their own rate limits, separate from general API limits:| Operation | Limit | Window |
|---|---|---|
| List keys | 30 requests | 1 minute |
| Create key | 10 requests | 1 minute |
| Rotate key | 5 requests | 1 minute |
| Payment API | 50 requests | 1 hour |
| Dashboard API | 200 requests | 1 hour |
| Other API | 100 requests | 1 hour |
429 Too Many Requests with headers indicating when you can retry:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per window |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Audit Trail
Every key operation is logged in the audit trail:- Key creation (who, when, name, mode)
- Key rotation (who, when, key ID)
- Key usage (timestamp, endpoint, IP address, response status)
Incident Response
If you suspect a key has been compromised:- Rotate immediately:
zendfi keys rotate <key-id> - Check the audit log for any unauthorized usage
- Update all services with the new key
- Review access to determine how the key was exposed
- Harden storage based on findings (move to secrets manager, add IP restrictions, etc.)