Creating a Custom Secrets Plugin
You can integrate the gateway with any secret management system by implementing a custom plugin.
1. Implement the SecretProvider interface
Create a new directory under the gateway's plugins/ folder. Implement the abstract SecretProvider class:
plugins/my_secret_provider/plugin.py
from radicalbit_ai_gateway.utils.secrets import (
SecretNotFoundError,
SecretProvider,
set_secret_provider_factory,
)
class MyCustomProvider(SecretProvider):
def get_secret(self, key: str) -> str:
# Fetch the secret from your system
value = my_backend.fetch(key)
if value is None:
raise SecretNotFoundError(key, source="my_secret_provider")
return value
def list_secret_keys(self) -> list[str]:
# Return the secret keys your system holds: keys only, never values
return my_backend.list_keys()
# Register the provider at import time
set_secret_provider_factory(MyCustomProvider)
Both methods are required.
get_secretis called for each!secret KEYreference whenever the gateway registers a project's routes (at startup and on every publish) and whenever it validates a configuration's references. RaiseSecretNotFoundErrorwhen a key is not found.list_secret_keysreturns the secret keys the backend holds. It powers the Secrets section and is called on every request the page makes. Return keys only, never secret values. If the backend cannot be reached, raiseSecretsBackendError(fromradicalbit_ai_gateway.utils.exceptions). The page then shows its error state. Do not return an empty list, because the page would show an outage as "no secret keys".
The gateway builds a new provider instance each time it reads the backend. Do not rely on instance state lasting longer than a single read.
2. Add dependencies
Create a requirements.txt in the same plugin directory. Dependencies are installed automatically when the plugin is enabled:
plugins/my_secret_provider/requirements.txt
my-secret-lib>=1.0.0
3. Directory structure
plugins/
my_secret_provider/
__init__.py
plugin.py
requirements.txt
4. Enable the plugin
export ENABLED_PLUGINS="my_secret_provider"
The gateway discovers plugins by scanning the plugins/ directory and matching names against ENABLED_PLUGINS. The plugin's plugin.py module is imported at startup, which triggers the set_secret_provider_factory() call.