secrets-ts
purpose
Secrets management best practices for Teams bots: environment variables, Key Vault, managed identity, and credential hygiene across development and production environments.
rules
- Never commit secrets to source control. Add
.envto.gitignorebefore the first commit. Create a.env.examplefile with placeholder values and comments documenting each required variable. Scan repositories with tools likegit-secretsor GitHub secret scanning to catch accidental commits. OWASP -- Hard-coded credentials - A Teams bot requires at minimum three secrets for Azure Bot registration:
CLIENT_ID(Azure AD app registration ID),CLIENT_SECRET(app credential), andTENANT_ID(Azure AD tenant). These are configured in theAppconstructor viaclientId,clientSecret, andtenantIdoptions. learn.microsoft.com -- Azure Bot registration - Use Azure Key Vault for all secrets in production environments. Store
CLIENT_SECRET,OPENAI_API_KEY, database connection strings, and any other sensitive values in Key Vault. Access them via Key Vault references in App Settings or programmatically with@azure/keyvault-secrets. learn.microsoft.com -- Key Vault overview - Use managed identity (system-assigned or user-assigned) for zero-secret production deployments. The Teams SDK supports
managedIdentityClientId: "system"or a specific client ID, eliminating the need forCLIENT_SECRETentirely. This also works for accessing Key Vault, Cosmos DB, and Blob Storage without connection strings. learn.microsoft.com -- Managed identity - Apply the least-privilege principle to Azure AD app registrations. Grant only the Microsoft Graph permissions the bot actually needs (e.g.,
User.Readfor profile access, notDirectory.ReadWrite.All). Use delegated permissions where possible (user-level) rather than application permissions (admin-level). Review and remove unused permissions quarterly. learn.microsoft.com -- Graph permissions - Rotate
CLIENT_SECRETbefore expiration. Azure AD app credentials can be set with 6-month, 12-month, or 24-month expiration. Create a new credential before the old one expires, update Key Vault, verify the bot works, then remove the old credential. Automate this with Key Vault rotation policies and Event Grid notifications. learn.microsoft.com -- Credential rotation - Secure API keys (
OPENAI_API_KEY,AZURE_OPENAI_API_KEY) with the same rigor as bot credentials. Store in Key Vault, access via managed identity or Key Vault references, and set usage limits/quotas on the OpenAI/Azure OpenAI side to limit blast radius if a key is compromised. learn.microsoft.com -- Azure OpenAI - Never log secrets or tokens. Implement log scrubbing to redact patterns matching API keys, JWTs, and connection strings. The Teams SDK
ConsoleLoggerdoes not automatically redact secrets -- wrap or post-process log output if it might contain token values from error stack traces. OWASP -- Logging Cheat Sheet - Use the Teams SDK
tokenoption for custom credential factories when managed identity does not fit your architecture. The token factory patterntoken: (config) => getToken()lets you integrate with custom secret stores or token services without hardcoding credentials. github.com/microsoft/teams.ts - For local development, use
.envfiles loaded viadotenv(included in the project template vianode -r dotenv/config .). Keep local.envsecrets separate from production secrets. Use Azure CLI login (az login) withDefaultAzureCredentialto access Key Vault and other Azure services locally without storing production secrets on dev machines. learn.microsoft.com -- DefaultAzureCredential
patterns
Secure .env setup and gitignore configuration
shell
# .gitignore — always include these
.env
.env.local
.env.*.local
*.pem
*.key
credentials.json
# .env.example — commit this to document required variables
# Azure Bot Registration (required)