Skip to content
Last updated

Configuration & secrets

Every non-trivial function needs configuration: a company name for the welcome message, API keys for upstream services, phone numbers for routing. Sinch Functions draws a hard line between two things:

  • Variables — non-sensitive settings that can live in source control.
  • Secrets — sensitive values that must never touch source control.

They flow through different mechanisms, and the distinction is worth understanding before you start storing things.

Variables vs secrets

VariablesSecrets
ExamplesCompany name, support number, feature flagsAPI keys, passwords, client secrets
Stored insinch.jsonvariablesOS keychain (local) + platform secret store (production)
Committed?Yes — checked into your repoNo — .env is .gitignored by default
Updated withEdit sinch.json + redeploysinch secrets add KEY value
Visible in logsPlain textRedacted
Available asprocess.env.FOO / IConfiguration["FOO"]Same — runtime injects both into env vars

Declaring variables — sinch.json

{
  "name": "my-function",
  "runtime": "nodejs20",
  "variables": {
    "COMPANY_NAME": "Acme Corp",
    "SUPPORT_NUMBER": "+15551234567",
    "ENABLE_RECORDING": "true"
  }
}

Variables are bundled into the deploy and loaded into the runtime's environment on startup. To update one, edit sinch.json and run sinch functions deploy again.

Declaring secrets — .env and sinch secrets

Your project's .env file lists the secret keys your function needs. The values are left empty because the CLI loads them from the OS keychain at dev time.

# .env — keys only, values come from the keychain
PROJECT_ID=
PROJECT_ID_API_KEY=
PROJECT_ID_API_SECRET=
STRIPE_SECRET_KEY=
ELEVENLABS_API_KEY=

Store the values once with the CLI:

sinch secrets add STRIPE_SECRET_KEY sk_live_abc123
sinch secrets add ELEVENLABS_API_KEY ...
sinch secrets list
sinch secrets get STRIPE_SECRET_KEY
sinch secrets delete STRIPE_SECRET_KEY

Secrets are scoped per function — the function name in sinch.json is the keychain namespace. Two functions with different names have isolated secret stores.

Where the keychain actually is

PlatformStorage backend
WindowsWindows Credential Manager
macOSKeychain Access
LinuxSecret Service API (libsecret / GNOME Keyring)

On Linux without a graphical session you may need to install libsecret and configure a keychain daemon.

Reading configuration from your handler

Node.js — createConfig

The richest API is createConfig(context) (aka createUniversalConfig):

import { createConfig } from '@sinch/functions-runtime';

const config = createConfig(context);

const apiKey = config.requireSecret('STRIPE_SECRET_KEY');         // throws if missing
const companyName = config.getVariable('COMPANY_NAME', 'Acme Corp');
const creds = config.getApplicationCredentials();                  // voice app key/secret

if (config.isDevelopment()) { /* local dev only */ }
if (config.isProduction())  { /* deployed only */ }

process.env still works if you want the raw access:

const companyName = process.env.COMPANY_NAME ?? 'Acme Corp';

C# — IConfiguration

C# gets IConfiguration injected into controllers by ASP.NET:

var companyName = Configuration["COMPANY_NAME"] ?? "Acme Corp";
var apiKey = Configuration["STRIPE_SECRET_KEY"]
    ?? throw new InvalidOperationException("STRIPE_SECRET_KEY is required");

IConfiguration reads from environment variables (what the runtime populates from variables + secrets) and from appsettings.json if you have one.

The base Sinch credentials

Every function needs three environment variables for the Sinch SDK clients to initialize. They come from sinch auth login and are stored in your OS keychain:

VariableSource
PROJECT_IDsinch auth login
PROJECT_ID_API_KEYsinch auth login
PROJECT_ID_API_SECRETsinch auth login

These are automatically injected during sinch functions dev and shipped with each deploy — you do not need to manage them in .env yourself.

Environment variables that unlock SDK clients

The runtime initializes a Sinch SDK client only if its required environment variables are present. Set these either via sinch.json variables (if they are non-secret identifiers) or via sinch secrets add (if they are credentials).

ClientRequired variables
VoiceVOICE_APPLICATION_KEY, VOICE_APPLICATION_SECRET
ConversationCONVERSATION_APP_ID (+ optional CONVERSATION_REGION: US/EU/BR)
SMSSMS_SERVICE_PLAN_ID
NumbersENABLE_NUMBERS_API=true
Verification (C#)VERIFICATION_APPLICATION_ID, VERIFICATION_APPLICATION_SECRET

If a variable is missing, the corresponding context.voice / context.conversation / etc. property is null and you should check before using it.

Environment detection

The runtime sets these automatically:

EnvironmentNode.jsC#
Local devNODE_ENV=developmentASPNETCORE_ENVIRONMENT=Development
ProductionNODE_ENV=productionASPNETCORE_ENVIRONMENT=Production

Use them for dev-only logging, feature toggles, or bypassing integrations that do not exist locally.

How it all flows together

sinch auth login ──▶ OS keychain ──┐

sinch secrets add KEY val ─▶ keychain┤
                                    ├──▶ sinch functions dev  ──▶ process.env in your local runtime
sinch.json (variables)      ────────┤

sinch.json (variables)      ────────┤
                                    ├──▶ sinch functions deploy ─▶ Sinch platform secret store ─▶ process.env in production
sinch secrets add KEY val ─▶ keychain┘

The CLI reconciles the three sources (keychain, sinch.json, .env) at deploy time, uploads everything, and the platform injects the final set as environment variables when your container starts. Secrets are encrypted at rest on the platform and redacted from logs.