Core Concepts

Configuration

Kipchak uses a centralized configuration system that makes it easy to manage your application settings across different environments.

Configuration Files

Configuration files are stored in the config/ directory and return associative arrays of settings. Each configuration file corresponds to a specific component or feature of your application.

File Structure

The starter project includes several configuration files:

config/
├── kipchak.api.php           # Core API settings
├── kipchak.auth.jwks.php     # JWKS authentication configuration
├── kipchak.auth.key.php      # API key authentication configuration
├── kipchak.couchdb.php       # CouchDB driver configuration
├── kipchak.doctrine.php      # Doctrine DBAL/ORM configuration
├── kipchak.memcached.php     # Memcached driver configuration
├── kipchak.rabbitmq.php      # RabbitMQ configuration
└── kipchak.subashi.php       # WAF (Subashi) configuration

Configuration File Format

All configuration files follow the same pattern - they return an array:

<?php

use function Kipchak\Core\env;

return [
    'name' => 'kipchak-template',
    'debug' => (bool) env('DEBUG', true),
    'logExceptions' => true,
    'logExceptionDetails' => true,
];

Core API Configuration

The kipchak.api.php file contains core application settings:

return [
    'name' => 'kipchak-template',        // Application name (hyphen/underscore separated)
    'debug' => (bool) env('DEBUG', true), // Enable debug mode
    'logExceptions' => true,              // Log exceptions
    'logExceptionDetails' => true,        // Log detailed exception information
    // 'loglevel' => \Monolog\Level::Debug // Override log level (optional)
];

When debug is enabled, log level defaults to Debug. Otherwise, it defaults to Info.

Environment Variables

Kipchak uses the env() helper function to read environment variables with fallback defaults:

use function Kipchak\Core\env;

$host = env('DB_HOST', 'localhost');  // Returns DB_HOST or 'localhost' if not set
$port = env('DB_PORT', 3306);         // Returns DB_PORT or 3306 if not set

Environment File (.env)

During development, create a .env file in your project root:

DEBUG=true
APP_NAME=MyAPI

# Database
DB_HOST=localhost
DB_PORT=3306
DB_USER=api
DB_PASSWORD=secret

# Memcached
MEMCACHED_HOST=localhost
MEMCACHED_PORT=11211

# CouchDB
COUCHDB_HOST=http://localhost
COUCHDB_PORT=5984
COUCHDB_USER=admin
COUCHDB_PASSWORD=password
COUCHDB_DATABASE=mydb

Authentication Configuration

JWKS Authentication

Configure JSON Web Key Set authentication in kipchak.auth.jwks.php:

return [
    'enabled' => false,                 // Enable globally
    'ignore_options' => true,           // Allow OPTIONS requests without auth
    'ignore_paths' => [                 // Paths that bypass authentication
        '/status'
    ],
    'jwksUri' => 'https://auth.example.com/certs',  // JWKS endpoint
    'validate_scopes' => true,          // Validate JWT scopes
    'scopes' => [                       // Required scopes
        'email',
        'profile'
    ],
];

API Key Authentication

Configure API key authentication in kipchak.auth.key.php:

return [
    'enabled' => false,                 // Enable globally
    'ignore_options' => true,           // Allow OPTIONS requests without auth
    'ignore_paths' => [                 // Paths that bypass authentication
        '/status'
    ],
    'authorised_keys' => [              // Valid API keys
        'key1' => 'client1',
        'key2' => 'client2',
        'key3' => 'client3'
    ],
    'header' => 'apikey',               // Header name to check
    'query_param' => 'apikey'           // Query parameter to check
];

API keys can be provided via:

  • Header: X-API-Key: key1 or custom header name
  • Query parameter: ?apikey=key1 or custom parameter name

Driver Configuration

CouchDB

Configure CouchDB connections in kipchak.couchdb.php:

return [
    'enabled' => true,
    'connections' => [
        'default' => [
            'host' => env('COUCHDB_HOST', 'http://couchdb'),
            'port' => env('COUCHDB_PORT', 5984),
            'username' => env('COUCHDB_USER', 'api'),
            'password' => env('COUCHDB_PASSWORD', 'api'),
            'database' => env('COUCHDB_DATABASE', 'api_database')
        ]
    ]
];

Memcached

Configure Memcached pools in kipchak.memcached.php:

return [
    'enabled' => true,
    'pools' => [
        'cache' => [
            [
                'host' => env('MEMCACHED_HOST', 'memcached'),
                'port' => env('MEMCACHED_PORT', 11211),
            ]
        ],
        'sessions' => [
            [
                'host' => env('MEMCACHED_HOST', 'memcached'),
                'port' => env('MEMCACHED_PORT', 11211),
            ]
        ]
    ],
    'pools_options' => [
        'cache' => [
            Memcached::OPT_PREFIX_KEY => '',
            Memcached::OPT_CONNECT_TIMEOUT => 1000,
            Memcached::OPT_RETRY_TIMEOUT => 1,
            // See https://www.php.net/manual/en/memcached.constants.php
        ],
    ]
];

Doctrine DBAL & ORM

