diff --git a/docs/deployment.md b/docs/deployment.md index 81c87d9..3d23083 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -6,6 +6,20 @@ For running the binary directly on your machine (development, debugging), see th --- +## ⚠️ Production Security Warning + +**IMPORTANT**: Default Helm values are for development. Production requires: + +| Setting | Default | Production | Risk if not changed | +|---------|---------|------------|---------------------| +| JWT auth | `false` | `true` | ⚠️ Unauthenticated access | +| TLS | `false` | `true` | ⚠️ Plaintext credentials | +| Database | Built-in pod | External managed | Data loss on restart | + +See [API Operator Guide](api-operator-guide.md) for complete production configuration. + +--- + ## Prerequisites Before deploying, ensure you have: @@ -274,6 +288,34 @@ During upgrade, in case schema changes have occurred in the new version, a DB mi helm uninstall hyperfleet-api --namespace hyperfleet-system ``` +## Helm Values + +### Key Configuration Options + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `image.registry` | Container registry | `CHANGE_ME` (must be set explicitly) | +| `image.repository` | Image repository | `openshift-hyperfleet/hyperfleet-api` | +| `image.tag` | Image tag | `latest` | +| `image.pullPolicy` | Image pull policy | `Always` | +| `config.adapters.required.cluster` | Cluster adapters required for Ready state | `[]` | +| `config.adapters.required.nodepool` | Nodepool adapters required for Ready state | `[]` | +| `config.server.jwt.enabled` | Enable JWT authentication | `false` (Helm default; app default is `true`) | +| `database.postgresql.enabled` | Enable built-in PostgreSQL | `true` | +| `database.external.enabled` | Use external database | `false` | +| `database.external.secretName` | Secret containing database credentials | `hyperfleet-db-external` | +| `serviceMonitor.enabled` | Enable Prometheus Operator ServiceMonitor | `false` | +| `serviceMonitor.interval` | Metrics scrape interval | `30s` | +| `serviceMonitor.scrapeTimeout` | Metrics scrape timeout | `10s` | +| `serviceMonitor.labels` | Additional labels for Prometheus selector | `{}` | +| `serviceMonitor.namespace` | Namespace for ServiceMonitor (if different) | `""` | +| `replicaCount` | Number of API replicas | `1` | +| `resources.limits.cpu` | CPU limit | `500m` | +| `resources.limits.memory` | Memory limit | `512Mi` | +| `podDisruptionBudget.enabled` | Enable PodDisruptionBudget | `false` | +| `podDisruptionBudget.minAvailable` | Minimum available pods during disruption | `1` | +| `podDisruptionBudget.maxUnavailable` | Maximum unavailable pods during disruption | - | + ### Custom Values File For repeatable deployments, create a `values.yaml` file: @@ -450,6 +492,17 @@ Before deploying to production, ensure: - [ ] **Disruption**: PodDisruptionBudget enabled (`podDisruptionBudget.enabled=true`) - [ ] **Monitoring**: ServiceMonitor enabled if using Prometheus Operator +## Production Best Practices + +- **Environment**: Use default (ProductionEnv) for production deployments; never set `HYPERFLEET_ENV=development` +- Use external managed database (Cloud SQL, RDS, Azure Database) with automated backups +- Store all sensitive data in Kubernetes Secrets, never in ConfigMap or values.yaml +- Enable authentication with `config.server.jwt.enabled=true` +- Set resource limits and use multiple replicas for high availability +- Use specific image tags (semantic versioning) instead of `latest` +- Enable PodDisruptionBudget for zero-downtime during cluster maintenance +- Configure health probes with appropriate timeouts for your workload + ### Configuration File Security The configuration file path — set via `--config` or `HYPERFLEET_CONFIG` — is a trust boundary. The API validates configuration **content** on startup (unknown fields are rejected, required values are enforced, TLS/JWT/timeout settings are checked) and will refuse to start with an invalid configuration. However, **path and permission safety is the operator's responsibility**. The API reads whatever file the process can access at the given path without checking permissions or ownership. diff --git a/docs/development.md b/docs/development.md index 455477d..54a4288 100644 --- a/docs/development.md +++ b/docs/development.md @@ -107,7 +107,7 @@ export HYPERFLEET_DATABASE_SSL_MODE=require # for remote databases make run-no-auth ``` -**Note**: The default runtime environment is `production` (JWT and TLS enabled). The `make run-no-auth` target explicitly disables authentication for local development. If running the binary directly, set `HYPERFLEET_ENV=development` or use `--server-jwt-enabled=false`. +**Note**: The default runtime environment is `production`. Security features (JWT, TLS) require explicit enablement in Helm values. The service starts on `localhost:8000` — see [Accessing the API](../README.md#accessing-the-api) for all available endpoints. @@ -451,6 +451,67 @@ make db/setup make test-integration ``` +## Development Environment Configuration + +### HYPERFLEET-1146: Development Environment Analysis + +**Background**: Prior to HYPERFLEET-1133, the API defaulted to `DevelopmentEnv` (insecure). To protect production deployments, HYPERFLEET-1133 changed the default to `ProductionEnv` (secure by default). + +**Analysis Question**: Is `e_development.go` still needed after this change? + +**Decision**: **KEEP `e_development.go`** with improved documentation. + +**Why keep it**: +- ✅ **One variable controls multiple settings** — `HYPERFLEET_ENV=development` forces JWT=false, TLS=false, SSL=disable +- ✅ **Convenient for scripts/CI** — One environment variable vs three separate flags +- ✅ **Semantic clarity** — "development mode" is clearer than remembering individual flags +- ✅ **Consistent with tests** — `unit_testing` and `integration_testing` use the same pattern +- ✅ **Production safe** — `EnvironmentDefault = ProductionEnv` prevents accidental use in production + +**How to use**: + +```bash +# Full development mode (JWT/TLS/DB SSL all disabled) +HYPERFLEET_ENV=development ./bin/hyperfleet-api serve + +# JWT-only no-auth (TLS and DB SSL keep their defaults) +make run-no-auth + +# Production mode (JWT/TLS enabled, default) +./bin/hyperfleet-api serve # Uses EnvironmentDefault = ProductionEnv +``` + +**⚠️ IMPORTANT**: `HYPERFLEET_ENV=development` is for **local development ONLY**. Never use in production. The development environment forces insecure settings: +- JWT authentication: **disabled** +- TLS encryption: **disabled** +- Database SSL: **disabled** + +**Production deployments**: Always use `EnvironmentDefault` (production) or explicitly enable security via Helm values: +```yaml +config: + server: + jwt: + enabled: true # Production requires JWT + tls: + enabled: true # Production requires TLS + database: + ssl: + mode: verify-full # Production requires SSL +``` + +**Alternative to `HYPERFLEET_ENV=development`**: If you prefer explicit flags over environment-based config, you can pass flags directly: + +```bash +./bin/hyperfleet-api serve \ + --server-jwt-enabled=false \ + --server-https-enabled=false \ + --db-ssl-mode=disable +``` + +However, `HYPERFLEET_ENV=development` is recommended for local development as it's simpler and less error-prone. + +--- + ## Related Documentation - [Configuration Guide](config.md) — Complete configuration reference