Advanced Configuration¶
By default the amazee.ai provider stores both credentials — the LLM API key and the VectorDB password — inside Drupal's configuration system via the Key module using the Configuration key provider. This is the simplest setup and works out of the box.
However, storing secrets inside configuration is not always appropriate — especially when config is exported to version control (e.g. via config/sync). This page documents how to encrypt the stored secrets with Easy Encryption, and how to use alternative key providers so that secrets never leave a secure storage backend.
The Managed Keys¶
| Key ID | Label | What it stores |
|---|---|---|
amazeeio_ai |
amazee.ai AI API Key | The LiteLLM bearer token used to call the LLM gateway |
amazeeio_ai_database |
amazee.ai AI Database Key | The password for the managed pgvector VectorDB |
amazeeio_ai_management_token |
amazee.ai Management Token | An account token used only to display team/account details on the settings page (created by the UI sign-in flow, not by the recipe) |
The first two keys are required and are created automatically when you connect the module. The management token is optional — the LLM and VectorDB work without it. The module reads the two required key IDs from ai_provider_amazeeio.settings:
You can point these settings at any Key module entity, regardless of which key provider backend that entity uses.
Encrypting the Keys with Easy Encryption (recommended)¶
The Easy Encryption module encrypts Key values at rest with zero configuration. Instead of the plaintext Configuration provider, keys use the Easy Encrypted provider: the secret is encrypted with a libsodium sealed box and only the ciphertext is stored in configuration — safe to export and commit to version control.
New installs: install Easy Encryption first¶
On install, Easy Encryption generates an encryption key pair automatically. It also transparently upgrades any newly created key that targets an insecure provider (config or state) to the Easy Encrypted provider before it is saved.
This means: if Easy Encryption is enabled before you connect the amazee.ai provider (via the sign-in flow or trial provisioning), the amazeeio_ai and amazeeio_ai_database keys are encrypted automatically. The credentials never touch the database or config exports in plaintext, and no changes to this module or your workflow are required.
Existing installs: migrating already-created keys¶
Keys created before Easy Encryption was installed keep the plaintext Configuration provider — the automatic upgrade only applies to new keys. Migrate them with Drush:
drush php-eval "
foreach (['amazeeio_ai', 'amazeeio_ai_database'] as \$id) {
\$key = \Drupal::entityTypeManager()->getStorage('key')->load(\$id);
if (\$key === NULL || \$key->getKeyProvider()->getPluginId() === 'easy_encrypted') {
continue;
}
\$value = \$key->getKeyValue();
\$key->setPlugin('key_provider', 'easy_encrypted');
\$key->set('key_provider_settings', []);
\$key->setKeyValue(\$value);
\$key->save();
}
"
drush cex -y
Alternatively, delete the two keys at Configuration → System → Keys (/admin/config/system/keys) and re-run the sign-in flow on the amazee.ai settings page — the recreated keys will be encrypted automatically.
If you have exported plaintext key values to config/sync in the past, remember that they remain in your git history. Rotate the credentials (regenerate them via the amazee.ai settings page) after migrating.
The private key¶
Encrypted values are decrypted with a private key stored in a .easy_encryption directory next to your web root (file permissions 0600), falling back to Drupal's State system if that directory is not writable.
- Never commit
.easy_encryptionto version control — add it to.gitignore. - On Lagoon, persist the directory or move it via
settings.php: - Each environment that needs to decrypt (i.e. actually call the LLM/VectorDB) needs the private key. Transfer it between environments with the Key transfer UI (enable the
easy_encryption_adminsub-module) or by securely copying the.easy_encryptiondirectory. See the Easy Encryption documentation for details.
Check Reports → Status report to verify an active encryption key is configured and the private key is available.
Easy Encryption vs. environment variables: Easy Encryption protects the values in config exports and the database, but the private key still lives on the server. For the strongest setup, combine approaches — or skip encryption entirely and keep the secret out of Drupal altogether using the environment-variable provider below.
Changing the Key Provider¶
Option 1: Environment Variable (recommended for Lagoon / Docker)¶
- Install the Key module and the Environment Key provider (or a compatible sub-module such as
key_env). - Set environment variables on your host:
- Update the Key entities (e.g. via
config/syncor Drush) to use the Environment variable provider and point at the variable names above. - The module will pick up the new values automatically on the next request.
Lagoon tip: Add the variables via the Lagoon API or the Lagoon UI as project-level or environment-level variables with
scope: runtimeso they are injected at container boot time.
Option 2: AWS Secrets Manager / HashiCorp Vault¶
Use a community Key provider module (e.g. key_aws_kms, vault_key) and configure it to fetch the secret by ARN or path. Update the Key entity's key provider to point at the relevant secret — the module does not need to be reconfigured.
Option 3: Drush / Manually Overriding Key Values¶
If you want to inject the key at deploy time without changing the Key entity's provider:
drush php-eval "
\$key = \Drupal::entityTypeManager()->getStorage('key')->load('amazeeio_ai');
\$key->setKeyValue(getenv('AMAZEEIO_AI_KEY'));
\$key->save();
"
Warning: This writes the secret value into the database. Prefer a proper key provider backend for production environments.
Overriding Configuration with settings.php¶
All module settings can be overridden in settings.php without touching the database. This is useful for setting host URLs or key IDs per-environment:
// settings.php (or settings.local.php)
$config['ai_provider_amazeeio.settings']['host'] = 'https://api.amazee.ai';
$config['ai_provider_amazeeio.settings']['postgres_host'] = 'postgres.example.com';
$config['ai_provider_amazeeio.settings']['postgres_port'] = 5432;
$config['ai_provider_amazeeio.settings']['postgres_default_database'] = 'my_vdb';
$config['ai_provider_amazeeio.settings']['postgres_username'] = 'my_user';
// Override which Key entity to use (must exist):
$config['ai_provider_amazeeio.settings']['api_key'] = 'my_custom_llm_key';
$config['ai_provider_amazeeio.settings']['postgres_password'] = 'my_custom_db_key';
Note: Config overrides via
settings.phpare read-only — they are not written back to the database and will not appear in config exports.
Pre-provisioning Keys Without Using the UI¶
For automated deployments (CI/CD, Ansible, etc.) you may want to pre-create the Key entities and module config before any admin visits the settings page. The snippet below shows how to do this via Drush php-eval or a custom deploy hook:
use Drupal\Core\Config\Config;
// Write module settings.
\Drupal::configFactory()
->getEditable('ai_provider_amazeeio.settings')
->set('host', 'https://<your-region>.api.amazee.ai')
->set('postgres_host', '<pgvector-host>')
->set('postgres_port', 5432)
->set('postgres_default_database', '<db-name>')
->set('postgres_username', '<db-user>')
->set('postgres_password', 'amazeeio_ai_database')
->set('api_key', 'amazeeio_ai')
->save();
// Create / update the LLM API key entity.
$key_storage = \Drupal::entityTypeManager()->getStorage('key');
$key = $key_storage->load('amazeeio_ai')
?? $key_storage->create([
'id' => 'amazeeio_ai',
'label' => 'amazee.ai AI API Key',
'key_type' => 'authentication',
'key_provider' => 'config',
'key_input' => 'text_field',
]);
$key->set('key_provider_settings', ['key_value' => '<LiteLLM token>']);
$key->save();
// Create / update the VectorDB password key entity.
$db_key = $key_storage->load('amazeeio_ai_database')
?? $key_storage->create([
'id' => 'amazeeio_ai_database',
'label' => 'amazee.ai AI Database Key',
'key_type' => 'authentication',
'key_provider' => 'config',
'key_input' => 'text_field',
]);
$db_key->set('key_provider_settings', ['key_value' => '<VectorDB password>']);
$db_key->save();
Once both keys exist and the config is saved, the provider will report as Connected without requiring the sign-in flow.
Manual Migration / Sync Configuration¶
If you have received credentials manually (e.g. for a dedicated environment) and want to manually update your config/sync files, you can adapt the following YAML structures.
config/sync/ai_provider_amazeeio.settings.yml¶
There are 4 main places to change the connection details in this file:
api_key: amazeeio_ai
moderation: false
# The base amazee.ai API host (typically https://api.amazee.ai)
amazee_host: 'https://api.amazee.ai'
# The specific LLM gateway URL for your environment
host: 'LLM_HOST_GOES_HERE'
# The PostgreSQL server address for the VectorDB
postgres_host: DB_HOST_GOES_HERE
postgres_port: 5432
# The database name for the VectorDB
postgres_default_database: DB_NAME_GOES_HERE
# The database user for the VectorDB
postgres_username: DB_USERNAME_GOES_HERE
postgres_password: amazeeio_ai_database
config/sync/key.key.amazeeio_ai.yml¶
This file handles the LLM API key (the LiteLLM bearer token). You only need to change the key_value part:
langcode: en
status: true
dependencies: { }
id: amazeeio_ai
label: 'amazee.ai AI API Key'
description: 'Automatically created by the amazee.ai AI provider.'
key_type: authentication
key_type_settings: { }
key_provider: config
key_provider_settings:
key_value: LLM_KEY_GOES_HERE
key_input: text_field
key_input_settings: { }
config/sync/key.key.amazeeio_ai_database.yml¶
This file handles the VectorDB password. You only need to change the key_value part:
langcode: en
status: true
dependencies: { }
id: amazeeio_ai_database
label: 'amazee.ai AI Database Key'
description: 'Automatically created by the amazee.ai AI provider.'
key_type: authentication
key_type_settings: { }
key_provider: config
key_provider_settings:
key_value: DATABASE_KEY_GOES_HERE
key_input: text_field
key_input_settings: { }
Reminder: After making manual changes to
config/sync, rundrush cim -yto import the new configuration into your database.