Configure Doctrine database access in kipchak.doctrine.php:

return [
    'dbal' => [
        'enabled' => false,
        'connections' => [
            'primary' => [
                'dbname' => 'mydb',
                'user' => env('DB_USER', 'api'),
                'password' => env('DB_PASSWORD', 'api'),
                'host' => env('DB_HOST', 'mysql'),
                'port' => env('DB_PORT', 3306),
                'driver' => 'pdo_mysql',
                'charset' => 'utf8'
            ]
        ]
    ],
    'orm' => [
        'enabled' => false,
        'entity_managers' => [
            'primary' => [
                'dev_mode' => (bool) env('DEBUG', true),
                'metadata_dirs' => [
                    realpath(__DIR__ . '/../api/Entities/Doctrine/Primary')
                ],
                'metadata_format' => 'attributes',
                'connection' => 'primary',
                'cache' => [
                    'enabled' => true,
                    'store' => 'memcached',
                ],
                'cache_config' => [
                    'memcached' => [
                        'pool' => 'cache'
                    ],
                    'file' => [
                        'dir' => '/tmp',
                    ]
                ],
            ],
        ]
    ]
];

RabbitMQ

Configure RabbitMQ connections in kipchak.rabbitmq.php:

return [
    'hostname' => env('RABBITMQ_HOST', ''),
    'port' => env('RABBITMQ_PORT', 5672),
    'username' => env('RABBITMQ_USERNAME', ''),
    'password' => env('RABBITMQ_PASSWORD', ''),
    'vhost' => env('RABBITMQ_VHOST', '/'),
    'isSecure' => env('RABBITMQ_IS_SECURE', false),
    'sslVerify' => env('RABBITMQ_SSL_VERIFY', false),
    'queues' => [
        'queue-name-1',
        'queue-name-2',
    ]
];

WAF Configuration (Subashi)

The Subashi WAF provides firewall capabilities with whitelisting, blacklisting, and rate limiting. Configure in kipchak.subashi.php:

return [
    'enabled' => true,
    'default_action' => 'allow',
    'blocked_response_code' => 403,
    'blocked_response_message' => 'Access Denied',

    // Rate limiting
    'rate_limiting' => [
        'enabled' => false,
        'default_limit' => 3,
        'default_window' => 5,
        'store' => 'memcached',
        'memcached_pool' => 'cache',
    ],

    // Whitelist rules (bypass all checks)
    'whitelist' => [
        [
            'name' => 'Whitelist trusted IPs',
            'conditions' => [
                [
                    'type' => 'ip',
                    'operator' => 'in_list',
                    'values' => ['127.0.0.1', '::1'],
                ],
            ],
            'action' => 'allow',
        ],
    ],

    // Blacklist rules (block if conditions match)
    'blacklist' => [
        [
            'name' => 'Block suspicious user agents',
            'conditions' => [
                [
                    'type' => 'header',
                    'key' => 'User-Agent',
                    'operator' => 'regex',
                    'value' => '/(bot|crawler|scraper)/i',
                ],
            ],
            'action' => 'block',
        ],
    ],

    // Rate limit rules
    'rate_limit_rules' => [
        [
            'name' => 'Per IP rate limit',
            'conditions' => [],
            'rate_limit' => [
                'limit' => 100,
                'window' => 60,
                'key_prefix' => 'ip',
                'key_source' => 'ip',
            ],
        ],
    ],
];

Supported Operators

  • equals, not_equals - Exact match
  • contains, not_contains - String contains
  • regex - Regular expression match
  • in_list, not_in_list - Value in array
  • exists, not_exists - Check presence
  • gt, lt, gte, lte - Numeric comparisons

Supported Condition Types

  • header - HTTP header
  • query_param - URL query parameter
  • ip - Client IP address
  • method - HTTP method
  • path - URL path
  • body - Request body (JSON)

Accessing Configuration

Configuration is accessed through the Config driver:

use Kipchak\Driver\Config\Config;

$config = Config::get();
$debug = $config->get('kipchak.api.debug');
$dbHost = $config->get('kipchak.doctrine.dbal.connections.primary.host');

Configuration keys use dot notation: filename.key.nested.value

Environment-Based Configuration

Development

Use .env files and set debug = true for detailed logging and error reporting.

Production

Set environment variables through your hosting platform:

  • Use environment variables instead of .env files
  • Set debug = false
  • Configure appropriate log levels
  • Enable caching for Doctrine ORM
  • Use secure connections for all services

Kubernetes

Override settings using ConfigMaps or Secrets:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DEBUG: "false"
  DB_HOST: "mysql-service"
  MEMCACHED_HOST: "memcached-service"

Best Practices

  1. Never commit .env files - Use .env.example as a template
  2. Use environment variables for secrets and environment-specific settings
  3. Provide sensible defaults in the env() function calls
  4. Keep configuration organized - One file per component/feature
  5. Document configuration options - Add comments explaining each setting
  6. Use type casting - Cast environment variables to appropriate types: (bool), (int), etc.
  7. Validate configuration - Check that required values are present during bootstrap
Previous
Controllers