# Protecting Your Function Sinch Functions can require authentication on any handler. When enabled, callers must provide your project's API key and secret via Basic Auth. This lets you expose HTTP endpoints that only your systems can reach. ## How it works 1. You mark which handlers require auth (or all of them) 2. The runtime checks incoming requests for an `Authorization: Basic` header 3. Credentials are validated against `PROJECT_ID_API_KEY` and `PROJECT_ID_API_SECRET` 4. Invalid or missing credentials get a `401 Unauthorized` response Voice callbacks (ICE, ACE, DiCE, PIE) and health checks are **never** auth-gated — they come from the Sinch platform and use webhook signature validation instead. ## Declaring protected handlers Node.js Export an `auth` array with the handler names you want to protect: ```typescript import type { FunctionContext, FunctionRequest } from '@sinch/functions-runtime'; // Protect the 'webhook' handler — callers must authenticate export const auth = ['webhook']; export async function webhook(context: FunctionContext, request: FunctionRequest) { // Only reachable with valid credentials return { received: request.body }; } export async function status(context: FunctionContext, request: FunctionRequest) { // No auth required — not listed in the auth array return { ok: true }; } ``` To protect **all** handlers: ```typescript export const auth = '*'; ``` C# Add the `[Authorize]` attribute to controller actions: ```csharp using Microsoft.AspNetCore.Authorization; public class FunctionController : SinchController { [Authorize] public IActionResult Webhook() { // Only reachable with valid credentials return Ok(new { received = "data" }); } public IActionResult Status() { // No auth required — no [Authorize] attribute return Ok(new { ok = true }); } } ``` ## Credentials Auth uses your Sinch project's API key and secret — the same credentials you use with `sinch auth login`. When deployed, these are injected automatically as environment variables: - `PROJECT_ID_API_KEY` — your project's API key - `PROJECT_ID_API_SECRET` — your project's API secret You don't need to configure anything. The runtime reads these from the environment at startup. ## Local development During local development (`sinch functions dev`), auth is **skipped** when credentials aren't configured. This means you can test your handlers without setting up auth locally. > **If you run `sinch functions dev` with a public tunnel**, your local server is reachable from the internet for the duration of the dev session. With auth skipped, any endpoint you marked as protected is effectively open to the world during that window. To test auth end-to-end through the tunnel, set the credentials (see below) before starting the dev server. To test auth locally, set the environment variables before starting dev mode: Node.js ```bash PROJECT_ID_API_KEY=mykey PROJECT_ID_API_SECRET=mysecret sinch functions dev ``` C# ```bash PROJECT_ID_API_KEY=mykey PROJECT_ID_API_SECRET=mysecret sinch functions dev ``` ## Testing with curl Once auth is enabled (locally with env vars or after deployment): ```bash # Authenticated request curl -u YOUR_API_KEY:YOUR_API_SECRET https://your-function-url/webhook # This is equivalent to: curl -H "Authorization: Basic $(echo -n 'YOUR_API_KEY:YOUR_API_SECRET' | base64)" \ https://your-function-url/webhook # Without credentials — returns 401 curl https://your-function-url/webhook ``` ## What's not protected These endpoints bypass auth regardless of your configuration: | Endpoint | Reason | | --- | --- | | Voice callbacks (ICE, ACE, DiCE, PIE) | Validated by webhook signature, not Basic Auth | | Health checks (`/health`) | Used by infrastructure for liveness probes |