HMAC Authentication & Security
Secure your HMAC-signed OG image URLs with FastOG's HMAC-SHA256 authentication. This guide covers signing, validating, and troubleshooting every request, so you can ship dynamic Open Graph images on the fly β subscription-based, billed by monthly render quota. Sign up, pick a Dynamic API plan, then create your API key and HMAC secret in the dashboard (paid API renders are clean). Sign on your server once and integrate in minutes.
π Quick Start
New to HMAC signing? Start here:
- Quick Start Guide β Get up and running in 5 minutes
- JavaScript Tutorial β Complete guide for Node.js/Next.js developers
- All framework tutorials β pick your stack:
π Documentation Index
Core Concepts
- HMAC Signature Guide β Complete reference with algorithm details, requirements, and examples in JavaScript, PHP, and Python
- HMAC Validation β Server-side implementation details, security features, and error responses
Tutorials
-
JavaScript/Node.js Tutorial β Comprehensive guide covering:
- Quick Start (5 minutes)
- Next.js App Router (3 patterns)
- Next.js Pages Router
- Express.js Backend
- Vanilla Node.js
- Frontend Integration Patterns (SSG, SSR, Client-Side)
- Testing & Debugging
- Common Pitfalls
Quick Reference
Algorithm
method = "GET"
path = "/api/v1/og"
canonicalQuery = every query param EXCEPT `s` (including `key`): array values sorted too; each pair rfc3986Encode(key)=rfc3986Encode(value); pairs sorted lexicographically and joined with "&"
message = method + path + "\n" + canonicalQuery
signature = hex(HMAC-SHA256(message, hmac_secret))
URL: /api/v1/og?title=Hello&key=sk_quick_123abc&s=<signature>
Query Parameters
| Parameter | Description | Example |
|---|---|---|
key |
Full API key | sk_quick_123abc |
s |
HMAC-SHA256 signature (64 hex chars) | 9f8a1b2c3d4e... |
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
missing_signature |
401 | Missing key or s parameter |
invalid_signature |
401 | Signature doesn't match |
π― Use Cases
Blog Posts
Generate dynamic OG images for blog posts:
const ogUrl = generateSignedOgUrl({
template: "blog",
title: post.title,
subtitle: post.excerpt,
author: post.author.name,
});
// <meta property="og:image" content="{ogUrl}" />
E-commerce Products
Create OG images for product pages:
const ogUrl = generateSignedOgUrl({
template: "ecommerce",
title: product.name,
price: product.price,
image: product.image,
});
Testimonials
Generate OG images for testimonial quotes:
const ogUrl = generateSignedOgUrl({
template: "testimonial",
author_name: user.name,
author_avatar: user.avatarUrl,
quote: user.bio,
});
π Security
Best Practices
- Store secrets securely β Use environment variables or secrets manager
- Never expose HMAC secret in client-side code β Sign on server only
- Use HTTPS β Prevents MITM attacks
- Rotate secrets periodically β Especially if compromised
- Monitor failed signatures β Repeated failures may indicate attacks
- Per-user isolation β Each API key has its own HMAC secret
Getting Your HMAC Secret
- Go to Dashboard β API Keys
- Create a new API key
- Copy the HMAC Secret (shown only once!)
- Store in environment variables
# .env
FASTOG_HMAC_SECRET=<your-64-char-hex-secret>
π§ͺ Testing
Generate Test URL
# Node.js
node -e "
const crypto = require('crypto');
const enc = (s) => encodeURIComponent(s).replace(/[!'()*]/g, (c) => '%' + c.charCodeAt(0).toString(16).toUpperCase());
const all = { title: 'Test', key: 'sk_quick_123abc' };
const pairs = [];
for (const [k, v] of Object.entries(all)) for (const vv of Array.isArray(v) ? v : [v]) pairs.push(enc(k) + '=' + enc(vv));
pairs.sort();
const canonical = pairs.join('&');
const sig = crypto.createHmac('sha256', 'YOUR_HMAC_SECRET').update('GET/api/v1/og\n' + canonical).digest('hex');
console.log('https://fastog.com/api/v1/og?title=Test&key=sk_quick_123abc&s=' + sig);
"
Test with curl
curl "https://fastog.com/api/v1/og?title=Test&key=sk_quick_123abc&s=<signature>"
Expected Responses
- β Valid signature β Returns OG image (or 422 if template params invalid)
- β Invalid signature β
{"code": "invalid_signature"} - β Missing params β
{"code": "missing_signature"}
π Troubleshooting
Signature doesn't match
- Verify you're using the correct HMAC secret (check API key in dashboard)
- Check the canonical query: every query param except
s(includingkey), values rfc3986-encoded, keys sorted lexicographically - Verify signature is lowercase hex (64 characters)
π Additional Resources
- API Reference β Complete API documentation
- Security Best Practices β Detailed security guide
- Knowledge Base β Technical implementation details
β FAQ
Q: Why query parameters instead of headers?
A: OG images are fetched by social network crawlers (LinkedIn, Twitter, Facebook) that don't send custom headers. The signature MUST be in the URL.
Q: Can I use the same signature for multiple requests?
A: Yes. A signature is computed from the exact query (minus s), so the same signed URL stays valid as long as the parameters don't change. Change any parameter (including key) and you must re-sign.
Q: Do I need to sign requests for all templates?
A: Yes. All requests to /api/v1/og require HMAC signatures.
Q: What happens if my HMAC secret is compromised?
A: Revoke the API key in the dashboard and create a new one. Each API key has its own HMAC secret.
Q: Can I disable HMAC validation for internal services?
A: Contact support for custom solutions. HMAC validation is mandatory for all public API endpoints.
π Support
Need help?
- Check the JavaScript Tutorial for complete code examples
- Review the HMAC Signature Guide for algorithm details
- Contact support at [email protected]
Related
- Documentation β All FastOG guides and references
- Free OG Image Testerβ Preview without an account
- Quick Start Guide β Get up and running in 5 minutes
- HMAC Signature Guide β Algorithm details
- HMAC Validation β Server-side validation
Try it free β no signup required
Preview and test dynamic OG images in seconds.
Open the Free OG Image Tester