{"id":16665041,"url":"https://github.com/andrearaponi/dito","last_synced_at":"2026-03-13T15:33:49.169Z","repository":{"id":257822832,"uuid":"870207723","full_name":"andrearaponi/dito","owner":"andrearaponi","description":"an advanced reverse proxy server written in Go ","archived":false,"fork":false,"pushed_at":"2025-06-19T18:13:42.000Z","size":53432,"stargazers_count":641,"open_issues_count":3,"forks_count":22,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-10-30T17:44:01.232Z","etag":null,"topics":["docker","go","golang","kubernetes","microservices","reverse-proxy"],"latest_commit_sha":null,"homepage":"https://ditoproxy.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andrearaponi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"andrearaponi","custom":["https://paypal.me/andrearaponi"]}},"created_at":"2024-10-09T16:20:06.000Z","updated_at":"2025-10-27T16:28:44.000Z","dependencies_parsed_at":"2025-06-08T18:33:40.899Z","dependency_job_id":null,"html_url":"https://github.com/andrearaponi/dito","commit_stats":null,"previous_names":["andrearaponi/dito"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/andrearaponi/dito","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrearaponi%2Fdito","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrearaponi%2Fdito/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrearaponi%2Fdito/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrearaponi%2Fdito/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrearaponi","download_url":"https://codeload.github.com/andrearaponi/dito/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrearaponi%2Fdito/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30469312,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T11:00:43.441Z","status":"ssl_error","status_checked_at":"2026-03-13T11:00:23.173Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","go","golang","kubernetes","microservices","reverse-proxy"],"created_at":"2024-10-12T11:01:29.609Z","updated_at":"2026-03-13T15:33:49.143Z","avatar_url":"https://github.com/andrearaponi.png","language":"Go","funding_links":["https://github.com/sponsors/andrearaponi","https://paypal.me/andrearaponi"],"categories":["Go"],"sub_categories":[],"readme":"**Note:** The primary documentation for Dito will be migrated to an mdBook format. Please be patient 🙂\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eDito\u003c/h1\u003e\n  \u003cp\u003e\n    \u003cimg src=\"https://img.shields.io/badge/status-active-green.svg\" alt=\"Status\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/release-0.7.5-green.svg\" alt=\"Release\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/license-Apache2-blue.svg\" alt=\"License\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/language-Go-blue.svg\" alt=\"Language\"\u003e\n  \u003c/p\u003e\n  \u003cp\u003e\n    \u003cimg src=\"dito.png\" alt=\"Dito Logo\"\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\nDito is an advanced, highly extensible reverse proxy server written in Go. It features a robust plugin-based architecture, custom certificate handling for backend connections, dynamic configuration reloading, and more. Plugins can manage their own dependencies and provide custom middleware functionality.\n\n## 🚀 Features\n\n*   **Layer 7 Reverse Proxy:** Handles HTTP and HTTPS requests efficiently.\n*   **WebSockets Support:** Proxy WebSocket connections with ease.\n*   **Dynamic Configuration Reloading (hot reload):** Update configurations without restarting the server.\n*   **Extensible Plugin System:** Enhance Dito’s functionality with custom Go plugins that can:\n    *   Add authentication mechanisms\n    *   Implement caching strategies\n    *   Apply rate limiting\n    *   Transform requests/responses\n    *   Add custom logging\n    *   And much more!\n*   **Plugin Security:** Plugins are signed using Ed25519 keys, and Dito verifies these signatures at startup.\n*   **Custom TLS Certificate Management:** Support for mTLS and custom certificates for backend connections.\n*   **Header Manipulation:** Add or remove HTTP headers as needed.\n*   **Advanced Logging:** Asynchronous logging with customizable verbosity and performance optimizations.\n*   **Custom Transport Configuration:** Fine-tune HTTP transport settings per location or globally.\n*   **Response Body Size Limits:** Control maximum response body sizes globally and per location with proper error handling (413 status code).\n*   **Response Buffering Control:** Enable or disable response buffering per location for optimal performance.\n*   **Prometheus Metrics:** Monitor performance and behavior with detailed metrics.\n\n## 📂 Project Structure\n\n```\ndito/\n├── cmd/                   # Entry points (main application \u0026 plugin-signer)\n├── app/                   # Core application logic\n├── config/                # Configuration loader \u0026 hot-reload\n├── handlers/              # Request routing \u0026 proxy handlers\n├── middlewares/           # Built-in middlewares (plugins can add more)\n├── plugin/                # Plugin loading, signing, and verification\n├── plugins/               # Plugin implementations\n├── transport/             # HTTP transport configuration\n├── websocket/             # WebSocket proxy support\n├── writer/                # Response writers and buffering\n├── metrics/               # Prometheus metrics\n├── logging/               # Structured logging\n├── deployments/           # Deployment configurations\n│   ├── kubernetes/        # Basic Kubernetes deployments\n│   ├── openshift/         # OpenShift production deployments\n│   └── docker/            # Docker Compose for development\n├── configs/               # Configuration files and templates\n│   └── templates/         # Configuration templates\n├── scripts/               # Deployment and utility scripts\n└── bin/                   # Built binaries and runtime files\n├── plugins/               # Example and community plugins\n├── transport/             # HTTP transport customization\n├── websockets/            # WebSocket support\n├── writer/                # Custom response writers\n├── logging/               # Logging utilities\n└── metrics/               # Prometheus metrics collection\n```\n\n## ⚙️ Installation\n\nEnsure you have Go (\u003e= 1.21) and `make` installed.\n\n### Quick Start (Recommended)\n\n```bash\n# Clone repo\ngit clone https://github.com/andrearaponi/dito.git \u0026\u0026 cd dito\n\n# One-command setup \u0026 start\nmake quick-start\n```\nThis will:\n1.  Build all binaries (Dito \u0026 plugin-signer)\n2.  Generate Ed25519 keys\n3.  Build \u0026 sign plugins\n4.  Update config with correct paths \u0026 hashes\n5.  Start the Dito server\n\n### Step-by-Step\n\n```bash\n# 1. Clone repo\ngit clone https://github.com/andrearaponi/dito.git \u0026\u0026 cd dito\n\n# 2. Setup (build, keys, plugins, config)\nmake setup\n\n# 3. Start server\nmake run\n```\n\n### Makefile Commands\n\n| Category | Command | Description |\n|----------|---------|-------------|\n| 🚀 **Quick** | `quick-start` | Clean, setup everything and start (recommended) |\n| | `setup` | Full development setup (build, keys, plugins, config) |\n| | `setup-prod` | Full production setup (persistent keys, prod config) |\n| | `run` | Start the Dito server |\n| | `fix-config` | Quick command to fix configuration after setup |\n| 🔨 **Build** | `build` | Build Dito binary only |\n| | `build-plugins` | Build all plugins |\n| | `build-plugin-signer` | Build plugin-signer tool |\n| 🔑 **Security** | `generate-keys` | Generate Ed25519 key pair for development |\n| | `generate-prod-keys` | Generate persistent Ed25519 key pair for production |\n| | `sign-plugins` | Sign all plugins with development keys |\n| | `sign-plugins-prod` | Sign all plugins with production keys |\n| | `update-config` | Update bin/config.yaml with development key paths/hashes |\n| | `update-prod-config` | Update bin/config-prod.yaml with production key paths/hashes |\n| | `update-k8s-config` | Create configs/config-prod-k8s.yaml for Kubernetes deployment |\n| 🚀 **OpenShift** | `deploy-ocp` | Complete OpenShift production deployment |\n| | `deploy-ocp-dev` | Quick development deployment to OpenShift |\n| | `status-ocp` | Check OpenShift deployment status |\n| | `logs-ocp` | View OpenShift deployment logs |\n| | `clean-ocp` | Clean up OpenShift resources |\n| 🔍 **Debug** | `debug-config` | Debug configuration issues |\n| | `help` | Show all commands with detailed descriptions |\n| 🧹 **Cleanup** | `clean` | Remove all build artifacts |\n| | `clean-plugins` | Clean plugin binaries only |\n| 🧪 **Development** | `test` | Run tests |\n| | `vet` | Run go vet |\n| | `fmt` | Format code |\n| | `sonar` | Run SonarQube analysis |\n\n### 🛠️ Manual Installation (Advanced)\n\n1.  **Build Dito:**\n    ```bash\n    go build -o bin/dito ./cmd/dito/main.go\n    ```\n    *(Note: Ensure the path to `main.go` is correct, e.g., `./cmd/dito/main.go` if `main.go` is in `cmd/dito/`)*\n\n2.  **Build plugin-signer:**\n    ```bash\n    cd cmd/plugin-signer \u0026\u0026 go build -o ../../bin/plugin-signer . \u0026\u0026 cd ../..\n    ```\n\n3.  **Generate keys:**\n    ```bash\n    ./bin/plugin-signer generate-keys\n    ```\n    *(This will create keys in the current directory, presumably `bin/` if run from there, or the project root. Move them to `bin/` if needed or specify paths)*\n\n4.  **Build plugins:**\n    ```bash\n    find plugins -mindepth 1 -maxdepth 1 -type d -exec sh -c 'cd \"$1\" \u0026\u0026 go build -buildmode=plugin -o \"$(basename \"$1\").so\"' sh {} \\;\n    ```\n\n5.  **Sign plugins:**\n    ```bash\n    find plugins -name \"*.so\" -exec ./bin/plugin-signer sign {} \\;\n    ```\n    *(Ensure `plugin-signer` can find the private keys; you might need to specify `-privateKey path/to/key`)*\n\n6.  **Update `config.yaml`** (ensure `public_key_path` \u0026 `public_key_hash` are correct).\n\n7.  **Run Dito:**\n    ```bash\n    ./bin/dito\n    ```\n\n## ⚙️ Usage\n\nStart with default config:\n```bash\nmake run\n```\n\nOr directly:\n```bash\n./bin/dito -f /path/to/custom-config.yaml -enable-profiler\n```\n\n### Config File\n*   **Template:** `cmd/config.yaml` (or the correct path to your template)\n*   **Runtime:** `bin/config.yaml` (auto-updated by `make setup` or `make quick-start`)\n\nKey fields:\n```yaml\nport: '8081'\nhot_reload: true\nmetrics:\n  enabled: true\n  path: \"/metrics\"\nlogging:\n  enabled: true\n  verbose: false\n  level: \"info\"\nplugins:\n  directory: \"./plugins\" # Relative to where Dito is run, or absolute path\n  public_key_path: \"./ed25519_public.key\" # Relative to where Dito is run, or absolute path\n  public_key_hash: \"\u003cSHA256_HASH\u003e\" # The SHA256 hash of the public key\ntransport:\n  http:\n    idle_conn_timeout: 90s\n    max_idle_conns: 1000\n    max_idle_conns_per_host: 200\n    max_conns_per_host: 0\n    tls_handshake_timeout: 2s\n    response_header_timeout: 2s\n    expect_continue_timeout: 500ms\n    disable_compression: false\n    dial_timeout: 2s\n    keep_alive: 30s\n    force_http2: true\nlocations:\n  - path: \"^/test-ws$\"\n    target_url: \"wss://echo.websocket.org\"\n    enable_websocket: true\n    replace_path: true\n\n  - path: \"^/dito$\"\n    target_url: \"https://httpbin.org/get\"\n    replace_path: true\n    transport:\n      http:\n        disable_compression: true\n    additional_headers:\n      X-Custom: \"true\"\n    excluded_headers:\n      - Cookie\n    middlewares:\n      - hello-plugin # Plugin name as defined in its directory\n```\n\n## 📏 Response Limits Configuration\n\nDito provides flexible response body size limits that can be configured both globally and per location to prevent memory issues and control resource usage.\n\n### Global Response Limits\n\nSet default limits for all locations in the main configuration:\n\n```yaml\n# Global response limits configuration\nresponse_limits:\n  max_response_body_size: 100000 # 100KB default limit for all locations\n```\n\n### Per-Location Response Limits\n\nOverride global limits for specific locations with custom settings:\n\n```yaml\nlocations:\n  - path: \"^/api/small\"\n    target_url: \"https://api.example.com\"\n    max_response_body_size: 1024 # 1KB limit for this specific endpoint\n    disable_response_buffering: false # Enable response buffering (default)\n    \n  - path: \"^/api/large\"\n    target_url: \"https://api.example.com\"\n    max_response_body_size: 52428800 # 50MB limit for large responses\n    disable_response_buffering: true # Disable buffering for streaming\n```\n\n### Response Limit Features\n\n- **Automatic Error Handling**: Returns proper `413 Request Entity Too Large` status code when limits are exceeded\n- **JSON Error Responses**: Provides structured error messages with limit details\n- **Early Detection**: Checks `Content-Length` header before processing to fail fast\n- **Streaming Support**: Works with both buffered and unbuffered responses\n- **Logging**: Comprehensive warning logs when limits are exceeded\n- **Zero Downtime**: Limits can be updated via hot reload without server restart\n\n### Error Response Format\n\nWhen a response exceeds the configured limit, Dito returns a standardized JSON error:\n\n```json\n{\n  \"error\": {\n    \"code\": 413,\n    \"message\": \"Response body size exceeds limit\",\n    \"details\": {\n      \"limit_bytes\": 90,\n      \"path\": \"/api/endpoint\"\n    }\n  }\n}\n```\n\n### Response Buffering Control\n\nThe `disable_response_buffering` option controls how responses are handled:\n\n- **`false` (default)**: Responses are buffered in memory before sending to client\n  - Better for small responses\n  - Allows Content-Length to be set accurately\n  - Enables proper error handling when limits are exceeded\n  \n- **`true`**: Responses are streamed directly to client  \n  - Better for large responses or real-time data\n  - Lower memory usage\n  - Cannot recover if response exceeds limit mid-stream\n## 🔌 Plugin System\n\nDito uses Go plugins (.so files). Each plugin must:\n1.  Be in its own subdirectory under `plugins/`.\n2.  Contain:\n    *   `\u003cplugin-name\u003e.so`\n    *   `\u003cplugin-name\u003e.so.sig` (signature file)\n    *   `config.yaml` (plugin-specific config, optional but common)\n\n### Signing \u0026 Verification\n*   **Mandatory:** Dito will not start without valid plugin signing.\n*   Uses Ed25519 digital signatures.\n\nSteps (if done manually):\n1.  **Generate key pair:**\n    ```bash\n    ./bin/plugin-signer generate-keys -privateKey ed25519_private.key -publicKey ed25519_public.key\n    ```\n    *(Save these keys securely, e.g., in `bin/` or a dedicated directory)*\n\n2.  **Compute public key hash:**\n    ```bash\n    shasum -a 256 ed25519_public.key | awk '{print $1}'\n    ```\n    *(Ensure the path to `ed25519_public.key` is correct)*\n\n3.  **Update Dito's `config.yaml`** with `public_key_path` (e.g., `./bin/ed25519_public.key`) and the computed `public_key_hash`.\n\n4.  **Sign plugin:**\n    ```bash\n    ./bin/plugin-signer sign -plugin path/to/plugin.so -privateKey path/to/ed25519_private.key\n    ```\n    *(This will create a `.sig` file next to the plugin's `.so` file)*\n\n## 🐛 Troubleshooting\n\n*   **`public key integrity validation failed`**: Regenerate hash and update config. Ensure the hash exactly matches the specified public key file.\n*   **`failed to read public key`**: Check public key file path in `config.yaml` \u0026 file permissions.\n*   **`plugin signature verification failed`**: Re-sign with correct private key. Ensure public key in `config.yaml` matches the private key used for signing.\n\n\n## Custom Transport Configuration\n\nThis allows for fine-grained control over how Dito connects to backend services, including:\n\n- **Timeouts and Connection Limits**: Configure timeouts and maximum connections to handle backend service behavior.\n- **TLS Settings**: Manage TLS handshake timeouts and enforce HTTP/2 if needed.\n- **Custom Certificates**: Specify client certificates for mTLS connections to backends.\n\n### WebSocket Support\n\nDito supports WebSocket proxying, allowing you to seamlessly forward WebSocket connections to your backend servers. This can be configured per location, enabling WebSocket support on specific routes.\n\n#### Configuration\n\nTo enable WebSocket support, add `enable_websocket: true` to the location configuration. Here’s an example:\n\n```yaml\n# List of location configurations for proxying requests.\nlocations:\n  - path: \"^/test-ws$\" # Regex pattern to match the request path.\n    target_url: \"wss://echo.websocket.org\" # The target URL to which the request will be proxied.\n    enable_websocket: true # Enable WebSocket support for this location.\n    replace_path: true # Replace the matched path with the target URL.\n```\n#### Upcoming Enhancements\n\nFuture versions of Dito will include more advanced WebSocket features, such as:\n\n- **Enhanced TLS Support**: Configurable TLS settings for secure WebSocket connections, allowing for encrypted communication and improved security.\n- **Comprehensive Error Handling**: Improved resilience and error management for WebSocket connections to ensure stability during unexpected interruptions.\n- **Detailed Metrics**: Real-time metrics for WebSocket traffic, enabling better performance monitoring and insight into connection stability and throughput.\n\nThese features aim to provide full control, security, and reliability for WebSocket connections in Dito, enhancing the overall communication experience.\n\n\n### TLS/SSL\n\nDito supports mTLS (mutual TLS) for secure connections to backends. You can specify:\n\n- `cert_file`: The client certificate.\n- `key_file`: The client private key.\n- `ca_file`: The certificate authority (CA) for verifying the backend.\n\n## Metrics\n\nDito supports monitoring through Prometheus by exposing various metrics related to the proxy's performance and behavior. The metrics are accessible at the configured path (default is `/metrics`).\n\n### Available Metrics\n\nDito provides both custom metrics and standard metrics from the Go runtime and Prometheus libraries:\n\n#### Custom Metrics\n- **`http_requests_total`**: Total number of HTTP requests processed, partitioned by method, path, and status code.\n- **`http_request_duration_seconds`**: Duration of HTTP requests in seconds, with predefined buckets.\n- **`active_connections`**: Number of active connections currently being handled by the proxy.\n- **`data_transferred_bytes_total`**: Total amount of data transferred in bytes, partitioned by direction (`inbound` or `outbound`).\n\n#### Standard Metrics\n- **Go runtime metrics**: Metrics such as memory usage, garbage collection statistics, and the number of goroutines, which are automatically exposed by the Go Prometheus client library. Examples include:\n   - `go_goroutines`: Number of goroutines currently running.\n   - `go_memstats_alloc_bytes`: Number of bytes allocated in the heap.\n   - `go_gc_duration_seconds`: Duration of garbage collection cycles.\n- **Prometheus HTTP handler metrics**: Metrics related to the Prometheus HTTP handler itself, such as:\n   - `promhttp_metric_handler_requests_total`: Total number of HTTP requests handled by the metrics endpoint.\n   - `promhttp_metric_handler_requests_in_flight`: Current number of scrapes being served.\n\n### Configuration Example\n\nTo enable metrics, make sure the following section is present in the `config.yaml` file:\n\n```yaml\nmetrics:\n   enabled: true # Enable or disable metrics.\n   path: \"/metrics\" # The path on which the metrics will be exposed.\n```\n## Reporting Issues\n\nIf you encounter any issues while using Dito, please follow these steps to open an issue on the GitHub repository:\n\n1. **Go Version**: Specify the version of Go you are using.\n   - You can find your Go version by running `go version` in your terminal.\n\n2. **Error Details**: Provide a detailed description of the error or issue you encountered. Include:\n   - The exact error message.\n   - The steps you took to produce the error.\n   - Any relevant logs or console outputs.\n\n3. **Configuration File**: Include the `config.yaml` file you are using.\n   - This will help us understand the context in which the issue occurred and allow us to replicate the problem.\n\n## 👏 Contributing\n\n1.  Fork the repo.\n2.  Create your feature branch (`git checkout -b feature/AmazingFeature`).\n3.  Commit your changes (`git commit -m 'Add some AmazingFeature'`).\n4.  Push to the branch (`git push origin feature/AmazingFeature`).\n5.  Open a Pull Request.\n\n## 🐳 Containerization \u0026 OpenShift Deployment\n\nDito is fully containerized and optimized for OpenShift Container Platform (OCP) with enterprise-grade security and deployment practices.\n\n### Quick Deployment\n\nFor a complete OpenShift deployment with automatic key management and configuration:\n\n```bash\n# Make the deployment script executable\nchmod +x scripts/deploy-ocp.sh\n\n# Deploy with defaults (namespace: dito, version: v2.0.0-production)\n./scripts/deploy-ocp.sh\n\n# Deploy to custom namespace with specific version\n./scripts/deploy-ocp.sh -n my-dito -v latest\n\n# Force key regeneration\n./scripts/deploy-ocp.sh -f\n\n# Only update configuration (no deployment)\n./scripts/deploy-ocp.sh -c\n\n# Only deploy (skip config/key generation)\n./scripts/deploy-ocp.sh -d\n```\n\n### Manual Deployment Steps\n\n#### 1. Build and Push Container Image\n\n```bash\n# Build for OpenShift with automatic registry login and push\n./docker-build.sh\n\n# Or with custom settings\nVERSION=v2.1.0 NAMESPACE=my-dito ./docker-build.sh\n```\n\n#### 2. Generate Production Keys\n\n```bash\n# Generate persistent production keys (only if they don't exist)\nmake generate-prod-keys\n```\n\n#### 3. Create OpenShift Resources\n\n```bash\n# Create namespace\noc new-project dito\n\n# Create Secret for keys\noc create secret generic dito-keys \\\n    --from-file=ed25519_public.key=bin/ed25519_public_prod.key \\\n    --from-file=ed25519_private.key=bin/ed25519_private_prod.key\n\n# Create ConfigMap for application config\n# First, create Kubernetes-specific config from template\nHASH=$(shasum -a 256 bin/ed25519_public_prod.key | awk '{print $1}')\nsed \"s/PLACEHOLDER_HASH_TO_BE_REPLACED/$HASH/\" configs/templates/application.yaml \u003e configs/config-prod-k8s.yaml\n\noc create configmap dito-config \\\n    --from-file=config.yaml=configs/config-prod-k8s.yaml\n```\n\n#### 4. Deploy Application\n\n```bash\n# Deploy the application\noc apply -f deployments/openshift/production-deployment.yaml\n```\n\n### Deployment Models\n\n| File | Use Case | Features |\n|------|----------|----------|\n| `deployments/kubernetes/basic-deployment.yaml` | Basic deployment | Simple setup, minimal security |\n| `deployments/openshift/production-deployment.yaml` | Production deployment | Plugin signing, proper secrets, health checks |\n\n### Security Features\n\n#### Container Security\n- **Non-root execution**: Runs as user ID 1001\n- **Read-only root filesystem**: Prevents runtime modifications\n- **Dropped capabilities**: Minimal privilege model\n- **Security contexts**: OpenShift security context constraints\n\n#### Key Management\n- **External key generation**: Keys never stored in container images\n- **Runtime plugin signing**: Plugins signed during pod initialization\n- **Secure secret mounting**: Keys mounted as Kubernetes Secrets\n- **Proper file permissions**: Keys accessible only to application user\n\n### Configuration Management\n\nDito supports multiple configuration approaches:\n\n1. **Template-based**: Use `configs/templates/application.yaml` with hash substitution\n2. **Environment-specific**: Separate configs for dev/prod/staging in `configs/`\n3. **ConfigMap injection**: Runtime configuration via Kubernetes ConfigMaps\n4. **Hot-reload**: Dynamic configuration updates without restarts\n\nSee `configs/README.md` for detailed configuration management.\n\n## 📄 License\n\nThis project is licensed under the Apache License 2.0. See the [LICENSE](./LICENSE) file for details.\n\n---\n\n**Made with ❤️**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrearaponi%2Fdito","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrearaponi%2Fdito","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrearaponi%2Fdito/lists"}