Start here
0.12.0 Migration Guide
Recreate API keys after the upgrade, because v0.12.0 stores only a SHA-256 hash.
This migration guide covers the breaking changes introduced in Blnk v0.12.0, specifically related to API key security enhancements. The main change implements SHA-256 hashing for API keys, which affects how API keys are stored and retrieved.
Breaking changes summary
- From: API keys stored in plain text, retrievable from list endpoint
- To: API keys hashed using SHA-256, plain text only available during creation
- Impact: Once upgraded, existing API keys will return authentication errors when used. You must recreate API keys after upgrading.
What changed
- API key hashing: API keys are now hashed using SHA-256 before being stored in the database.
- Plain text key availability: The plain text key is only returned during API key creation (
POST /api-keys). - List endpoint behavior: When listing API keys (
GET /api-keys?owner=<owner_id>), thekeyfield now returns the hashed version instead of the plain text key. - Security enhancement: Plain text keys cannot be retrieved after creation for security reasons.
What still works
- Creating API keys: Plain text key is returned during creation.
- Authentication: The system automatically hashes incoming keys for comparison.
- API key management: Listing, revoking, and checking status still work.
Migration steps
Review your API key usage
Identify all places in your codebase where API keys are retrieved or used:
- Check for code that reads API keys from
GET /api-keys- Any code that expects to use the
keyfield from list responses. - Automation scripts that retrieve keys after creation.
- Migration scripts that read existing API keys.
- Any code that expects to use the
- Identify API key storage locations
- Where you currently store API keys.
- How you retrieve them for authentication.
- Any caching mechanisms that rely on plain text keys.
Update API key creation workflow
Ensure you store the plain text key immediately after creation:
curl -X POST "http://localhost:5001/api-keys" \
-H "X-blnk-key: <master-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "My API Key",
"owner": "my-owner-id",
"scopes": ["ledgers:read", "balances:write"],
"expires_at": "2026-12-31T23:59:59Z"
}'{
"api_key_id": "api_key_123...",
"key": "g-nnlP_kfxOP42baBGFJ",
"name": "My API Key",
"owner_id": "my-owner-id"
}Store the key securely:
- Environment variables.
- Secret management systems (AWS Secrets Manager, HashiCorp Vault, etc.).
- Secure configuration files (excluded from version control).
Update existing code
Remove any code that expects plain text keys from the list endpoint:
const response = await fetch('/api-keys?owner=my-owner');
const keys = await response.json();
const apiKey = keys[0].key;const createResponse = await fetch('/api-keys', {
method: 'POST',
headers: {
'X-Blnk-Key': masterKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'My Key',
owner: 'my-owner',
scopes: ['*:*'],
expires_at: '2026-12-31T23:59:59Z'
})
});
const newKey = await createResponse.json();
const plainTextKey = newKey.key;
const authHeaders = {
'X-Blnk-Key': plainTextKey
};The list response key is now a hash, so using it for authentication fails. Store the plain text key from the create response and send that stored value on later requests.
Migrate existing API keys
Before upgrading, or immediately after:
- Identify all existing API keys that are currently in use.
- Create new API keys with the same scopes and permissions.
- Store the new plain text keys securely immediately after creation.
- Update your applications to use the new keys.
- Test authentication with the new keys.
- Revoke old API keys once migration is complete.
Verify authentication
Test that authentication works correctly:
curl -X GET "http://localhost:5001/ledgers" \
-H "X-blnk-key: <your-stored-plain-text-key>"Authentication works with the stored plain text key. The system hashes incoming keys and compares them with the stored hashes.
Security benefits
- Secure storage: API keys are stored as hashes, not plain text.
- Database protection: Even if the database is compromised, plain text keys cannot be extracted.
- Best practices: Follows security best practices for credential storage.
- Reduced exposure risk: Reduces risk of key exposure through logs or database dumps.
Technical details
- Hashing algorithm: SHA-256.
- Authentication: System handles hashing automatically during authentication.
- Caching: API key caching has been improved for better performance.
- Cache invalidation: Occurs automatically when keys are revoked.