Configuration

Configure environment variables, Nextcloud integration, database connections, feature flags, and third-party services for Certexi.

Last updated: 2025-02-18

Configuration

Certexi uses environment variables for all configuration. This guide covers every setting, organized by service.

Quick Start

cp env.production.template .env.production
nano .env.production
npm run check-env  # Validate configuration

Critical Variables

These must be configured before the application will start:

VariableDescriptionHow to Generate
DATABASE_URLPostgreSQL connection stringSee Installation
NEXTAUTH_SECRETAuthentication secretopenssl rand -base64 32
NEXTAUTH_URLApplication URLYour production domain
SENTRY_DSNError tracking endpointGet from sentry.io

Nextcloud Integration

Certexi uses Nextcloud for OAuth authentication and evidence file storage.

OAuth2 Setup

  1. Log in to Nextcloud as admin
  2. Navigate to Settings > Security > OAuth 2.0 clients
  3. Add a new client with redirect URI: https://your-app.com/api/auth/nextcloud/callback
  4. Copy the Client ID and Secret
NEXTCLOUD_URL=https://cloud.example.com
NEXTCLOUD_CLIENT_ID=your_client_id
NEXTCLOUD_CLIENT_SECRET=your_client_secret

Evidence Storage

Files are stored via WebDAV in Nextcloud. Configure the storage path:

AWS_S3_BUCKET=certexi-prod-storage  # S3 for file storage
ℹ️

Dual Storage

Certexi supports both Nextcloud WebDAV and AWS S3 for evidence files. Nextcloud is used for document management while S3 handles high-throughput binary uploads.

Database Configuration

Connection String Format

postgresql://USER:PASSWORD@HOST:5432/DATABASE?sslmode=require
⚠️

Always Use SSL

Always include ?sslmode=require for production connections. Never expose your database to the public internet.

Connection Pooling

Certexi uses Drizzle ORM with built-in connection pooling:

// Default pool configuration
{
  max: 10,
  idle_timeout: 20,
  connect_timeout: 10,
  max_lifetime: 1800, // 30 minutes
}

For high-traffic deployments, use PgBouncer in front of PostgreSQL with pool_mode = transaction.

Redis Configuration

REDIS_URL=redis://localhost:6379

Redis is optional but recommended for:

  • Session caching
  • Rate limiting state
  • Real-time event pub/sub
  • API response caching with configurable TTL

Security Settings

Secret Generation

# Generate ECDSA P-256 key pair for credential signing
openssl ecparam -name prime256v1 -genkey -noout -out private-key.pem
openssl ec -in private-key.pem -pubout -out public-key.pem
ISSUER_PRIVATE_KEY=your_hex_key    # Use KMS in production
JWT_SECRET=your_jwt_secret_32chars
ENCRYPTION_KEY=your_encryption_key
🚨

Key Management

Never store private keys in environment variables for production. Use AWS KMS, Azure Key Vault, or an HSM. See Key Management for details.

Rate Limiting

RATE_LIMIT_MAX_REQUESTS=100   # Requests per window
RATE_LIMIT_WINDOW_MS=60000    # Window duration (1 minute)

Firewall

Recommended production firewall rules:

sudo ufw allow 443/tcp       # HTTPS
sudo ufw allow 80/tcp        # HTTP redirect
sudo ufw allow from YOUR_IP to any port 22  # SSH
sudo ufw default deny incoming
sudo ufw enable

Feature Flags

Feature Flag Toggle

<Card className="w-80">
  <CardHeader className="pb-2">
    <CardTitle className="text-sm">Feature Flags</CardTitle>
    <CardDescription>Toggle optional capabilities</CardDescription>
  </CardHeader>
  <CardContent className="space-y-3">
    {[
      { flag: 'ENABLE_OFFLINE_MODE', label: 'Offline PWA', on: true },
      { flag: 'ENABLE_NFC_SCANNING', label: 'NFC Scanning', on: true },
      { flag: 'ENABLE_CCTV', label: 'CCTV Integration', on: true },
      { flag: 'ENABLE_MOTION_DETECTION', label: 'Motion Detection', on: true },
      { flag: 'ENABLE_OCR', label: 'OCR Processing', on: false },
      { flag: 'ENABLE_AI_SERVICE', label: 'AI Service', on: false },
    ].map((item, i) => (
      <div key={i} className="flex items-center justify-between text-sm">
        <div>
          <div className="font-medium">{item.label}</div>
          <div className="text-[10px] font-mono text-muted-foreground">{item.flag}</div>
        </div>
        <Badge variant={item.on ? "default" : "outline"} className={item.on ? "bg-green-500" : ""}>
          {item.on ? 'ON' : 'OFF'}
        </Badge>
      </div>
    ))}
  </CardContent>
</Card>

Control optional features via environment variables:

VariableDefaultDescription
ENABLE_OFFLINE_MODEtruePWA offline support
ENABLE_NFC_SCANNINGtrueWeb NFC integration
ENABLE_CCTVtrueSurveillance integration
ENABLE_MOTION_DETECTIONtrueMotion detection system
ENABLE_OCRfalseOCR processing for documents
ENABLE_AI_SERVICEfalseFlowhash AI integration

Monitoring

Sentry

SENTRY_DSN=https://your-key@sentry.io/project-id

Sentry captures errors, performance transactions, and source maps automatically.

Health Checks

The /api/health endpoint returns status for all services. Configure uptime monitoring (e.g., UptimeRobot) to poll this endpoint every 5 minutes.

Prometheus Metrics

Available at /api/metrics (admin authentication required):

curl -H "Authorization: Bearer $ADMIN_TOKEN" \
  https://your-app.com/api/metrics

AI Service

FLOWHASH_AI_SERVICE_URL=http://localhost:8000

The Flowhash AI service provides OCR processing, document classification, and anomaly detection. See the architecture overview for integration details.

Validation

Run the configuration validator before deploying:

npm run check-env

This checks all required variables are set, validates connection strings, and tests reachability of external services.

Configuration | Certexi Docs