> ## Documentation Index
> Fetch the complete documentation index at: https://docs.soundchecklive.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Key Vault

> Azure Key Vault configuration and secret management

Soundcheck uses Azure Key Vault to securely store and manage sensitive configuration values. This provides centralized secret management with audit trails and secure access through managed identities.

## Overview

The infrastructure stores sensitive environment variables in Azure Key Vault instead of directly in App Service settings:

### Benefits

| Benefit | Description |
| - | - |
| **Centralized Management** | All secrets in one secure location |
| **Managed Identity Access** | No credentials stored in application |
| **Audit Trails** | Track all secret access and modifications |
| **Secret Rotation** | Rotate secrets without redeployment |
| **Private Access** | Key Vault accessible only via private endpoint |

***

## Secrets stored

| Secret Name | Purpose | Used By |
| - | - | - |
| `next-public-api-password` | Frontend API authentication | Web App |
| `next-public-api-username` | Frontend API authentication | Web App |
| `clerk-secret-key` | Clerk authentication | Web App |
| `administrator-password` | Database admin password | Backend |
| `docker-registry-server-password` | Container registry | Backend |
| `postgres-database-url` | Database connection string | Backend |
| `sentry-dsn` | Error tracking | All services |
| `qb-client-id` | QuickBooks OAuth app client ID | Backend |
| `qb-client-secret` | QuickBooks OAuth app client secret | Backend |
| `credential-encryption-key` | AES key for QB OAuth token encryption | Backend |
| `google-maps-server-api-key` | Server-only Google Maps/Places key for place photo proxy (`GOOGLE_MAPS_SERVER_API_KEY` on api-events). Populate per env (dev/qa/prod); do not reuse the browser Maps key | Backend |

***

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                      Azure Key Vault                        │
│                                                             │
│  ┌─────────────────┐  ┌─────────────────┐                  │
│  │ Frontend Secrets │  │ Backend Secrets │                  │
│  │                  │  │                  │                  │
│  │ • clerk-secret   │  │ • database-url   │                  │
│  │ • api-password   │  │ • admin-password │                  │
│  │ • api-username   │  │ • registry-pass  │                  │
│  └─────────────────┘  └─────────────────┘                  │
└─────────────────────────────────────────────────────────────┘
                            │
                   Private Endpoint
                            │
              ┌─────────────┴─────────────┐
              │                           │
    ┌─────────┴─────────┐       ┌────────┴────────┐
    │   Web App Service  │       │   API App Service│
    │                    │       │                  │
    │  Managed Identity  │       │  Managed Identity│
    │  (Key Vault Reader)│       │  (Key Vault Reader)│
    └────────────────────┘       └──────────────────┘
```

***

## Configuration

### App service Key Vault references

App Services use Key Vault references instead of direct values:

```hcl theme={null}
# Frontend app_settings
app_settings = {
  CLERK_SECRET_KEY = "@Microsoft.KeyVault(SecretUri=${var.clerk_secret_key_secret_uri})"
  NEXT_PUBLIC_API_PASSWORD = "@Microsoft.KeyVault(SecretUri=${var.api_password_secret_uri})"
}

# Backend app_settings
app_settings = {
  DATABASE_URL = "@Microsoft.KeyVault(SecretUri=${var.postgres_database_url_secret_uri})"
}
```

### Terraform module structure

```
modules/security/
├── main.tf           # Key Vault and secrets
├── variables.tf      # Secret value inputs
└── outputs.tf        # Secret URI outputs
```

***

## Network security

### Private endpoint

Key Vault is only accessible through a private endpoint:

* **Subnet**: Dedicated private endpoint subnet (10.0.2.0/24)
* **DNS Zone**: `privatelink.vaultcore.azure.net`
* **NSG**: HTTPS traffic only

### Access control

| Principal | Role | Scope |
| - | - | - |
| Managed Identity | Key Vault Secrets Officer | Key Vault |
| DevOps Pipeline | Key Vault Administrator | Key Vault |

***

## Adding new secrets

**1. Add secret resource**

In `modules/security/main.tf`:

```hcl theme={null}
resource "azurerm_key_vault_secret" "new_secret" {
  name         = "new-secret-name"
  value        = var.new_secret_value
  key_vault_id = azurerm_key_vault.main.id
}
```

**2. Add variable**

In `modules/security/variables.tf`:

```hcl theme={null}
variable "new_secret_value" {
  description = "Description of the secret"
  type        = string
  sensitive   = true
}
```

**3. Add output**

In `modules/security/outputs.tf`:

```hcl theme={null}
output "new_secret_uri" {
  value = azurerm_key_vault_secret.new_secret.id
}
```

**4. Update consuming module**

Pass the secret URI to the frontend or backend module.

***

## Troubleshooting

> [accordion] Access Denied
>
> Verify managed identity has proper RBAC permissions:
>
> ```bash theme={null}
> az role assignment list --assignee <managed-identity-principal-id>
> ```

> [accordion] DNS Resolution Failed
>
> Check private DNS zone is linked to VNet:
>
> ```bash theme={null}
> nslookup <vault-name>.vault.azure.net
> ```

> [accordion] Secret Already Exists
>
> Soft-delete the existing secret:
>
> ```bash theme={null}
> az keyvault secret delete \
>   --vault-name <vault-name> \
>   --name <secret-name>
> ```

> [accordion] App Service Can't Read Secret
>
> 1. Verify Key Vault reference syntax is correct
> 2. Check managed identity assignment on App Service
> 3. Verify private endpoint connectivity

***

## Vault names by environment

| Environment | Key Vault Name |
| - | - |
| Dev | `dev01-cus-core-kv` |
| QA | `qa01-cus-core-kv` |
| Prod | `prod-cus-core-kv` |

***

## Best practices

1. **Never log secrets** - Use Key Vault references, not direct values
2. **Regular rotation** - Implement secret rotation procedures
3. **Minimal access** - Apply principle of least privilege
4. **Monitor access** - Enable Key Vault logging and alerts
5. **Backup** - Ensure Key Vault has backup and recovery enabled


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.