Practical Auth for Functions: API Keys, Signatures, Console Guard, and Safe Defaults¶
Verified status as of March 28, 2026. Runtime note: FastFN auto-installs function-local dependencies from
requirements.txt/package.json; host runtimes are required infastfn dev --native, whilefastfn devdepends on a running Docker daemon.
Why this article matters¶
Security often gets added late, and then teams bolt on too much complexity.
This guide gives a practical baseline you can deploy now: - function-level auth, - strict method and body limits, - console safety, - webhook signature verification pattern.
It is written for builders who want production-safe defaults without enterprise overhead.
Quick docs map¶
- Complete endpoint list: HTTP API
- Function config keys: Function Spec
- Console access model: Console and Admin Access
- Operational hardening: Operational Recipes
- Security internals: Security Model
Security layers in fastfn¶
- Gateway policy from
fn.config.json. - Function-level auth logic inside your handler.
- Console/UI access gates.
You usually need all three.
Layer 1: Lock the gateway policy first¶
Minimal secure fn.config.json example:
{
"timeout_ms": 1500,
"max_concurrency": 5,
"max_body_bytes": 131072,
"invoke": {
"methods": ["POST"],
"summary": "Signed webhook receiver"
}
}
Effects:
- non-POST calls fail with 405,
- huge payloads fail with 413,
- runaway parallel requests fail with 429.
Layer 2: Add function-level API key auth¶
Node example:
exports.handler = async (event) => {
const headers = event.headers || {};
const apiKey = headers['x-api-key'] || headers['X-API-Key'];
const expected = (event.env || {}).MY_API_KEY;
if (!expected || apiKey !== expected) {
return {
status: 401,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ error: 'unauthorized' })
};
}
return {
status: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ok: true })
};
};
Store secret in fn.env.json:
Layer 3: Signature auth for external webhooks¶
For Stripe/GitHub-like integrations, use signature verification on raw body.
Pattern:
1. read raw body from event.body,
2. compute HMAC with shared secret,
3. compare to signature header,
4. reject mismatch with 401.
This is stronger than static API keys for callbacks.
Layer 4: Protect console and admin APIs¶
Recommended platform env:
FN_UI_ENABLED=1
FN_CONSOLE_LOCAL_ONLY=1
FN_CONSOLE_WRITE_ENABLED=0
FN_ADMIN_TOKEN=<strong-random-token>
Meaning: - UI accessible, - local-only by default, - write actions disabled unless admin token is present.
Verification checklist (copy/paste)¶
- Missing API key returns
401. - Wrong method returns
405. - Oversized payload returns
413. - Invalid signature returns
401. - Unauthenticated console write returns
403.
Example curl checks¶
Unauthorized:
Wrong method:
Expected responses should include 401 and 405 respectively.
Common mistakes¶
- Putting secrets in source code instead of
fn.env.json. - Exposing console writes from remote networks.
- Leaving sensitive endpoints open to
GET. - Ignoring
max_body_byteson webhook handlers.
Practical baseline profile¶
Use this as your default for external-facing functions: - methods restricted to minimum required, - body limit under 256 KB unless necessary, - low concurrency for expensive external APIs, - local-only console with token for privileged actions.
Related docs¶
Key takeaway¶
Start with gateway limits and add handler-level auth only where identity actually matters. That combination blocks bad requests early and keeps your auth code short enough to review and test.
What to keep in mind¶
- Put secrets in
fn.env.json, not in source files or copied curl payloads. - Restrict methods and body size before the request reaches your handler.
- Treat public function routes and console/admin endpoints as separate security surfaces.
Which auth pattern fits which job¶
- API keys work well for service-to-service calls and private webhooks.
- Signed payload verification is a good fit when the provider already sends a signature header.
- JWT verification makes sense when another service is responsible for login and token issuance.
See also¶
JWT issuance and verification pattern¶
Recommended architecture:
- issue JWT in a dedicated auth service
- verify signature + expiration in FastFN function helper
- map claims (
sub,scope,aud) to local permissions
Quick verification example:
Expected:
- invalid/expired token ->
401 - missing scope ->
403 - valid token and scope ->
200