Security
Authentication, authorization, secrets management, and security hardening in RAG DB
RAG DB follows a zero-trust, defense-in-depth approach. No secrets are stored in application code or configuration files. All inter-service communication uses managed identity, and all external access is authenticated.
Managed Identity
RAG DB uses a user-assigned managed identity for all Azure service interactions. No credentials are stored in environment variables, Key Vault, or application code for service-to-service calls.
The managed identity authenticates to:
- Azure Cosmos DB
- Azure Blob Storage
- Azure Key Vault
- Azure Service Bus
- Azure OpenAI
- Azure Container Registry
Why user-assigned over system-assigned: User-assigned identities survive resource recreation and can be shared across services in the same trust boundary, simplifying RBAC management.
Auth0 Integration
External API access is authenticated through Auth0 using the OAuth2 authorization code flow.
Key properties:
- Tokens are issued by Auth0 and validated on every API request
- Session cookies are set with
HttpOnly,Secure, andSameSite=Laxflags HttpOnlyprevents JavaScript from reading the cookie (mitigates XSS)Secureensures cookies are only sent over HTTPSSameSite=Laxprovides baseline CSRF protection
Dual API Keys
Each index in RAG DB has two API keys (key1 and key2) stored in Azure Key Vault. Dual keys enable zero-downtime rotation.
Rotation workflow:
- Call
POST /apiKeys/regeneratewith the key to rotate (key1orkey2) - RAG DB generates a new key and writes it to Key Vault
- Update your client to use the new key
- The old key is invalidated immediately upon regeneration
Both keys are valid simultaneously until one is explicitly regenerated. This allows you to rotate keys without coordinating a simultaneous update across all clients.
User Delegation SAS Tokens
When search results include source document download URLs, RAG DB generates User Delegation SAS tokens rather than using storage account keys.
Properties:
- Container-scoped — each token grants read access only to the specific blob container, not the entire storage account
- Read-only — tokens permit
Readoperations only; no write, delete, or list permissions - 7-day maximum validity — token lifetime is configurable via
SAS_TOKEN_TTL_DAYS(default: 7 days) - No account keys involved — tokens are signed using Azure AD credentials obtained through the managed identity
- Graceful degradation — if SAS generation fails, the download URL is omitted from the response; the search result is still returned
Key Vault Secret Management
RAG DB uses two Key Vault instances to separate concerns:
| Vault | Purpose | Examples |
|---|---|---|
| Environment vault | Infrastructure secrets shared across services | Cosmos DB connection strings, Service Bus connection strings |
| Application vault | Application-level secrets specific to RAG DB | API keys (key1/key2), Auth0 client secrets |
Secrets are accessed at runtime through the managed identity. No secrets are cached in memory beyond the current request lifecycle.
RBAC Roles
The managed identity is assigned the minimum set of Azure RBAC roles required for operation:
| Role | Scope | Purpose |
|---|---|---|
| Storage Blob Data Reader | Storage account | Read source documents from blob containers |
| Storage Blob Delegator | Storage account | Generate user delegation SAS tokens |
| Key Vault Administrator | Key Vault | Read and write secrets (API key rotation) |
| ACR Pull | Container Registry | Pull container images for deployment |
| Resource Group Contributor | Resource group | Manage Service Bus queues dynamically |
| Cosmos DB Data Contributor | Cosmos DB account | Read and write documents, create containers |
| Service Bus Data Sender | Service Bus namespace | Send messages to processing queues |
| Service Bus Data Owner | Service Bus namespace | Manage queues and subscriptions for dynamic index provisioning |
Application Security
No Secrets in Logs
All logging is sanitized. Connection strings, tokens, API keys, and request bodies containing sensitive data are never written to stdout, stderr, or application logs.
Parameterized Cosmos Queries
All Cosmos DB queries use parameterized syntax to prevent injection attacks:
# Correct: parameterized query
query = "SELECT * FROM c WHERE c.indexName = @indexName"
parameters = [{"name": "@indexName", "value": index_name}]
# Never: string interpolation
query = f"SELECT * FROM c WHERE c.indexName = '{index_name}'"Optimistic Concurrency
Document updates in Cosmos DB use ETag-based optimistic concurrency. Every write includes an if-match condition with the document's current ETag. If another process modified the document between read and write, the update fails with a 412 Precondition Failed error and is retried.
This prevents lost updates in concurrent indexing scenarios without requiring distributed locks.
CORS Configuration
Cross-Origin Resource Sharing is configured to allow only explicitly listed origins. The CORS policy:
- Restricts
Access-Control-Allow-Originto known frontend domains - Limits allowed HTTP methods to those actually used by the API
- Does not use wildcard (
*) origins in production