hegelmax/env-secured

Encrypted configuration manager for PHP (EnvSecured).

Maintainers

Package info

github.com/hegelmax/php-env-secured

pkg:composer/hegelmax/env-secured

Statistics

Installs: 5

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.0 2026-05-28 18:08 UTC

This package is auto-updated.

Last update: 2026-05-28 18:10:00 UTC


README

EnvSecured is a lightweight, secure, and self-contained PHP module for storing sensitive configuration values (API keys, database credentials, tokens, secrets) in an encrypted file and provides a clean interface to access them in runtime.

โญ Key Features

  • ๐Ÿ”’ EnvSecured Studio vault (config.envs) for new configs
  • ๐Ÿ” Legacy encrypted config file (config.enc) remains supported
  • ๐ŸŒ Browser-based UI for editing settings
  • ๐Ÿ“ค JSON export (download)
  • ๐Ÿ“ฅ JSON import (load file into form)
  • ๐Ÿ”‘ Automatic key generation (keys/*.key)
  • ๐Ÿงฌ Server-bound encryption (fingerprint-based)
  • ๐Ÿงฉ Zero global functions โ€” everything wrapped in PHP classes
  • ๐Ÿš€ Drop-in integration into any project
  • โš™๏ธ Can be used:
    • with Composer
    • without Composer

๐Ÿ—‚๏ธ Project Structure

env_secured/
โ”œโ”€โ”€ _init.php                    โ†’ Bootloader (entry point)
โ”œโ”€โ”€ libs/
โ”‚   โ”œโ”€โ”€ EnvSecured.php           โ†’ Main config manager
โ”‚   โ”œโ”€โ”€ EnvSecuredCrypto.php     โ†’ Encryption engine
โ”‚   โ””โ”€โ”€ html/
โ”‚       โ”œโ”€โ”€ page_form.php        โ†’ UI template: config editor
โ”‚       โ”œโ”€โ”€ page_success.php     โ†’ UI template: success page
โ”‚       โ””โ”€โ”€ page_error.php       โ†’ UI template: error page
โ”œโ”€โ”€ configs/                     โ†’ Encrypted config files (auto-created)
โ”‚   โ”œโ”€โ”€ config.envs              โ†’ EnvSecured Studio vault (auto-created)
โ”‚   โ””โ”€โ”€ config.enc               โ†’ Legacy encrypted config (still supported)
โ””โ”€โ”€ keys/                        โ†’ Key files (auto-created)
    โ”œโ”€โ”€ sodium.key               โ†’ Internal crypto key
    โ”œโ”€โ”€ secret.key               โ†’ Master secret key
    โ””โ”€โ”€ studio_password_*.enc    โ†’ Local encrypted Studio password cache

Both configs/ and keys/ directories are created automatically on first use if they do not exist.

๐Ÿ“ฆ Installation

Option A โ€” Composer (recommended)

composer require hegelmax/env-secured

Option B โ€” No Composer

Download the directory:

env_secured/

and place it anywhere in your project.

๐Ÿš€ Quick Start (Composer version)

require __DIR__ . '/vendor/autoload.php';

use EnvSecured\EnvSecured;

$envRoot = __DIR__ . '/env'; // Directory for configs/ and keys/

$env = new EnvSecured($envRoot);
$env->run();

// Retrieve configuration
$config = EnvSecured::get();          // full array
$dbHost = EnvSecured::get('DB_HOST'); // single value

๐Ÿš€ Quick Start (No Composer)

Copy init.php.sample to your project (e.g. as _init.php) and adjust paths, then include it:

require __DIR__ . '/env_secured/_init.php';

Then read configuration via:

$env = EnvSecured::get();  // array
echo EnvSecured::get('API_URL'); 

๐Ÿ–ฅ๏ธ First Run โ€” Creating Config

When no encrypted config exists, opening your init script in a browser shows the Config Editor UI:

/_init.php

UI allows:

โœ” Editing KEY=value rows

โœ” Saving encrypted config (config.enc)

โœ” Downloading JSON

โœ” Loading JSON into form

Folders created automatically:

env/
  configs/
    config.enc
  keys/
    sodium.key
    secret.key

๐Ÿ”’ Storage and Encryption Model

New configs are written as EnvSecured Studio-compatible .envs vaults:

  • JSON project model with Settings, Crypto, Variables, and Values
  • default storage mode: WholeJson
  • vault password KDF: PBKDF2-HMAC-SHA256, 300000 iterations
  • payload encryption: AES-256-CBC + HMAC-SHA256
  • encrypted payload format: Nonce, Ciphertext, Tag

The PHP runtime can read Studio modes:

  • Open
  • SecretsOnly
  • AllValues
  • WholeJson

Legacy config.enc remains readable/writable when ENV_SECURED_STORAGE_FORMAT = 'legacy' or when only the old file exists.

Legacy local encryption and the Studio password cache use:

  • 256-bit sodium.key
  • 256-bit secret.key
  • machine + project fingerprint
  • XSalsa20-Poly1305 (libsodium)
  • unique nonce per encryption
  • atomic writes to prevent corruption

Conceptually:

fingerprint = HASH( hostname | projectRoot | secret.key )
finalKey    = HASH( fingerprint | sodium.key )
cipher      = base64( nonce | secretbox(plaintext, nonce, finalKey) )

For the Studio password cache, PHP also binds encryption to the absolute .envs path:

cacheKey = HASH( fingerprint | sodium.key | "studio-password-cache|/absolute/path/config.envs" )

So copying only keys/*.key is not enough to decrypt the cached password outside the same machine/path context.

๐Ÿ›ก๏ธ Why It's Safe

  • Keys stored outside web root (in env_secured/keys/)
  • Config stored encrypted (env_secured/configs/config.enc)
  • No plaintext config on server
  • No global functions โ†’ no name collisions
  • Atomic writes for safe file operations
  • Encryption relies on libsodium (modern & secure)
  • Browser editor POST requests are protected with a session-bound CSRF token
  • Security headers on all UI responses: Content-Security-Policy (with nonce), X-Frame-Options: DENY, Cache-Control: no-store, X-Content-Type-Options: nosniff
  • Input limits: max 500 key/value pairs, key โ‰ค 128 chars, value โ‰ค 64 KB

โš™๏ธ Configuration in Code

Once EnvSecured loads the config:

1๏ธโƒฃ Array access

$config = EnvSecured::get();
echo $config['DB_HOST'];

2๏ธโƒฃ Single value

echo EnvSecured::get('API_TOKEN');

3๏ธโƒฃ Global constants

If constant autodefine is enabled:

echo API_TOKEN;

Enable via:

const ENV_SECURED_CONFIG_DEFINE_CONST = true;

๐Ÿ› ๏ธ Optional Constants

Place them before calling EnvSecured.

const ENV_SECURED_CONFIG_SCHEMA           = 'prod';
const ENV_SECURED_CONFIG_ALLOW_EDIT       = false;
const ENV_SECURED_CONFIG_ALLOW_SESSION    = true;
const ENV_SECURED_CONFIG_DEFINE_CONST     = true;

const ENV_SECURED_STORAGE_FORMAT          = 'studio'; // studio (default for new configs) | legacy
const ENV_SECURED_STUDIO_FILE             = __DIR__ . '/env/configs/config.envs';
const ENV_SECURED_STUDIO_PASSWORD         = 'change-me'; // optional; otherwise POST, ENVSECURED_PASSWORD, or local cache
const ENV_SECURED_STUDIO_ENCRYPTION_MODE  = 'WholeJson'; // Open | SecretsOnly | AllValues | WholeJson
const ENV_SECURED_STUDIO_SERVICE          = 'backend'; // optional runtime scope
const ENV_SECURED_STUDIO_ENVIRONMENT      = 'prod'; // optional runtime scope

const ENV_SECURED_DEFAULTS = [
    ['key' => 'DB_HOST', 'value' => 'localhost'],
    ['key' => 'API_URL', 'value' => 'https://localhost/api'],
];

ENV_SECURED_CONFIG_SCHEMA is a legacy file-name prefix, not a Studio service or environment. Use ENV_SECURED_STUDIO_SERVICE and ENV_SECURED_STUDIO_ENVIRONMENT for Studio scopes.

Note: The browser editor always starts a PHP session (to issue a CSRF token), regardless of ENV_SECURED_CONFIG_ALLOW_SESSION. If your application starts its own session before including EnvSecured, that is fine โ€” session_start() will not be called twice. If your application starts a session after, include EnvSecured first, or call session_start() yourself beforehand.

Warning: ENV_SECURED_CONFIG_ALLOW_SESSION=true stores the decrypted config in $_SESSION['ENV']. Default PHP session handlers usually store sessions as plaintext files, so this may write secrets to disk outside EnvSecured encryption. Prefer EnvSecured::get() unless you control and protect PHP session storage.

๐Ÿ”ง Requirements

  • PHP 8.1+
  • ext-sodium enabled
  • ext-openssl enabled
  • Writable directory for:
    • configs/
    • keys/

๐Ÿงฉ EnvSecured Studio Compatibility

PHP now writes new configs in Studio's .envs project-vault structure. Simple PHP KEY=value rows are stored as Studio variables and values; by default, the whole JSON project is encrypted with the Studio password.

The PHP editor can set the per-variable Secret flag:

  • Secret: controls Studio IsSecret; used by SecretsOnly.

The file protection selector maps to Studio modes:

  • Open
  • Secrets only -> SecretsOnly
  • All values -> AllValues
  • Masked / whole vault -> WholeJson

Compatibility limits:

  • PHP preserves legacy config.enc, but that old format is not a Studio vault.
  • PHP can consume Studio service/environment scopes and interpolation.
  • The browser editor is still a simple key/value editor, so it cannot expose the full Studio UI model such as scope matrix, manifests, validation settings, generated values, and export masks.
  • For complex Studio projects, prefer editing in EnvSecured Studio and use PHP as the runtime reader/writer for known keys.

๐Ÿ’ป JSON Import / Export

EnvSecured supports configuration migration via JSON file, that can be useful for:

  • migrations
  • backups
  • moving configs between servers
  • Dev โ†’ Prod workflows

Export (Download JSON)

Downloads a readable .json file containing all config values.

Import (Load JSON)

Loads a .json file directly in the browser and fills the config form.

No data is sent to the server until Save (encrypted) is pressed.

๐Ÿ“ค Migrating Between Servers

  1. On old server โ†’ open UI โ†’ Download JSON
  2. Transfer the downloaded file to the new server
  3. On new server โ†’ open UI โ†’ Load JSON
  4. Click Save (encrypted)

A new encrypted config is generated automatically for the new environment; secret keys remain private.

๐Ÿงช Self-Test (Optional)

Temporary snippet:

require_once __DIR__ . '/env_secured/libs/EnvSecuredCrypto.php';

$crypto = new \EnvSecured\EnvSecuredCrypto(__DIR__ . '/env_secured');
$cipher = $crypto->encrypt("test");
var_dump($cipher);

Then ensure:

$crypto->decrypt($cipher) === "test";

๐Ÿ“„ License

MIT License. Free for commercial use.

ยฉ 2025 Maxim Hegel