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:

  1. Quick Start Guide β€” Get up and running in 5 minutes
  2. JavaScript Tutorial β€” Complete guide for Node.js/Next.js developers
  3. 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

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:

javascript
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:

javascript
const ogUrl = generateSignedOgUrl({
    template: "ecommerce",
    title: product.name,
    price: product.price,
    image: product.image,
});

Testimonials

Generate OG images for testimonial quotes:

javascript
const ogUrl = generateSignedOgUrl({
    template: "testimonial",
    author_name: user.name,
    author_avatar: user.avatarUrl,
    quote: user.bio,
});

πŸ” Security

Best Practices

  1. Store secrets securely β€” Use environment variables or secrets manager
  2. Never expose HMAC secret in client-side code β€” Sign on server only
  3. Use HTTPS β€” Prevents MITM attacks
  4. Rotate secrets periodically β€” Especially if compromised
  5. Monitor failed signatures β€” Repeated failures may indicate attacks
  6. Per-user isolation β€” Each API key has its own HMAC secret

Getting Your HMAC Secret

  1. Go to Dashboard β†’ API Keys
  2. Create a new API key
  3. Copy the HMAC Secret (shown only once!)
  4. Store in environment variables
bash
# .env
FASTOG_HMAC_SECRET=<your-64-char-hex-secret>

πŸ§ͺ Testing

Generate Test URL

bash
# 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

bash
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

  1. Verify you're using the correct HMAC secret (check API key in dashboard)
  2. Check the canonical query: every query param except s (including key), values rfc3986-encoded, keys sorted lexicographically
  3. Verify signature is lowercase hex (64 characters)

πŸ“– Additional Resources

❓ 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?

Try it free β€” no signup required

Preview and test dynamic OG images in seconds.

Open the Free OG Image Tester