# Environment Variables

This document describes all environment variables used across The Order monorepo services and applications.

## Table of Contents

- [Required Variables](#required-variables)
- [Optional Variables](#optional-variables)
- [Development Variables](#development-variables)
- [Service-Specific Variables](#service-specific-variables)
- [Configuration Examples](#configuration-examples)

---

## Required Variables

These variables must be set for the application to function properly.

### Database

#### `DATABASE_URL`
- **Type**: String (URL)
- **Required**: Yes
- **Description**: PostgreSQL connection string
- **Format**: `postgresql://user:password@host:port/database`
- **Example**: `postgresql://postgres:password@localhost:5432/theorder`
- **Used By**: All services

### Storage

#### `STORAGE_BUCKET`
- **Type**: String
- **Required**: Yes
- **Description**: S3/GCS bucket name for document storage
- **Example**: `the-order-documents-prod`
- **Used By**: Dataroom, Intake services

#### `STORAGE_TYPE`
- **Type**: Enum (`s3` | `gcs`)
- **Required**: No (default: `s3`)
- **Description**: Storage provider type
- **Example**: `s3`
- **Used By**: Dataroom, Intake services

#### `STORAGE_REGION`
- **Type**: String
- **Required**: No (default: `us-east-1`)
- **Description**: AWS region for S3 or GCS region
- **Example**: `us-east-1`
- **Used By**: Dataroom, Intake services

#### `AWS_ACCESS_KEY_ID`
- **Type**: String
- **Required**: No (uses IAM role if not provided)
- **Description**: AWS access key ID for S3 access
- **Used By**: Storage client

#### `AWS_SECRET_ACCESS_KEY`
- **Type**: String
- **Required**: No (uses IAM role if not provided)
- **Description**: AWS secret access key for S3 access
- **Used By**: Storage client

### Key Management System (KMS)

#### `KMS_KEY_ID`
- **Type**: String
- **Required**: Yes
- **Description**: KMS key identifier for encryption and signing
- **Example**: `arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012`
- **Used By**: Identity service, Crypto package

#### `KMS_TYPE`
- **Type**: Enum (`aws` | `gcp`)
- **Required**: No (default: `aws`)
- **Description**: KMS provider type
- **Example**: `aws`
- **Used By**: Identity service, Crypto package

#### `KMS_REGION`
- **Type**: String
- **Required**: No (default: `us-east-1`)
- **Description**: KMS region
- **Example**: `us-east-1`
- **Used By**: Identity service, Crypto package

### Authentication

#### `JWT_SECRET`
- **Type**: String
- **Required**: Yes
- **Description**: Secret key for JWT token signing and verification (minimum 32 characters)
- **Example**: `your-super-secret-jwt-key-minimum-32-chars-long`
- **Used By**: All services (for JWT authentication)

#### `VC_ISSUER_DID`
- **Type**: String
- **Required**: No (or `VC_ISSUER_DOMAIN` must be set)
- **Description**: DID (Decentralized Identifier) for verifiable credential issuance
- **Example**: `did:web:the-order.example.com`
- **Used By**: Identity service

#### `VC_ISSUER_DOMAIN`
- **Type**: String
- **Required**: No (or `VC_ISSUER_DID` must be set)
- **Description**: Domain for did:web DID resolution (will be converted to `did:web:{domain}`)
- **Example**: `the-order.example.com`
- **Used By**: Identity service

#### `EIDAS_PROVIDER_URL`
- **Type**: String (URL)
- **Required**: No
- **Description**: eIDAS provider URL for qualified signatures
- **Example**: `https://eidas-provider.example.com`
- **Used By**: Identity service, eIDAS bridge

#### `EIDAS_API_KEY`
- **Type**: String
- **Required**: No
- **Description**: API key for eIDAS provider
- **Example**: `eidas-api-key-here`
- **Used By**: Identity service, eIDAS bridge

#### `ENTRA_TENANT_ID`
- **Type**: String
- **Required**: No
- **Description**: Azure AD tenant ID for Microsoft Entra VerifiedID
- **Example**: `12345678-1234-1234-1234-123456789012`
- **Used By**: Identity service

#### `ENTRA_CLIENT_ID`
- **Type**: String
- **Required**: No
- **Description**: Azure AD application (client) ID for Microsoft Entra VerifiedID
- **Example**: `87654321-4321-4321-4321-210987654321`
- **Used By**: Identity service

#### `ENTRA_CLIENT_SECRET`
- **Type**: String
- **Required**: No
- **Description**: Azure AD client secret for Microsoft Entra VerifiedID
- **Example**: `client-secret-value`
- **Used By**: Identity service

#### `ENTRA_CREDENTIAL_MANIFEST_ID`
- **Type**: String
- **Required**: No
- **Description**: Credential manifest ID from Azure Verified ID portal
- **Example**: `urn:uuid:12345678-1234-1234-1234-123456789012`
- **Used By**: Identity service

#### `AZURE_LOGIC_APPS_WORKFLOW_URL`
- **Type**: String (URL)
- **Required**: No
- **Description**: Azure Logic Apps workflow URL
- **Example**: `https://your-logic-app.azurewebsites.net`
- **Used By**: Identity service, workflows

#### `AZURE_LOGIC_APPS_ACCESS_KEY`
- **Type**: String
- **Required**: No
- **Description**: Azure Logic Apps access key (if not using managed identity)
- **Example**: `access-key-here`
- **Used By**: Identity service, workflows

#### `AZURE_LOGIC_APPS_MANAGED_IDENTITY_CLIENT_ID`
- **Type**: String
- **Required**: No
- **Description**: Managed identity client ID for Logic Apps authentication
- **Example**: `managed-identity-client-id`
- **Used By**: Identity service, workflows

---

## Optional Variables

### OpenID Connect (OIDC)

#### `OIDC_ISSUER`
- **Type**: String (URL)
- **Required**: No
- **Description**: OIDC issuer URL
- **Example**: `https://auth.example.com`
- **Used By**: Identity service, Shared auth middleware

#### `OIDC_CLIENT_ID`
- **Type**: String
- **Required**: No
- **Description**: OIDC client ID
- **Example**: `the-order-client`
- **Used By**: Identity service, Shared auth middleware

#### `OIDC_CLIENT_SECRET`
- **Type**: String
- **Required**: No
- **Description**: OIDC client secret
- **Example**: `client-secret-here`
- **Used By**: Identity service, Shared auth middleware

### Monitoring & Observability

#### `OTEL_EXPORTER_OTLP_ENDPOINT`
- **Type**: String (URL)
- **Required**: No
- **Description**: OpenTelemetry collector endpoint for traces
- **Example**: `http://otel-collector:4318`
- **Used By**: Monitoring package

#### `OTEL_SERVICE_NAME`
- **Type**: String
- **Required**: No
- **Description**: Service name for OpenTelemetry tracing
- **Example**: `identity-service`
- **Used By**: Monitoring package

### Payment Gateway

#### `PAYMENT_GATEWAY_API_KEY`
- **Type**: String
- **Required**: No
- **Description**: Stripe API key for payment processing
- **Example**: `sk_live_...` or `sk_test_...`
- **Used By**: Finance service

#### `PAYMENT_GATEWAY_WEBHOOK_SECRET`
- **Type**: String
- **Required**: No
- **Description**: Stripe webhook secret for verifying webhook signatures
- **Example**: `whsec_...`
- **Used By**: Finance service

### OCR Service

#### `OCR_SERVICE_URL`
- **Type**: String (URL)
- **Required**: No
- **Description**: External OCR service URL (if not set, uses local Tesseract.js)
- **Example**: `https://ocr-service.example.com`
- **Used By**: Intake service, OCR package

#### `OCR_SERVICE_API_KEY`
- **Type**: String
- **Required**: No
- **Description**: API key for external OCR service
- **Example**: `ocr-api-key-here`
- **Used By**: Intake service, OCR package

### Machine Learning

#### `ML_CLASSIFICATION_SERVICE_URL`
- **Type**: String (URL)
- **Required**: No
- **Description**: ML service URL for document classification
- **Example**: `https://ml-service.example.com`
- **Used By**: Intake service, Workflows

#### `ML_CLASSIFICATION_API_KEY`
- **Type**: String
- **Required**: No
- **Description**: API key for ML classification service
- **Example**: `ml-api-key-here`
- **Used By**: Intake service, Workflows

### Caching

#### `REDIS_URL`
- **Type**: String (URL)
- **Required**: No
- **Description**: Redis connection string for caching
- **Example**: `redis://localhost:6379` or `redis://:password@host:6379`
- **Used By**: (Future implementation)

### Message Queue

#### `MESSAGE_QUEUE_URL`
- **Type**: String (URL)
- **Required**: No
- **Description**: Message queue connection string (e.g., RabbitMQ, Kafka)
- **Example**: `amqp://localhost:5672` or `kafka://localhost:9092`
- **Used By**: (Future implementation)

### Google Cloud Platform (GCP)

#### `GCP_PROJECT_ID`
- **Type**: String
- **Required**: No
- **Description**: GCP project ID (if using GCS storage)
- **Example**: `the-order-project`
- **Used By**: Storage client (GCS mode)

#### `GCP_KEY_FILE`
- **Type**: String (file path)
- **Required**: No
- **Description**: Path to GCP service account key file (if using GCS storage)
- **Example**: `/path/to/service-account-key.json`
- **Used By**: Storage client (GCS mode)

---

## Development Variables

### `NODE_ENV`
- **Type**: Enum (`development` | `staging` | `production`)
- **Required**: No (default: `development`)
- **Description**: Environment mode
- **Used By**: All services

### `PORT`
- **Type**: Number
- **Required**: No (default: `3000`)
- **Description**: Server port number
- **Example**: `4001` (Intake), `4002` (Identity), `4003` (Finance), `4004` (Dataroom)
- **Used By**: All services

### `LOG_LEVEL`
- **Type**: Enum (`fatal` | `error` | `warn` | `info` | `debug` | `trace`)
- **Required**: No (default: `info`)
- **Description**: Logging verbosity level
- **Used By**: All services

### `SWAGGER_SERVER_URL`
- **Type**: String (URL)
- **Required**: No
- **Description**: Base URL for Swagger/OpenAPI documentation
- **Example**: `http://localhost:4002` (Identity service)
- **Note**: In development, defaults to `http://localhost:{PORT}` if not set
- **Used By**: All services (for API documentation)

### `CORS_ORIGIN`
- **Type**: String (comma-separated)
- **Required**: No
- **Description**: Allowed CORS origins (comma-separated list)
- **Example**: `http://localhost:3000,https://app.example.com`
- **Note**: In development, defaults to `http://localhost:3000` if not set
- **Used By**: All services

---

## Service-Specific Variables

### Identity Service
- `DATABASE_URL` (required)
- `KMS_KEY_ID` (required)
- `KMS_TYPE` (optional)
- `KMS_REGION` (optional)
- `JWT_SECRET` (required)
- `VC_ISSUER_DID` or `VC_ISSUER_DOMAIN` (required)
- `OIDC_ISSUER` (optional)
- `OIDC_CLIENT_ID` (optional)
- `OIDC_CLIENT_SECRET` (optional)
- `PORT` (optional, default: 4002)
- `SWAGGER_SERVER_URL` (optional)

### Intake Service
- `DATABASE_URL` (required)
- `STORAGE_BUCKET` (required)
- `STORAGE_TYPE` (optional)
- `STORAGE_REGION` (optional)
- `OCR_SERVICE_URL` (optional)
- `OCR_SERVICE_API_KEY` (optional)
- `ML_CLASSIFICATION_SERVICE_URL` (optional)
- `ML_CLASSIFICATION_API_KEY` (optional)
- `PORT` (optional, default: 4001)
- `SWAGGER_SERVER_URL` (optional)

### Finance Service
- `DATABASE_URL` (required)
- `PAYMENT_GATEWAY_API_KEY` (optional)
- `PAYMENT_GATEWAY_WEBHOOK_SECRET` (optional)
- `PORT` (optional, default: 4003)
- `SWAGGER_SERVER_URL` (optional)

### Dataroom Service
- `DATABASE_URL` (required)
- `STORAGE_BUCKET` (required)
- `STORAGE_TYPE` (optional)
- `STORAGE_REGION` (optional)
- `PORT` (optional, default: 4004)
- `SWAGGER_SERVER_URL` (optional)

---

## Configuration Examples

### Development Environment

```bash
# .env.development
NODE_ENV=development
LOG_LEVEL=debug

# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/theorder_dev

# Storage
STORAGE_BUCKET=the-order-documents-dev
STORAGE_TYPE=s3
STORAGE_REGION=us-east-1

# KMS
KMS_KEY_ID=arn:aws:kms:us-east-1:123456789012:key/dev-key
KMS_TYPE=aws
KMS_REGION=us-east-1

# Authentication
JWT_SECRET=development-jwt-secret-key-minimum-32-characters-long
VC_ISSUER_DOMAIN=localhost:4002

# CORS
CORS_ORIGIN=http://localhost:3000

# Swagger
SWAGGER_SERVER_URL=http://localhost:4002
```

### Production Environment

```bash
# .env.production
NODE_ENV=production
LOG_LEVEL=info

# Database
DATABASE_URL=postgresql://user:password@db.example.com:5432/theorder

# Storage
STORAGE_BUCKET=the-order-documents-prod
STORAGE_TYPE=s3
STORAGE_REGION=us-east-1

# KMS
KMS_KEY_ID=arn:aws:kms:us-east-1:123456789012:key/prod-key
KMS_TYPE=aws
KMS_REGION=us-east-1

# Authentication
JWT_SECRET=${JWT_SECRET}  # From secrets manager
VC_ISSUER_DID=did:web:the-order.example.com

# OIDC
OIDC_ISSUER=https://auth.example.com
OIDC_CLIENT_ID=the-order-prod
OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}  # From secrets manager

# Payment Gateway
PAYMENT_GATEWAY_API_KEY=${STRIPE_API_KEY}  # From secrets manager
PAYMENT_GATEWAY_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}  # From secrets manager

# Monitoring
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
OTEL_SERVICE_NAME=identity-service

# CORS
CORS_ORIGIN=https://app.example.com,https://admin.example.com

# Swagger
SWAGGER_SERVER_URL=https://api.example.com
```

### Docker Compose Example

```yaml
services:
  identity:
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgresql://postgres:postgres@db:5432/theorder
      - KMS_KEY_ID=arn:aws:kms:us-east-1:123456789012:key/dev-key
      - JWT_SECRET=development-jwt-secret-key-minimum-32-characters-long
      - VC_ISSUER_DOMAIN=localhost:4002
      - PORT=4002
```

---

## Security Best Practices

1. **Never commit secrets to version control**
   - Use `.env` files (gitignored) for local development
   - Use secrets management services (AWS Secrets Manager, HashiCorp Vault) for production

2. **Use strong JWT secrets**
   - Minimum 32 characters
   - Use cryptographically random strings
   - Rotate regularly

3. **Restrict CORS origins**
   - Only include trusted domains
   - Never use `*` in production

4. **Use IAM roles when possible**
   - Prefer IAM roles over access keys for AWS services
   - Reduces risk of credential exposure

5. **Rotate credentials regularly**
   - Set up rotation schedules for API keys
   - Monitor for credential leaks

---

## Validation

All environment variables are validated at application startup using Zod schemas in `packages/shared/src/env.ts`. Invalid or missing required variables will cause the application to fail to start with a clear error message.

---

## See Also

- [Architecture Documentation](../architecture/README.md)
- [Deployment Guide](../deployment/README.md)
- [Security Documentation](../governance/SECURITY.md)

