Team Practices
What to commit, what not to, how to onboard a new developer, and how to handle secrets — the conventions the whole team follows.
Commit vs. Do Not Commit
| File | Commit? | Reason |
|---|---|---|
appsettings.json | Yes | Base defaults, machine-neutral |
appsettings.Development.json | Yes | Dev feature flags, log levels |
appsettings.Staging.json | Yes | Staging non-secret settings |
appsettings.Production.json | Yes | Prod non-secret settings (log levels, sampling) |
appsettings.Tenant.{code}.json | Yes | Tenant feature flags, topic names, model selection |
appsettings.Tenant.{code}.development.json | Yes | Shared dev DB (if team shares a dev DB) |
launchSettings.json | Yes | Env var names and ports — no secrets |
appsettings.Development.Local.json | Never | Your machine's SQL Server name |
appsettings.Staging.Local.json | Never | Machine-local overrides |
appsettings.Tenant.{code}.production.json | Never | Real credentials and production addresses |
appsettings.Tenant.{code}.staging.json | Never | Staging credentials |
| Any file with a password or API key | Never | Use a vault; inject at deploy time |
gitignore Rules
These patterns are already in .gitignore at the root of the repository:
appsettings.Local.json
appsettings.*.Local.json
**/appsettings.Local.json
**/appsettings.*.Local.json
For tenant production/staging files that should never be committed, add:
**/appsettings.Tenant.*.production.json
**/appsettings.Tenant.*.staging.json
Alternatively, manage tenant env files entirely outside the repository — deploy them from a secrets manager rather than keeping them in the repo at all.
Onboarding a New Developer
Clone the repository
git clone https://github.com/bizfirstai/BizFirstPayrollV3.git
Create appsettings.Development.Local.json
In src/mvc-server/Solutions/AiUltimate/BizFirst.Ai.Consolidated.WebApi/,
create the file with their machine's SQL Server name.
Full template in Local Setup.
Verify launchSettings.json
Confirm ASPNETCORE_ENVIRONMENT=Development and TENANT_CODE
is set to the tenant they are working on.
Run the app
Press F5 or dotnet run. The app connects to their local SQL instance.
Confirm git will not stage the Local file
git status
appsettings.Development.Local.json must not appear. If it does, check .gitignore.
Keeping appsettings.json Neutral
The base file must use placeholder connection strings that are safe to commit.
The placeholder .\SQLEXPRESS is acceptable — it either works on developer machines
that happen to have a default SQLEXPRESS instance, or it gets overridden by each developer's Local file.
appsettings.json to contain a specific machine name like
LAPTOP-XYZ\SQLEXPRESS or a network address like sql.apexretail.local,
reject it and ask the author to move the value to their Local file.
CI/CD Pipeline Practices
| Practice | How |
|---|---|
| Set environment | ASPNETCORE_ENVIRONMENT as a secure pipeline variable |
| Set tenant | TENANT_CODE as a secure pipeline variable |
| Deploy tenant credentials | Fetch from Azure Key Vault / AWS Secrets Manager → write appsettings.Tenant.{code}.production.json at deploy time |
| Never store secrets in the repo | Even in branches or tags — secrets in git history are permanent leaks |
Code Review Checklist
appsettings.jsoncontains no machine names, IPs, or passwords- No
*.Local.jsonfiles are staged or committed - Tenant production/staging files are not committed
launchSettings.jsoncontains no passwords or live API keys (env var names are fine, values are not)- New config keys in base files have sensible neutral defaults
- New tenant-specific keys are documented
Secrets Policy
| Secret | Where to store |
|---|---|
| JWT signing key | Vault; injected at deploy time into Tenant.{code}.production.json |
| Database passwords | Vault |
| Kafka credentials | Vault |
| OpenAI / LLM API keys | Vault |
| Google SSO client secret | Vault |
| Grafana API key | Vault |
| Secrets on developer machines | appsettings.Development.Local.json — gitignored, never leaves the machine |