# Security Guide
Operational security guidance for SqlAugur — credential management, login and user hardening, and connection security. For an overview of query validation, parameter blocking, and rate limiting, see the [Security section in the README](README.md#security).
## Connection Security and Credential Management
**Recommended: Use Windows Authentication or Azure Managed Identity**
The most secure authentication methods avoid storing credentials in configuration files entirely:
**Windows Authentication (on-premises or domain-joined environments):**
```json
{
"SqlAugur": {
"Servers": {
"production": {
"ConnectionString": "Server=myserver;Database=master;Integrated Security=True;TrustServerCertificate=False;Encrypt=True;"
}
}
}
}
```
**Azure Managed Identity (Azure SQL Database):**
```json
{
"SqlAugur": {
"Servers": {
"azure-prod": {
"ConnectionString": "Server=myserver.database.windows.net;Database=master;Authentication=Active Directory Managed Identity;TrustServerCertificate=False;Encrypt=True;"
}
}
}
}
```
**If SQL Authentication is Required:**
When Windows Authentication or Managed Identity are not available, follow these practices:
1. **Never commit credentials to source control** — `appsettings.json` is already gitignored, but ensure you never commit credentials in example files or documentation
2. **Use .NET configuration environment variable overrides** — .NET's `IConfiguration` system supports overriding any config value via environment variables using the `__` (double-underscore) separator. This is the recommended approach for injecting credentials without putting them in config files:
Start with a connection string template in `appsettings.json` (no password):
```json
{
"SqlAugur": {
"Servers": {
"production": {
"ConnectionString": "Server=myserver;Database=master;User Id=sqlreader;Encrypt=True;TrustServerCertificate=False;"
}
}
}
}
```
Then override the full connection string (including the password) via an environment variable:
```bash
export SqlAugur__Servers__production__ConnectionString="Server=myserver;Database=master;User Id=sqlreader;Password=your-secure-password;Encrypt=True;TrustServerCertificate=False;"
dotnet run --project SqlAugur
```
> **Note:** Some MCP clients (e.g., Claude Desktop) support `${ENV_VAR}` substitution syntax in their own configuration files, but this is **not a .NET feature** — .NET's `IConfiguration` system does not resolve `${...}` placeholders in values. Do not rely on this syntax in `appsettings.json`. Use the `__` environment variable override pattern shown above, or inject credentials through your MCP client's own environment variable support.
3. **Use secure credential stores:**
**Azure Key Vault** — native integration is built in. Set `AzureKeyVaultUri` in your `appsettings.json` to your vault URI:
```json
{
"SqlAugur": {
"AzureKeyVaultUri": "https://myvault.vault.azure.net/"
}
}
```
Then store connection strings as Key Vault secrets. For example, a secret named `SqlAugur--Servers--production--ConnectionString` would map to the connection string for a server named 'production'
Authentication uses [`DefaultAzureCredential`](https://learn.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential), which automatically tries Managed Identity, Azure CLI, Visual Studio, environment variables, and other methods in order. No additional authentication configuration is needed in most environments.
**AWS Secrets Manager** — use a wrapper script to inject credentials via environment variables before starting SqlAugur:
```bash
#!/usr/bin/env bash
export SqlAugur__Servers__production__ConnectionString=$(
aws secretsmanager get-secret-value \
--secret-id sqlaugur/production \
--query SecretString --output text
)
exec sqlaugur "$@"
```
**HashiCorp Vault** — use a wrapper script to inject credentials via environment variables before starting SqlAugur:
```bash
#!/usr/bin/env bash
export SqlAugur__Servers__production__ConnectionString=$(
vault kv get -field=connection_string secret/sqlaugur/production
)
exec sqlaugur "$@"
```
Point your MCP client at the wrapper script instead of `sqlaugur` directly.
**Windows Credential Manager** — for local development on Windows
4. **Use strong passwords** — use a password manager to generate a long (30+ characters), random password. A random password of this length naturally satisfies Windows complexity requirements. Keep [`CHECK_POLICY`](https://learn.microsoft.com/en-us/sql/relational-databases/security/password-policy) and `CHECK_EXPIRATION` enabled on the SQL login (the SQL Server defaults) to enforce complexity and rotation at the server level.
**Connection String Encryption:**
Always use encrypted connections to protect credentials in transit:
- Set `Encrypt=True` in all connection strings
- Use `TrustServerCertificate=False` for production (only use `True` for development with self-signed certificates)
- Ensure SQL Server has a valid SSL/TLS certificate from a trusted CA
## SQL Server Login and User Recommendations
The SQL Server login and database user used by this MCP server should follow least-privilege principles:
- **Grant read-only access** — the login only needs `SELECT` permission on the databases and schemas it should access. Do not grant `db_datawriter`, `db_ddladmin`, or server-level roles like `sysadmin`.
- **Do not grant EXECUTE on unsafe CLR assemblies** — `SELECT` statements can call user-defined functions, including CLR functions. If a CLR assembly is registered with `EXTERNAL_ACCESS` or `UNSAFE` permission sets, it can perform file I/O, network calls, and other side effects when invoked from a SELECT. The login should not have EXECUTE permission on any such assemblies.
- **Use a dedicated login** — do not reuse logins shared with other applications. A dedicated login makes it easy to audit activity and revoke access independently.
- **Restrict database access** — if the login should only query specific databases, create database users only in those databases. Three-part name queries (`OtherDb.dbo.Table`) are allowed by design, so database-level permissions are the control point.
- **Consider Resource Governor** — for production SQL Server instances, place the login in a Resource Governor workload group with CPU and memory limits to prevent expensive queries from impacting other workloads.